PR libstdc++/59439 optimize uses of classic ("C") std::locale
authorJonathan Wakely <jwakely@redhat.com>
Wed, 3 Oct 2018 11:27:40 +0000 (12:27 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Wed, 3 Oct 2018 11:27:40 +0000 (12:27 +0100)
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

libstdc++-v3/ChangeLog
libstdc++-v3/src/c++98/locale.cc
libstdc++-v3/src/c++98/locale_init.cc

index fe0fbf7bbdc6ab6b2b8a8a90d2bd3775ddd34433..84e61ca955c047c71f63c4d5fdb4b91d39694a50 100644 (file)
@@ -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>
 
        * include/debug/map.h
index 148bf59658ec089a778451ccbf3d000120b9b7f5..fe06d29703907e27e86bcbd94fdf54083eead3e9 100644 (file)
@@ -77,7 +77,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   locale::locale(const locale& __other) throw()
   : _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
   // assumes that the _Impl objects are constructed correctly.
@@ -86,7 +89,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   { }
 
   locale::~locale() throw()
-  { _M_impl->_M_remove_reference(); }
+  {
+    if (_M_impl != _S_classic)
+      _M_impl->_M_remove_reference();
+  }
 
   bool
   locale::operator==(const locale& __rhs) const throw()
@@ -112,8 +118,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   const locale&
   locale::operator=(const locale& __other) throw()
   {
-    __other._M_impl->_M_add_reference();
-    _M_impl->_M_remove_reference();
+    if (__other._M_impl != _S_classic)
+      __other._M_impl->_M_add_reference();
+    if (_M_impl != _S_classic)
+      _M_impl->_M_remove_reference();
     _M_impl = __other._M_impl;
     return *this;
   }
index c9078c015c31f708792c99b17f548e60d438a9fa..b580a9f9d587ef07020b0d418502d89d89ccbf82 100644 (file)
@@ -257,9 +257,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     //   fall back to lock protected access to both _S_global and
     //   its reference count.
     _M_impl = _S_global;
-    if (_M_impl == _S_classic)
-      _M_impl->_M_add_reference();
-    else
+    if (_M_impl != _S_classic)
       {
         __gnu_cxx::__scoped_lock sentry(get_locale_mutex());
         _S_global->_M_add_reference();
@@ -275,7 +273,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     {
       __gnu_cxx::__scoped_lock sentry(get_locale_mutex());
       __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;
       const string __other_name = __other.name();
       if (__other_name != "*")
@@ -284,7 +283,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     // Reference count sanity check: one reference removed for the
     // 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
     // destroyed.
     return locale(__old);