diff options
| -rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_interceptors.cc | 4 | ||||
| -rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cc | 19 | ||||
| -rw-r--r-- | compiler-rt/test/tsan/deadlock_detector_stress_test.cc | 44 | 
3 files changed, 43 insertions, 24 deletions
diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc index ad8dd7155ae..c87ad2d90bd 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc @@ -1047,7 +1047,7 @@ TSAN_INTERCEPTOR(int, pthread_rwlock_tryrdlock, void *m) {    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_trywrlock, void *m) {    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;  } diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cc b/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cc index b82768413b1..6a3100975e5 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cc @@ -29,6 +29,15 @@ static void EnsureDeadlockDetectorID(Context *ctx, ThreadState *thr,    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 pc, uptr addr, bool all) {      }    }    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, uptr pc, uptr addr) {      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 *thr, uptr pc, uptr addr) {      PrintCurrentStack(thr, pc);    }    thr->mset.Del(s->GetId(), write); +  DDUnlock(CTX(), thr, s);    s->mtx.Unlock();  } diff --git a/compiler-rt/test/tsan/deadlock_detector_stress_test.cc b/compiler-rt/test/tsan/deadlock_detector_stress_test.cc index da9451f21da..a4d4505a689 100644 --- a/compiler-rt/test/tsan/deadlock_detector_stress_test.cc +++ b/compiler-rt/test/tsan/deadlock_detector_stress_test.cc @@ -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  }  | 

