PR libstdc++/59439 optimize uses of classic ("C") std::locale
The global locale::_Impl that represents the "C" locale is never destroyed, so there is no need to keep track of reference count updates for that object. This greatly reduce contention between threads that refer to the classic locale. Since the global std::locale initially uses the classic locale, this benefits the common case for any code using the global locale, such as construction/destruction of iostream objects. All these updates are done inside libstdc++.so so there's no need to worry about users' objects having inlined old versions of the code which still update the reference count for the classic locale. PR libstdc++/59439 * src/c++98/locale.cc (locale::locale(const locale&)): Bypass reference count updates for the classic locale. (locale::~locale()): Likewise. (locale::operator=(const locale&)): Likewise. * src/c++98/locale_init.cc (locale::locale()): Likewise. (locale::global(const locale&)): Likewise. From-SVN: r264811
This commit is contained in:
parent
e7df9e44c6
commit
749c0e1d8b
|
@ -1,3 +1,13 @@
|
||||||
|
2018-10-03 Jonathan Wakely <jwakely@redhat.com>
|
||||||
|
|
||||||
|
PR libstdc++/59439
|
||||||
|
* src/c++98/locale.cc (locale::locale(const locale&)): Bypass
|
||||||
|
reference count updates for the classic locale.
|
||||||
|
(locale::~locale()): Likewise.
|
||||||
|
(locale::operator=(const locale&)): Likewise.
|
||||||
|
* src/c++98/locale_init.cc (locale::locale()): Likewise.
|
||||||
|
(locale::global(const locale&)): Likewise.
|
||||||
|
|
||||||
2018-10-03 François Dumont <fdumont@gcc.gnu.org>
|
2018-10-03 François Dumont <fdumont@gcc.gnu.org>
|
||||||
|
|
||||||
* include/debug/map.h
|
* include/debug/map.h
|
||||||
|
|
|
@ -77,7 +77,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
|
|
||||||
locale::locale(const locale& __other) throw()
|
locale::locale(const locale& __other) throw()
|
||||||
: _M_impl(__other._M_impl)
|
: _M_impl(__other._M_impl)
|
||||||
{ _M_impl->_M_add_reference(); }
|
{
|
||||||
|
if (_M_impl != _S_classic)
|
||||||
|
_M_impl->_M_add_reference();
|
||||||
|
}
|
||||||
|
|
||||||
// This is used to initialize global and classic locales, and
|
// This is used to initialize global and classic locales, and
|
||||||
// assumes that the _Impl objects are constructed correctly.
|
// assumes that the _Impl objects are constructed correctly.
|
||||||
|
@ -86,7 +89,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
locale::~locale() throw()
|
locale::~locale() throw()
|
||||||
{ _M_impl->_M_remove_reference(); }
|
{
|
||||||
|
if (_M_impl != _S_classic)
|
||||||
|
_M_impl->_M_remove_reference();
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
locale::operator==(const locale& __rhs) const throw()
|
locale::operator==(const locale& __rhs) const throw()
|
||||||
|
@ -112,8 +118,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
const locale&
|
const locale&
|
||||||
locale::operator=(const locale& __other) throw()
|
locale::operator=(const locale& __other) throw()
|
||||||
{
|
{
|
||||||
__other._M_impl->_M_add_reference();
|
if (__other._M_impl != _S_classic)
|
||||||
_M_impl->_M_remove_reference();
|
__other._M_impl->_M_add_reference();
|
||||||
|
if (_M_impl != _S_classic)
|
||||||
|
_M_impl->_M_remove_reference();
|
||||||
_M_impl = __other._M_impl;
|
_M_impl = __other._M_impl;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -257,9 +257,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
// fall back to lock protected access to both _S_global and
|
// fall back to lock protected access to both _S_global and
|
||||||
// its reference count.
|
// its reference count.
|
||||||
_M_impl = _S_global;
|
_M_impl = _S_global;
|
||||||
if (_M_impl == _S_classic)
|
if (_M_impl != _S_classic)
|
||||||
_M_impl->_M_add_reference();
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
__gnu_cxx::__scoped_lock sentry(get_locale_mutex());
|
__gnu_cxx::__scoped_lock sentry(get_locale_mutex());
|
||||||
_S_global->_M_add_reference();
|
_S_global->_M_add_reference();
|
||||||
|
@ -275,7 +273,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
{
|
{
|
||||||
__gnu_cxx::__scoped_lock sentry(get_locale_mutex());
|
__gnu_cxx::__scoped_lock sentry(get_locale_mutex());
|
||||||
__old = _S_global;
|
__old = _S_global;
|
||||||
__other._M_impl->_M_add_reference();
|
if (__other._M_impl != _S_classic)
|
||||||
|
__other._M_impl->_M_add_reference();
|
||||||
_S_global = __other._M_impl;
|
_S_global = __other._M_impl;
|
||||||
const string __other_name = __other.name();
|
const string __other_name = __other.name();
|
||||||
if (__other_name != "*")
|
if (__other_name != "*")
|
||||||
|
@ -284,7 +283,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
|
|
||||||
// Reference count sanity check: one reference removed for the
|
// Reference count sanity check: one reference removed for the
|
||||||
// subsition of __other locale, one added by return-by-value. Net
|
// subsition of __other locale, one added by return-by-value. Net
|
||||||
// difference: zero. When the returned locale object's destrutor
|
// difference: zero. When the returned locale object's destructor
|
||||||
// is called, then the reference count is decremented and possibly
|
// is called, then the reference count is decremented and possibly
|
||||||
// destroyed.
|
// destroyed.
|
||||||
return locale(__old);
|
return locale(__old);
|
||||||
|
|
Loading…
Reference in New Issue