forked from OSchip/llvm-project
[tsan] in deadlock detector do not register locks on their creation and unregister them on destruction; added a relevant test
llvm-svn: 201568
This commit is contained in:
parent
a50abe6656
commit
aa416c39cd
|
|
@ -45,10 +45,6 @@ void MutexCreate(ThreadState *thr, uptr pc, uptr addr,
|
|||
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 pc, uptr addr) {
|
|||
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 pc, uptr addr, bool all) {
|
|||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue