[compiler-rt] r201514 - [sanitizer] add tests for DeadlockDetector, minor fix in onLock
Kostya Serebryany
kcc at google.com
Mon Feb 17 06:57:49 PST 2014
Author: kcc
Date: Mon Feb 17 08:57:49 2014
New Revision: 201514
URL: http://llvm.org/viewvc/llvm-project?rev=201514&view=rev
Log:
[sanitizer] add tests for DeadlockDetector, minor fix in onLock
Modified:
compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector.h
compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_deadlock_detector_test.cc
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector.h?rev=201514&r1=201513&r2=201514&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector.h Mon Feb 17 08:57:49 2014
@@ -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()); }
Modified: compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_deadlock_detector_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_deadlock_detector_test.cc?rev=201514&r1=201513&r2=201514&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_deadlock_detector_test.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_deadlock_detector_test.cc Mon Feb 17 08:57:49 2014
@@ -32,17 +32,21 @@ typedef TwoLevelBitVector<3, BasicBitVec
// 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>();
+}
+
+
More information about the llvm-commits
mailing list