summaryrefslogtreecommitdiff
path: root/test/tsan/deadlock_detector_stress_test.cc
diff options
context:
space:
mode:
authorKostya Serebryany <kcc@google.com>2014-02-21 15:07:18 +0000
committerKostya Serebryany <kcc@google.com>2014-02-21 15:07:18 +0000
commitde60b3af716f062752e1dee410de1064438a20af (patch)
treee700e86fb5c432ad36724f4d428b8489ef5f00af /test/tsan/deadlock_detector_stress_test.cc
parentdec7f55adcd8487a99cca5dbd90205a0fe1e73e7 (diff)
[tsan] add coarse-grained lock around the DeadlockDetector. We can do better than that, but that's a start.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@201861 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/tsan/deadlock_detector_stress_test.cc')
-rw-r--r--test/tsan/deadlock_detector_stress_test.cc55
1 files changed, 46 insertions, 9 deletions
diff --git a/test/tsan/deadlock_detector_stress_test.cc b/test/tsan/deadlock_detector_stress_test.cc
index 535ced7c6..74dafe84b 100644
--- a/test/tsan/deadlock_detector_stress_test.cc
+++ b/test/tsan/deadlock_detector_stress_test.cc
@@ -44,8 +44,8 @@ class LockTest {
// CHECK: Starting Test1
fprintf(stderr, "Expecting lock inversion: %p %p\n", A(0), A(1));
// CHECK: Expecting lock inversion: [[A1:0x[a-f0-9]*]] [[A2:0x[a-f0-9]*]]
- L(0); L(1); U(0); U(1);
- L(1); L(0); U(0); U(1);
+ Lock_0_1();
+ Lock_1_0();
// CHECK: WARNING: ThreadSanitizer: lock-order-inversion (potential deadlock)
// CHECK: path: [[M1:M[0-9]+]] => [[M2:M[0-9]+]] => [[M1]]
// CHECK: Mutex [[M1]] ([[A1]]) created at:
@@ -59,9 +59,9 @@ class LockTest {
// CHECK: Starting Test2
fprintf(stderr, "Expecting lock inversion: %p %p %p\n", A(0), A(1), A(2));
// CHECK: Expecting lock inversion: [[A1:0x[a-f0-9]*]] [[A2:0x[a-f0-9]*]] [[A3:0x[a-f0-9]*]]
- L(0); L(1); U(0); U(1);
- L(1); L(2); U(1); U(2);
- L(2); L(0); U(0); U(2);
+ Lock2(0, 1);
+ Lock2(1, 2);
+ Lock2(2, 0);
// CHECK: WARNING: ThreadSanitizer: lock-order-inversion (potential deadlock)
// CHECK: path: [[M1:M[0-9]+]] => [[M2:M[0-9]+]] => [[M3:M[0-9]+]] => [[M1]]
// CHECK: Mutex [[M1]] ([[A1]]) created at:
@@ -76,11 +76,11 @@ class LockTest {
void Test3() {
fprintf(stderr, "Starting Test3\n");
// CHECK: Starting Test3
- L(0); L(1); U(0); U(1);
+ Lock_0_1();
L(2);
CreateAndDestroyManyLocks();
U(2);
- L(1); L(0); U(0); U(1);
+ Lock_1_0();
// CHECK: WARNING: ThreadSanitizer: lock-order-inversion (potential deadlock)
// CHECK-NOT: WARNING: ThreadSanitizer:
}
@@ -90,15 +90,27 @@ class LockTest {
void Test4() {
fprintf(stderr, "Starting Test4\n");
// CHECK: Starting Test4
- L(0); L(1); U(0); U(1);
+ Lock_0_1();
L(2);
CreateLockUnlockAndDestroyManyLocks();
U(2);
- L(1); L(0); U(0); U(1);
+ Lock_1_0();
+ // CHECK-NOT: WARNING: ThreadSanitizer:
+ }
+
+ void Test5() {
+ fprintf(stderr, "Starting Test5\n");
+ // CHECK: Starting Test5
+ RunThreads(&LockTest::Lock_0_1, &LockTest::Lock_1_0);
+ // CHECK: WARNING: ThreadSanitizer: lock-order-inversion
// CHECK-NOT: WARNING: ThreadSanitizer:
}
private:
+ void Lock2(size_t l1, size_t l2) { L(l1); L(l2); U(l2); U(l1); }
+ void Lock_0_1() { Lock2(0, 1); }
+ void Lock_1_0() { Lock2(1, 0); }
+
void CreateAndDestroyManyLocks() {
PaddedLock create_many_locks_but_never_acquire[kDeadlockGraphSize];
}
@@ -109,6 +121,30 @@ class LockTest {
many_locks[i].unlock();
}
}
+
+ // LockTest Member function callback.
+ struct CB {
+ void (LockTest::*f)();
+ LockTest *lt;
+ };
+
+ // Thread function with CB.
+ static void *Thread(void *param) {
+ CB *cb = (CB*)param;
+ (cb->lt->*cb->f)();
+ return NULL;
+ }
+
+ void RunThreads(void (LockTest::*f1)(), void (LockTest::*f2)()) {
+ const int kNumThreads = 2;
+ pthread_t t[kNumThreads];
+ CB cb[2] = {{f1, this}, {f2, this}};
+ for (int i = 0; i < kNumThreads; i++)
+ pthread_create(&t[i], 0, Thread, &cb[i]);
+ for (int i = 0; i < kNumThreads; i++)
+ pthread_join(t[i], 0);
+ }
+
static const size_t kDeadlockGraphSize = 4096;
size_t n_;
PaddedLock *locks_;
@@ -119,6 +155,7 @@ int main() {
{ LockTest t(5); t.Test2(); }
{ LockTest t(5); t.Test3(); }
{ LockTest t(5); t.Test4(); }
+ { LockTest t(5); t.Test5(); }
fprintf(stderr, "DONE\n");
// CHECK: DONE
}