basic_string atomicity

David Edelsohn dje.gcc@gmail.com
Fri Jan 6 00:33:00 GMT 2012


Maybe something like the attached patch.

        * include/ext/atomicity.h (__exchange_and_add): Use
        __atomic_fetch_add with ACQUIRE memory model.
        (__exchange_and_sub): New function.
        (__atomic_add): Use __atomic_fetch_add with ACQUIRE memory model.
        (__exchange_and_sub_single): New function.
        (__exchange_and_sub_dispatch): New function.
        * include/bits/locale_classes.h (_M_remove_reference): Use
        __exchange_and_sub_dispatch.
        * include/bits/basic_string.h (_M_dispose): Use
        __exchange_and_sub_dispatch.
        * include/bits/ios_base.h (_M_remove_reference): Use
        __exchange_and_sub_dispatch.
        * include/bits/shared_ptr_base.h (_M_release): Use
        __exchange_and_sub_dispatch.
        (_M_weak_release): Same.


- David
-------------- next part --------------
Index: include/ext/atomicity.h
===================================================================
--- include/ext/atomicity.h	(revision 182825)
+++ include/ext/atomicity.h	(working copy)
@@ -1,6 +1,6 @@
 // Support for atomic operations -*- C++ -*-
 
-// Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010, 2011
+// Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010, 2011, 2012
 // Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
@@ -45,16 +45,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #ifdef _GLIBCXX_ATOMIC_BUILTINS
   static inline _Atomic_word 
   __exchange_and_add(volatile _Atomic_word* __mem, int __val)
-  { return __sync_fetch_and_add(__mem, __val); }
+  { return __atomic_fetch_add(__mem, __val, 2); }
+
+  static inline _Atomic_word 
+  __exchange_and_sub(volatile _Atomic_word* __mem, int __val)
+  { return __atomic_fetch_sub(__mem, __val, 3); }
 
   static inline void
   __atomic_add(volatile _Atomic_word* __mem, int __val)
-  { __sync_fetch_and_add(__mem, __val); }
+  { __atomic_fetch_add(__mem, __val, 2); }
 #else
   _Atomic_word
   __attribute__ ((__unused__))
   __exchange_and_add(volatile _Atomic_word*, int) throw ();
 
+  _Atomic_word
+  __attribute__ ((__unused__))
+  __exchange_and_sub(volatile _Atomic_word*, int) throw ();
+
   void
   __attribute__ ((__unused__))
   __atomic_add(volatile _Atomic_word*, int) throw ();
@@ -68,6 +76,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     return __result;
   }
 
+  static inline _Atomic_word
+  __exchange_and_sub_single(_Atomic_word* __mem, int __val)
+  {
+    _Atomic_word __result = *__mem;
+    *__mem -= __val;
+    return __result;
+  }
+
   static inline void
   __atomic_add_single(_Atomic_word* __mem, int __val)
   { *__mem += __val; }
@@ -86,6 +102,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif
   }
 
+  static inline _Atomic_word
+  __attribute__ ((__unused__))
+  __exchange_and_sub_dispatch(_Atomic_word* __mem, int __val)
+  {
+#ifdef __GTHREADS
+    if (__gthread_active_p())
+      return __exchange_and_sub(__mem, __val);
+    else
+      return __exchange_and_sub_single(__mem, __val);
+#else
+    return __exchange_and_sub_single(__mem, __val);
+#endif
+  }
+
   static inline void
   __attribute__ ((__unused__))
   __atomic_add_dispatch(_Atomic_word* __mem, int __val)
Index: include/bits/locale_classes.h
===================================================================
--- include/bits/locale_classes.h	(revision 182825)
+++ include/bits/locale_classes.h	(working copy)
@@ -1,7 +1,7 @@
 // Locale support -*- C++ -*-
 
 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-// 2006, 2007, 2008, 2009, 2010, 2011
+// 2006, 2007, 2008, 2009, 2010, 2011, 2012
 // Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
@@ -407,7 +407,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     {
       // Be race-detector-friendly.  For more info see bits/c++config.
       _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_refcount);
-      if (__gnu_cxx::__exchange_and_add_dispatch(&_M_refcount, -1) == 1)
+      if (__gnu_cxx::__exchange_and_sub_dispatch(&_M_refcount, 1) == 1)
 	{
           _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_refcount);
 	  __try
@@ -516,7 +516,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     {
       // Be race-detector-friendly.  For more info see bits/c++config.
       _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_refcount);
-      if (__gnu_cxx::__exchange_and_add_dispatch(&_M_refcount, -1) == 1)
+      if (__gnu_cxx::__exchange_and_sub_dispatch(&_M_refcount, 1) == 1)
 	{
           _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_refcount);
 	  __try
Index: include/bits/basic_string.h
===================================================================
--- include/bits/basic_string.h	(revision 182825)
+++ include/bits/basic_string.h	(working copy)
@@ -1,7 +1,7 @@
 // Components for manipulating sequences of characters -*- C++ -*-
 
 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-// 2006, 2007, 2008, 2009, 2010, 2011
+// 2006, 2007, 2008, 2009, 2010, 2011, 2012
 // Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
@@ -239,8 +239,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	    {
 	      // Be race-detector-friendly.  For more info see bits/c++config.
 	      _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&this->_M_refcount);
-	      if (__gnu_cxx::__exchange_and_add_dispatch(&this->_M_refcount,
-							 -1) <= 0)
+	      if (__gnu_cxx::__exchange_and_sub_dispatch(&this->_M_refcount,
+							 1) <= 0)
 		{
 		  _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&this->_M_refcount);
 		  _M_destroy(__a);
Index: include/bits/ios_base.h
===================================================================
--- include/bits/ios_base.h	(revision 182825)
+++ include/bits/ios_base.h	(working copy)
@@ -1,7 +1,7 @@
 // Iostreams base classes -*- C++ -*-
 
 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-// 2006, 2007, 2008, 2009, 2010
+// 2006, 2007, 2008, 2009, 2010, 2012
 // Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
@@ -480,7 +480,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
         // Be race-detector-friendly.  For more info see bits/c++config.
         _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_refcount);
-        int __res = __gnu_cxx::__exchange_and_add_dispatch(&_M_refcount, -1);
+        int __res = __gnu_cxx::__exchange_and_sub_dispatch(&_M_refcount, 1);
         if (__res == 0)
           {
             _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_refcount);
Index: include/bits/shared_ptr_base.h
===================================================================
--- include/bits/shared_ptr_base.h	(revision 182825)
+++ include/bits/shared_ptr_base.h	(working copy)
@@ -1,6 +1,7 @@
 // shared_ptr and weak_ptr implementation details -*- C++ -*-
 
-// Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+// Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012
+// Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -140,7 +141,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
         // Be race-detector-friendly.  For more info see bits/c++config.
         _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_use_count);
-	if (__gnu_cxx::__exchange_and_add_dispatch(&_M_use_count, -1) == 1)
+	if (__gnu_cxx::__exchange_and_sub_dispatch(&_M_use_count, 1) == 1)
 	  {
             _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_use_count);
 	    _M_dispose();
@@ -156,8 +157,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
             // Be race-detector-friendly.  For more info see bits/c++config.
             _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
-	    if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count,
-						       -1) == 1)
+	    if (__gnu_cxx::__exchange_and_sub_dispatch(&_M_weak_count,
+						       1) == 1)
               {
                 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
 	        _M_destroy();
@@ -174,7 +175,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
         // Be race-detector-friendly. For more info see bits/c++config.
         _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_weak_count);
-	if (__gnu_cxx::__exchange_and_add_dispatch(&_M_weak_count, -1) == 1)
+	if (__gnu_cxx::__exchange_and_sub_dispatch(&_M_weak_count, 1) == 1)
 	  {
             _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count);
 	    if (_Mutex_base<_Lp>::_S_need_barriers)


More information about the Libstdc++ mailing list