[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