[compiler-rt] r201568 - [tsan] in deadlock detector do not register locks on their creation and unregister them on destruction; added a relevant test

Kostya Serebryany kcc at google.com
Tue Feb 18 04:50:32 PST 2014


Author: kcc
Date: Tue Feb 18 06:50:31 2014
New Revision: 201568

URL: http://llvm.org/viewvc/llvm-project?rev=201568&view=rev
Log:
[tsan] in deadlock detector do not register locks on their creation and unregister them on destruction; added a relevant test

Modified:
    compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc
    compiler-rt/trunk/test/tsan/deadlock_detector_stress_test.cc

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=201568&r1=201567&r2=201568&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc Tue Feb 18 06:50:31 2014
@@ -45,10 +45,6 @@ void MutexCreate(ThreadState *thr, uptr
   s->is_rw = rw;
   s->is_recursive = recursive;
   s->is_linker_init = linker_init;
-  if (common_flags()->detect_deadlocks) {
-    EnsureDeadlockDetectorID(thr, s);
-    Printf("MutexCreate: %zx\n", s->deadlock_detector_id);
-  }
   s->mtx.Unlock();
 }
 
@@ -66,8 +62,9 @@ void MutexDestroy(ThreadState *thr, uptr
   if (s == 0)
     return;
   if (common_flags()->detect_deadlocks) {
-    EnsureDeadlockDetectorID(thr, s);
-    Printf("MutexDestroy: %zx\n", s->deadlock_detector_id);
+    if (s->deadlock_detector_id)
+      g_deadlock_detector.removeNode(s->deadlock_detector_id);
+    s->deadlock_detector_id = 0;
   }
   if (IsAppMem(addr)) {
     CHECK(!thr->is_freeing);
@@ -169,7 +166,7 @@ int MutexUnlock(ThreadState *thr, uptr p
   thr->mset.Del(s->GetId(), true);
   if (common_flags()->detect_deadlocks) {
     EnsureDeadlockDetectorID(thr, s);
-    Printf("MutexUnlock: %zx\n", s->deadlock_detector_id);
+    // Printf("MutexUnlock: %zx\n", s->deadlock_detector_id);
     g_deadlock_detector.onUnlock(&thr->deadlock_detector_tls,
                                  s->deadlock_detector_id);
   }

Modified: compiler-rt/trunk/test/tsan/deadlock_detector_stress_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/tsan/deadlock_detector_stress_test.cc?rev=201568&r1=201567&r2=201568&view=diff
==============================================================================
--- compiler-rt/trunk/test/tsan/deadlock_detector_stress_test.cc (original)
+++ compiler-rt/trunk/test/tsan/deadlock_detector_stress_test.cc Tue Feb 18 06:50:31 2014
@@ -33,6 +33,7 @@ class LockTest {
     locks_[i].unlock();
   }
 
+  // Simple lock order onversion.
   void Test1() {
     fprintf(stderr, "Starting Test1\n");
     // CHECK: Starting Test1
@@ -42,6 +43,7 @@ class LockTest {
     // CHECK-NOT: ThreadSanitizer:
   }
 
+  // Simple lock order inversion with 3 locks.
   void Test2() {
     fprintf(stderr, "Starting Test2\n");
     // CHECK: Starting Test2
@@ -51,7 +53,24 @@ class LockTest {
     // CHECK-NOT: ThreadSanitizer:
   }
 
+  // Lock order inversion with lots of new locks created (but not used)
+  // between. Since the new locks are not used we should still detect the
+  // deadlock.
+  void Test3() {
+    fprintf(stderr, "Starting Test3\n");
+    // CHECK: Starting Test3
+    L(0); L(1); U(0); U(1);
+    CreateAndDestroyManyLocks();
+    L(1); L(0); U(0); U(1);
+    // CHECK: ThreadSanitizer: lock-order-inversion (potential deadlock)
+    // CHECK-NOT: ThreadSanitizer:
+  }
+
  private:
+  void CreateAndDestroyManyLocks() {
+    PaddedLock create_many_locks_but_never_acquire[kDeadlockGraphSize];
+  }
+  static const size_t kDeadlockGraphSize = 4096;
   size_t n_;
   PaddedLock *locks_;
 };
@@ -59,6 +78,7 @@ class LockTest {
 int main() {
   { LockTest t(5); t.Test1(); }
   { LockTest t(5); t.Test2(); }
+  { LockTest t(5); t.Test3(); }
   fprintf(stderr, "DONE\n");
   // CHECK: DONE
 }





More information about the llvm-commits mailing list