This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: libstdc++ and race detectors


> You didn't get my point: it was about setting _GLIBCXX_EXTERN_TEMPLATE =
> -1 for your things, like debug-mode does.

Yes, I see now. With setting -D_GLIBCXX_EXTERN_TEMPLATE=-1 the
following patch works:
http://codereview.appspot.com/download/issue1800042_7001.diff

Index: include/ext/atomicity.h
===================================================================
--- include/ext/atomicity.h	(revision 162071)
+++ include/ext/atomicity.h	(working copy)
@@ -34,6 +34,28 @@
 #include <bits/gthr.h>
 #include <bits/atomic_word.h>

+// These two macros are required to make libstdc++ race-detector-friendly.
+// By using these macros we are letting a race detector know that
+// all events that occurred before _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(x)
+// happen-before (precede) all events that occurred after the following
+// _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(x).
+// See __decrement_reference_count for an example.
+// By default, these two macros are defined empty -- anyone who wants
+// to use a race detector will need to redefine these macros to call
+// appropriate race detector API.
+//
+// In order to work properly w/o rebuilding libstdc++.so these macros should
+// be used together with -D_GLIBCXX_EXTERN_TEMPLATE=-1.
+//
+// TODO(kcc): do we need to add a link to some external documentation
+// or mention the race detection tools by name?
+#ifndef _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE
+# define  _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(a)
+#endif
+#ifndef _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER
+# define  _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(a)
+#endif
+
 _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)

   // Functions for portable atomic access.
@@ -98,6 +120,20 @@
 #endif
   }

+  // Decrement the reference counter by 1 atomically and return the old value.
+  // The code is annotated to be race-detector-friendly
+  // (see the definition of _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER).
+  static _Atomic_word
+  __decrement_reference_count(_Atomic_word* __mem)
+  {
+    _GLIBCXX_SYNCHRONIZATION_HAPPENS_BEFORE(__mem);
+    _Atomic_word __res = __gnu_cxx::__exchange_and_add_dispatch(__mem, -1);
+    if (__res == 0) {
+      _GLIBCXX_SYNCHRONIZATION_HAPPENS_AFTER(__mem);
+    }
+    return __res;
+  }
+
 _GLIBCXX_END_NAMESPACE

 // Even if the CPU doesn't need a memory barrier, we need to ensure
Index: include/bits/basic_string.h
===================================================================
--- include/bits/basic_string.h	(revision 162071)
+++ include/bits/basic_string.h	(working copy)
@@ -232,8 +232,7 @@
 #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)
+            if
(__gnu_cxx::__decrement_reference_count(&this->_M_refcount) <= 0)
 	      _M_destroy(__a);
 	}  // XXX MT



--kcc


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]