diff options
author | Kostya Serebryany <kcc@google.com> | 2014-02-17 14:57:49 +0000 |
---|---|---|
committer | Kostya Serebryany <kcc@google.com> | 2014-02-17 14:57:49 +0000 |
commit | 6774f2241d4108693e602a46925660f2d4d10e1d (patch) | |
tree | fa20722fe24a46f487a428bc9acb225aa5434402 | |
parent | 1c9b9bcb5c800cbe0f672e9caf21334a8bd4d855 (diff) | |
download | bcm5719-llvm-6774f2241d4108693e602a46925660f2d4d10e1d.tar.gz bcm5719-llvm-6774f2241d4108693e602a46925660f2d4d10e1d.zip |
[sanitizer] add tests for DeadlockDetector, minor fix in onLock
llvm-svn: 201514
-rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_deadlock_detector.h | 11 | ||||
-rw-r--r-- | compiler-rt/lib/sanitizer_common/tests/sanitizer_deadlock_detector_test.cc | 56 |
2 files changed, 61 insertions, 6 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_deadlock_detector.h b/compiler-rt/lib/sanitizer_common/sanitizer_deadlock_detector.h index d0ff29de4e7..8391442dacc 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_deadlock_detector.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_deadlock_detector.h @@ -36,6 +36,7 @@ class DeadlockDetectorTLS { } void addLock(uptr lock_id, uptr current_epoch) { + // Printf("addLock: %zx %zx\n", lock_id, current_epoch); if (current_epoch != epoch_) { bv_.clear(); epoch_ = current_epoch; @@ -44,6 +45,7 @@ class DeadlockDetectorTLS { } void removeLock(uptr lock_id, uptr current_epoch) { + // Printf("remLock: %zx %zx\n", lock_id, current_epoch); if (current_epoch != epoch_) { bv_.clear(); epoch_ = current_epoch; @@ -117,8 +119,8 @@ class DeadlockDetector { bool onLock(DeadlockDetectorTLS<BV> *dtls, uptr cur_node) { uptr cur_idx = nodeToIndex(cur_node); bool is_reachable = g_.isReachable(cur_idx, dtls->getLocks()); - dtls->addLock(cur_idx, current_epoch_); g_.addEdges(dtls->getLocks(), cur_idx); + dtls->addLock(cur_idx, current_epoch_); return is_reachable; } @@ -129,6 +131,13 @@ class DeadlockDetector { uptr testOnlyGetEpoch() const { return current_epoch_; } + void Print() { + for (uptr from = 0; from < size(); from++) + for (uptr to = 0; to < size(); to++) + if (g_.hasEdge(from, to)) + Printf(" %zx => %zx\n", from, to); + } + private: void check_idx(uptr idx) const { CHECK_LT(idx, size()); } diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_deadlock_detector_test.cc b/compiler-rt/lib/sanitizer_common/tests/sanitizer_deadlock_detector_test.cc index 115b233a749..3f93c2363e2 100644 --- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_deadlock_detector_test.cc +++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_deadlock_detector_test.cc @@ -32,17 +32,21 @@ typedef TwoLevelBitVector<3, BasicBitVector<u8> > BV4; // Poor man's unique_ptr. template<class BV> struct ScopedDD { - ScopedDD() { dp = new DeadlockDetector<BV>; } + ScopedDD() { + dp = new DeadlockDetector<BV>; + dp->clear(); + dtls.clear(); + } ~ScopedDD() { delete dp; } DeadlockDetector<BV> *dp; + DeadlockDetectorTLS<BV> dtls; }; template <class BV> void BasicTest() { ScopedDD<BV> sdd; DeadlockDetector<BV> &d = *sdd.dp; - DeadlockDetectorTLS<BV> dtls; - d.clear(); + DeadlockDetectorTLS<BV> &dtls = sdd.dtls; set<uptr> s; for (size_t i = 0; i < d.size() * 3; i++) { uptr node = d.newNode(0); @@ -118,8 +122,7 @@ template <class BV> void RemoveNodeTest() { ScopedDD<BV> sdd; DeadlockDetector<BV> &d = *sdd.dp; - DeadlockDetectorTLS<BV> dtls; - d.clear(); + DeadlockDetectorTLS<BV> &dtls = sdd.dtls; uptr l0 = d.newNode(0); uptr l1 = d.newNode(1); @@ -220,3 +223,46 @@ TEST(DeadlockDetector, RemoveNodeTest) { RemoveNodeTest<BV3>(); RemoveNodeTest<BV4>(); } + +template <class BV> +void MultipleEpochsTest() { + ScopedDD<BV> sdd; + DeadlockDetector<BV> &d = *sdd.dp; + DeadlockDetectorTLS<BV> &dtls = sdd.dtls; + + set<uptr> locks; + for (uptr i = 0; i < d.size(); i++) { + EXPECT_TRUE(locks.insert(d.newNode(i)).second); + } + EXPECT_EQ(d.testOnlyGetEpoch(), d.size()); + for (uptr i = 0; i < d.size(); i++) { + EXPECT_TRUE(locks.insert(d.newNode(i)).second); + EXPECT_EQ(d.testOnlyGetEpoch(), d.size() * 2); + } + locks.clear(); + + uptr l0 = d.newNode(0); + uptr l1 = d.newNode(0); + d.onLock(&dtls, l0); + d.onLock(&dtls, l1); + d.onUnlock(&dtls, l0); + EXPECT_EQ(d.testOnlyGetEpoch(), 3 * d.size()); + for (uptr i = 0; i < d.size(); i++) { + EXPECT_TRUE(locks.insert(d.newNode(i)).second); + } + EXPECT_EQ(d.testOnlyGetEpoch(), 4 * d.size()); + + // Can not handle the locks from the previous epoch. + // The user should update the lock id. + EXPECT_DEATH(d.onLock(&dtls, l0), "CHECK failed.*current_epoch_"); + EXPECT_DEATH(d.onUnlock(&dtls, l1), "CHECK failed.*current_epoch_"); +} + +TEST(DeadlockDetector, MultipleEpochsTest) { + MultipleEpochsTest<BV1>(); + MultipleEpochsTest<BV2>(); + MultipleEpochsTest<BV3>(); + MultipleEpochsTest<BV4>(); +} + + |