]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++config (_GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE, [...]): Add.
authorKostya Serebryany <kcc@google.com>
Thu, 12 Aug 2010 22:56:59 +0000 (22:56 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Thu, 12 Aug 2010 22:56:59 +0000 (22:56 +0000)
2010-08-12  Kostya Serebryany <kcc@google.com>
    Paolo Carlini  <paolo.carlini@oracle.com>

* include/bits/c++config (_GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE,
_GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER): Add.
* src/ios_init.cc (ios_base::Init::~Init): Decorate with the
latter.
* include/tr1_impl/boost_sp_counted_base.h: Likewise.
* include/ext/rc_string_base.h: Likewise.
* include/bits/locale_classes.h: Likewise.
* include/bits/basic_string.h: Likewise.
* include/bits/ios_base.h: Likewise.
* testsuite/27_io/ios_base/cons/assign_neg.cc: Adjust dg-error
line number.
* testsuite/27_io/ios_base/cons/copy_neg.cc: Likewise.
* testsuite/ext/profile/mutex_extensions.cc: Likewise.

Co-Authored-By: Paolo Carlini <paolo.carlini@oracle.com>
From-SVN: r163210

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/basic_string.h
libstdc++-v3/include/bits/c++config
libstdc++-v3/include/bits/ios_base.h
libstdc++-v3/include/bits/locale_classes.h
libstdc++-v3/include/ext/rc_string_base.h
libstdc++-v3/include/tr1_impl/boost_sp_counted_base.h
libstdc++-v3/src/ios_init.cc
libstdc++-v3/testsuite/27_io/ios_base/cons/assign_neg.cc
libstdc++-v3/testsuite/27_io/ios_base/cons/copy_neg.cc
libstdc++-v3/testsuite/ext/profile/mutex_extensions.cc

index 84d35983fb8ca8ed9d1886a1eb9fb33765db22b9..f133c0a51fa867cadf4c62eb00ef9cb6a340809f 100644 (file)
@@ -1,3 +1,20 @@
+2010-08-12  Kostya Serebryany <kcc@google.com>
+           Paolo Carlini  <paolo.carlini@oracle.com>
+
+       * include/bits/c++config (_GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE,
+       _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER): Add.
+       * src/ios_init.cc (ios_base::Init::~Init): Decorate with the
+       latter.
+       * include/tr1_impl/boost_sp_counted_base.h: Likewise.
+       * include/ext/rc_string_base.h: Likewise.
+       * include/bits/locale_classes.h: Likewise.
+       * include/bits/basic_string.h: Likewise.
+       * include/bits/ios_base.h: Likewise.
+       * testsuite/27_io/ios_base/cons/assign_neg.cc: Adjust dg-error
+       line number.
+       * testsuite/27_io/ios_base/cons/copy_neg.cc: Likewise.
+       * testsuite/ext/profile/mutex_extensions.cc: Likewise.
+
 2010-08-11  Paolo Carlini  <paolo.carlini@oracle.com>
 
        * include/bits/hashtable.h (_Hashtable<>::erase(const key_type&)):
index fe9e1a3519c38f6fd17738ade497352f8e49a2aa..74820eb348e8c56aab2539fcafd65c2f17f1ae92 100644 (file)
@@ -232,9 +232,16 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
 #ifndef _GLIBCXX_FULLY_DYNAMIC_STRING
          if (__builtin_expect(this != &_S_empty_rep(), false))
 #endif
-           if (__gnu_cxx::__exchange_and_add_dispatch(&this->_M_refcount,
-                                                      -1) <= 0)
-             _M_destroy(__a);
+           {
+             // 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)
+               {
+                 _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&this->_M_refcount)
+                 _M_destroy(__a);
+               }
+           }
        }  // XXX MT
 
        void
index 9dc9ac24cd8d473e3c2082ed68f1f7e2e489087d..fef6933a3b5c390ede2c7912802e169d8bfc8a17 100644 (file)
 # define _GLIBCXX_DEPRECATED_ATTR
 #endif
 
+// Macros for race detectors.
+// _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(A) and
+// _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(A) should be used to explain
+// atomic (lock-free) synchronization to race detectors:
+// the race detector will infer a happens-before arc from the former to the
+// latter when they share the same argument pointer.
+//
+// The most frequent use case for these macros (and the only case in the
+// current implementation of the library) is atomic reference counting:
+//   void _M_remove_reference()
+//   {
+//     _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&this->_M_refcount)
+//     if (__gnu_cxx::__exchange_and_add_dispatch(&this->_M_refcount, -1) <= 0)
+//       {
+//         _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&this->_M_refcount)
+//         _M_destroy(__a);
+//       }
+//   }
+// The annotations in this example tell the race detector that all memory
+// accesses occurred when the refcount was positive do not race with
+// memory accesses which occurred after the refcount became zero.
+
+#ifndef _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE
+# define  _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(A)
+#endif
+#ifndef _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER
+# define  _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(A)
+#endif
+
 // Macros for activating various namespace association modes.
 // _GLIBCXX_NAMESPACE_ASSOCIATION_DEBUG
 // _GLIBCXX_NAMESPACE_ASSOCIATION_PARALLEL
index 6515dd40e8e97c275558927bbb6e7a8b6173e5b0..6cca99166ca7172e36a1b7eaf7e3ed2f1406731a 100644 (file)
@@ -474,7 +474,16 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
       // 0 => OK to delete.
       int
       _M_remove_reference() 
-      { return __gnu_cxx::__exchange_and_add_dispatch(&_M_refcount, -1); }
+      {
+        // 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);
+        if (__res == 0)
+          {
+            _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_refcount)
+          }
+        return __res;
+      }
     };
 
      _Callback_list*   _M_callbacks;
@@ -962,4 +971,3 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
 _GLIBCXX_END_NAMESPACE
 
 #endif /* _IOS_BASE_H */
-
index 347e76124865f452c2702fb6d9926fc11789ab8f..c519f3584766f256e7ab5ded0c4de42db86c9a52 100644 (file)
@@ -402,8 +402,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
     void
     _M_remove_reference() const throw()
     {
+      // 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)
        {
+          _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_refcount)
          __try
            { delete this; }
          __catch(...)
@@ -508,8 +511,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
     void
     _M_remove_reference() throw()
     {
+      // 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)
        {
+          _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_refcount)
          __try
            { delete this; }
          __catch(...)
index dd18738dc57af2e4ddbbb1f0339071e3833e6af7..32c9d3865aeef4d257ba1ad2b0eaa968c38a1516 100644 (file)
@@ -199,9 +199,16 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
       void
       _M_dispose()
       {
+       // Be race-detector-friendly.  For more info see bits/c++config.
+       _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_M_rep()->_M_info.
+                                               _M_refcount)
        if (__exchange_and_add_dispatch(&_M_rep()->_M_info._M_refcount,
                                        -1) <= 0)
-         _M_rep()->_M_destroy(_M_get_allocator());
+         {
+           _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_rep()->_M_info.
+                                                  _M_refcount)
+           _M_rep()->_M_destroy(_M_get_allocator());
+         }
       }  // XXX MT
 
       bool
index 56030856dca639caa2e56489be5aa860c617f58c..a995df5bb767293e6691645a070e7b412926332f 100644 (file)
@@ -1,6 +1,6 @@
 // <tr1_impl/boost_sp_counted_base.h> -*- C++ -*-
 
-// Copyright (C) 2007, 2009 Free Software Foundation, Inc.
+// Copyright (C) 2007, 2008, 2009, 2010 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
@@ -139,8 +139,11 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
       void
       _M_release() // nothrow
       {
+        // 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)
          {
+            _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_use_count)
            _M_dispose();
            // There must be a memory barrier between dispose() and destroy()
            // to ensure that the effects of dispose() are observed in the
@@ -152,9 +155,14 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
                _GLIBCXX_WRITE_MEM_BARRIER;
              }
 
+            // 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)
-             _M_destroy();
+              {
+                _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count)
+               _M_destroy();
+              }
          }
       }
   
@@ -165,8 +173,11 @@ _GLIBCXX_BEGIN_NAMESPACE_TR1
       void
       _M_weak_release() // nothrow
       {
+        // 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)
          {
+            _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_M_weak_count)
            if (_Mutex_base<_Lp>::_S_need_barriers)
              {
                // See _M_release(),
index 1885d825971a1007136ab9b00a9de0aacc391a06..209a324a9313e0cd637da705b63144286ce43335 100644 (file)
@@ -1,7 +1,7 @@
 // Iostreams base classes -*- C++ -*-
 
 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-// 2006, 2007, 2008, 2009
+// 2006, 2007, 2008, 2009, 2010
 // Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
@@ -122,8 +122,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
 
   ios_base::Init::~Init()
   {
+    // Be race-detector-friendly.  For more info see bits/c++config.
+    _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(&_S_refcount)
     if (__gnu_cxx::__exchange_and_add_dispatch(&_S_refcount, -1) == 2)
       {
+        _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(&_S_refcount)
        // Catch any exceptions thrown by basic_ostream::flush()
        __try
          { 
index 9f85ad1c9d8f4d5b3a3f440bcbe8d512fa3c8646..a7adff4d3f482eefdcb2a7fa9d186f84edcc6054 100644 (file)
@@ -34,5 +34,5 @@ void test01()
 }
 // { dg-error "synthesized" "" { target *-*-* } 33 } 
 // { dg-error "within this context" "" { target *-*-* } 26 } 
-// { dg-error "is private" "" { target *-*-* } 779 }
+// { dg-error "is private" "" { target *-*-* } 788 }
 // { dg-error "operator=" "" { target *-*-* } 0 } 
index 2a7573749bdf00d0a24ee889f561d151547e52b8..44f7af87da82e1d2bb3fcd2427ada33d22d7cadd 100644 (file)
@@ -34,5 +34,5 @@ void test02()
 }
 // { dg-error "within this context" "" { target *-*-* } 26 }
 // { dg-error "synthesized" "" { target *-*-* } 33 } 
-// { dg-error "is private" "" { target *-*-* } 776 } 
+// { dg-error "is private" "" { target *-*-* } 785 } 
 // { dg-error "copy constructor" "" { target *-*-* } 0 } 
index 4b306619ff9fc820e6ddc7e3c2af95c63e4b7e5f..471c4482b2d41fa19dbd47150760d70b4585da67 100644 (file)
@@ -3,7 +3,7 @@
 
 // -*- C++ -*-
 
-// Copyright (C) 2006, 2007, 2009 Free Software Foundation, Inc.
+// Copyright (C) 2006, 2007, 2009, 2010 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
@@ -22,4 +22,4 @@
 
 #include <vector>
 
-// { dg-error "Cannot use -D_GLIBCXX_PROFILE with " "" { target *-*-* } 167 }
+// { dg-error "Cannot use -D_GLIBCXX_PROFILE with " "" { target *-*-* } 196 }