summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKostya Serebryany <kcc@google.com>2014-02-17 14:57:49 +0000
committerKostya Serebryany <kcc@google.com>2014-02-17 14:57:49 +0000
commit6774f2241d4108693e602a46925660f2d4d10e1d (patch)
treefa20722fe24a46f487a428bc9acb225aa5434402
parent1c9b9bcb5c800cbe0f672e9caf21334a8bd4d855 (diff)
downloadbcm5719-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.h11
-rw-r--r--compiler-rt/lib/sanitizer_common/tests/sanitizer_deadlock_detector_test.cc56
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>();
+}
+
+
OpenPOWER on IntegriCloud