[compiler-rt] r202128 - [sanitizer] partially support pthread_rwlock_* (no rd* form yet)

Kostya Serebryany kcc at google.com
Tue Feb 25 01:33:10 PST 2014


Author: kcc
Date: Tue Feb 25 03:33:10 2014
New Revision: 202128

URL: http://llvm.org/viewvc/llvm-project?rev=202128&view=rev
Log:
[sanitizer] partially support pthread_rwlock_* (no rd* form yet)

Modified:
    compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
    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_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc?rev=202128&r1=202127&r2=202128&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc Tue Feb 25 03:33:10 2014
@@ -1047,7 +1047,7 @@ TSAN_INTERCEPTOR(int, pthread_rwlock_try
   SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_tryrdlock, m);
   int res = REAL(pthread_rwlock_tryrdlock)(m);
   if (res == 0) {
-    MutexReadLock(thr, pc, (uptr)m);
+    MutexLock(thr, pc, (uptr)m, /*rec=*/1, /*try_lock=*/true);
   }
   return res;
 }
@@ -1074,7 +1074,7 @@ TSAN_INTERCEPTOR(int, pthread_rwlock_try
   SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_trywrlock, m);
   int res = REAL(pthread_rwlock_trywrlock)(m);
   if (res == 0) {
-    MutexLock(thr, pc, (uptr)m);
+    MutexLock(thr, pc, (uptr)m, /*rec=*/1, /*try_lock=*/true);
   }
   return res;
 }

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=202128&r1=202127&r2=202128&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 25 03:33:10 2014
@@ -29,6 +29,15 @@ static void EnsureDeadlockDetectorID(Con
   ctx->dd.ensureCurrentEpoch(&thr->deadlock_detector_tls);
 }
 
+static void DDUnlock(Context *ctx, ThreadState *thr,
+                                     SyncVar *s) {
+  if (!common_flags()->detect_deadlocks) return;
+  Lock lk(&ctx->dd_mtx);
+  EnsureDeadlockDetectorID(ctx, thr, s);
+  // Printf("MutexUnlock: %zx\n", s->deadlock_detector_id);
+  ctx->dd.onUnlock(&thr->deadlock_detector_tls, s->deadlock_detector_id);
+}
+
 void MutexCreate(ThreadState *thr, uptr pc, uptr addr,
                  bool rw, bool recursive, bool linker_init) {
   Context *ctx = CTX();
@@ -186,13 +195,7 @@ int MutexUnlock(ThreadState *thr, uptr p
     }
   }
   thr->mset.Del(s->GetId(), true);
-  if (common_flags()->detect_deadlocks) {
-    Lock lk(&ctx->dd_mtx);
-    EnsureDeadlockDetectorID(ctx, thr, s);
-    // Printf("MutexUnlock: %zx\n", s->deadlock_detector_id);
-    ctx->dd.onUnlock(&thr->deadlock_detector_tls,
-                                 s->deadlock_detector_id);
-  }
+  DDUnlock(ctx, thr, s);
   s->mtx.Unlock();
   return rec;
 }
@@ -230,6 +233,7 @@ void MutexReadUnlock(ThreadState *thr, u
     PrintCurrentStack(thr, pc);
   }
   ReleaseImpl(thr, pc, &s->read_clock);
+  DDUnlock(CTX(), thr, s);
   s->mtx.Unlock();
   thr->mset.Del(s->GetId(), false);
 }
@@ -267,6 +271,7 @@ void MutexReadOrWriteUnlock(ThreadState
     PrintCurrentStack(thr, pc);
   }
   thr->mset.Del(s->GetId(), write);
+  DDUnlock(CTX(), thr, s);
   s->mtx.Unlock();
 }
 

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=202128&r1=202127&r2=202128&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 25 03:33:10 2014
@@ -1,4 +1,8 @@
-// RUN: %clangxx_tsan %s -o %t
+// RUN: %clangxx_tsan %s -o %t -DLockType=PthreadMutex
+// RUN: TSAN_OPTIONS=detect_deadlocks=1 not %t 2>&1 | FileCheck %s
+// RUN: %clangxx_tsan %s -o %t -DLockType=PthreadSpinLock
+// RUN: TSAN_OPTIONS=detect_deadlocks=1 not %t 2>&1 | FileCheck %s
+// RUN: %clangxx_tsan %s -o %t -DLockType=PthreadRWLock
 // RUN: TSAN_OPTIONS=detect_deadlocks=1 not %t 2>&1 | FileCheck %s
 #include <pthread.h>
 #undef NDEBUG
@@ -37,8 +41,22 @@ class PthreadSpinLock {
   char padding_[64 - sizeof(pthread_spinlock_t)];
 };
 
+class PthreadRWLock {
+ public:
+  PthreadRWLock() { assert(0 == pthread_rwlock_init(&mu_, 0)); }
+  ~PthreadRWLock() {
+    assert(0 == pthread_rwlock_destroy(&mu_));
+    (void)padding_;
+  }
+  void lock() { assert(0 == pthread_rwlock_wrlock(&mu_)); }
+  void unlock() { assert(0 == pthread_rwlock_unlock(&mu_)); }
+  bool try_lock() { return 0 == pthread_rwlock_trywrlock(&mu_); }
+
+ private:
+  pthread_rwlock_t mu_;
+  char padding_[64 - sizeof(pthread_rwlock_t)];
+};
 
-template <class LockType>
 class LockTest {
  public:
   LockTest(size_t n) : n_(n), locks_(new LockType[n]) { }
@@ -184,7 +202,9 @@ class LockTest {
 
   void CreateAndDestroyManyLocks() {
     LockType create_many_locks_but_never_acquire[kDeadlockGraphSize];
+    (void)create_many_locks_but_never_acquire;
   }
+
   void CreateLockUnlockAndDestroyManyLocks() {
     LockType many_locks[kDeadlockGraphSize];
     for (size_t i = 0; i < kDeadlockGraphSize; i++) {
@@ -222,20 +242,14 @@ class LockTest {
   LockType *locks_;
 };
 
-template <class LockType>
-void RunAllTests() {
-  { LockTest<LockType> t(5); t.Test1(); }
-  { LockTest<LockType> t(5); t.Test2(); }
-  { LockTest<LockType> t(5); t.Test3(); }
-  { LockTest<LockType> t(5); t.Test4(); }
-  { LockTest<LockType> t(5); t.Test5(); }
-  { LockTest<LockType> t(5); t.Test6(); }
-  { LockTest<LockType> t(10); t.Test7(); }
-}
-
 int main () {
-  RunAllTests<PthreadMutex>();
-  RunAllTests<PthreadSpinLock>();
+  { LockTest t(5); t.Test1(); }
+  { LockTest t(5); t.Test2(); }
+  { LockTest t(5); t.Test3(); }
+  { LockTest t(5); t.Test4(); }
+  { LockTest t(5); t.Test5(); }
+  { LockTest t(5); t.Test6(); }
+  { LockTest t(10); t.Test7(); }
   fprintf(stderr, "DONE\n");
   // CHECK: DONE
 }





More information about the llvm-commits mailing list