[compiler-rt] r316209 - [tsan] Add Mutex annotation flag for constant-initialized __tsan_mutex_linker_init behavior

Dmitry Vyukov via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 20 05:08:53 PDT 2017


Author: dvyukov
Date: Fri Oct 20 05:08:53 2017
New Revision: 316209

URL: http://llvm.org/viewvc/llvm-project?rev=316209&view=rev
Log:
[tsan] Add Mutex annotation flag for constant-initialized __tsan_mutex_linker_init behavior

Add a new flag, _⁠_tsan_mutex_not_static, which has the opposite sense
of _⁠_tsan_mutex_linker_init. When the new _⁠_tsan_mutex_not_static flag
is passed to _⁠_tsan_mutex_destroy, tsan ignores the destruction unless
the mutex was also created with the _⁠_tsan_mutex_not_static flag.

This is useful for constructors that otherwise woud set
_⁠_tsan_mutex_linker_init but cannot, because they are declared constexpr.

Google has a custom mutex with two constructors, a "linker initialized"
constructor that relies on zero-initialization and sets
⁠_⁠_tsan_mutex_linker_init, and a normal one which sets no tsan flags.
The "linker initialized" constructor is morally constexpr, but we can't
declare it constexpr because of the need to call into tsan as a side effect.

With this new flag, the normal c'tor can set _⁠_tsan_mutex_not_static,
the "linker initialized" constructor can rely on tsan's lazy initialization,
and _⁠_tsan_mutex_destroy can still handle both cases correctly.

Author: Greg Falcon (gfalcon)
Reviewed in: https://reviews.llvm.org/D39095


Modified:
    compiler-rt/trunk/include/sanitizer/tsan_interface.h
    compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_sync.h
    compiler-rt/trunk/test/tsan/custom_mutex.h

Modified: compiler-rt/trunk/include/sanitizer/tsan_interface.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/include/sanitizer/tsan_interface.h?rev=316209&r1=316208&r2=316209&view=diff
==============================================================================
--- compiler-rt/trunk/include/sanitizer/tsan_interface.h (original)
+++ compiler-rt/trunk/include/sanitizer/tsan_interface.h Fri Oct 20 05:08:53 2017
@@ -44,6 +44,11 @@ const unsigned __tsan_mutex_linker_init
 const unsigned __tsan_mutex_write_reentrant  = 1 << 1;
 // Mutex is read reentrant.
 const unsigned __tsan_mutex_read_reentrant   = 1 << 2;
+// Mutex does not have static storage duration, and must not be used after
+// its destructor runs.  The opposite of __tsan_mutex_linker_init.
+// If this flag is passed to __tsan_mutex_destroy, then the destruction
+// is ignored unless this flag was previously set on the mutex.
+const unsigned __tsan_mutex_not_static       = 1 << 8;
 
 // Mutex operation flags:
 
@@ -70,6 +75,7 @@ void __tsan_mutex_create(void *addr, uns
 // Annotate destruction of a mutex.
 // Supported flags:
 //   - __tsan_mutex_linker_init
+//   - __tsan_mutex_not_static
 void __tsan_mutex_destroy(void *addr, unsigned flags);
 
 // Annotate start of lock operation.

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc?rev=316209&r1=316208&r2=316209&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc Fri Oct 20 05:08:53 2017
@@ -84,7 +84,9 @@ void MutexDestroy(ThreadState *thr, uptr
   SyncVar *s = ctx->metamap.GetIfExistsAndLock(addr, true);
   if (s == 0)
     return;
-  if ((flagz & MutexFlagLinkerInit) || s->IsFlagSet(MutexFlagLinkerInit)) {
+  if ((flagz & MutexFlagLinkerInit)
+      || s->IsFlagSet(MutexFlagLinkerInit)
+      || ((flagz & MutexFlagNotStatic) && !s->IsFlagSet(MutexFlagNotStatic))) {
     // Destroy is no-op for linker-initialized mutexes.
     s->mtx.Unlock();
     return;

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_sync.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_sync.h?rev=316209&r1=316208&r2=316209&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_sync.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_sync.h Fri Oct 20 05:08:53 2017
@@ -34,6 +34,7 @@ enum MutexFlags {
   MutexFlagTryLockFailed       = 1 << 5, // __tsan_mutex_try_lock_failed
   MutexFlagRecursiveLock       = 1 << 6, // __tsan_mutex_recursive_lock
   MutexFlagRecursiveUnlock     = 1 << 7, // __tsan_mutex_recursive_unlock
+  MutexFlagNotStatic           = 1 << 8, // __tsan_mutex_not_static
 
   // The following flags are runtime private.
   // Mutex API misuse was detected, so don't report any more.
@@ -43,7 +44,8 @@ enum MutexFlags {
   // Must list all mutex creation flags.
   MutexCreationFlagMask        = MutexFlagLinkerInit |
                                  MutexFlagWriteReentrant |
-                                 MutexFlagReadReentrant,
+                                 MutexFlagReadReentrant |
+                                 MutexFlagNotStatic,
 };
 
 struct SyncVar {

Modified: compiler-rt/trunk/test/tsan/custom_mutex.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/tsan/custom_mutex.h?rev=316209&r1=316208&r2=316209&view=diff
==============================================================================
--- compiler-rt/trunk/test/tsan/custom_mutex.h (original)
+++ compiler-rt/trunk/test/tsan/custom_mutex.h Fri Oct 20 05:08:53 2017
@@ -6,15 +6,16 @@
 // A very primitive mutex annotated with tsan annotations.
 class Mutex {
  public:
-  Mutex(bool prof, unsigned flags)
+  Mutex(bool prof, unsigned create_flags, unsigned destroy_flags=0)
       : prof_(prof)
       , locked_(false)
-      , seq_(0) {
-    __tsan_mutex_create(this, flags);
+      , seq_(0)
+      , destroy_flags_(destroy_flags) {
+    __tsan_mutex_create(this, create_flags);
   }
 
   ~Mutex() {
-    __tsan_mutex_destroy(this, 0);
+    __tsan_mutex_destroy(this, destroy_flags_);
   }
 
   void Lock() {
@@ -57,6 +58,7 @@ class Mutex {
   const bool prof_;
   std::atomic<bool> locked_;
   int seq_;
+  unsigned destroy_flags_;
 
   // This models mutex profiling subsystem.
   static Mutex prof_mu_;




More information about the llvm-commits mailing list