[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