[compiler-rt] r203904 - [sanitizer] partially implement racy fast path in bitset-based deadlock detector

Kostya Serebryany kcc at google.com
Fri Mar 14 01:06:16 PDT 2014


Author: kcc
Date: Fri Mar 14 03:06:15 2014
New Revision: 203904

URL: http://llvm.org/viewvc/llvm-project?rev=203904&view=rev
Log:
[sanitizer] partially implement racy fast path in bitset-based deadlock detector

Modified:
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_bvgraph.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector1.cc
    compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_bvgraph_test.cc

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_bvgraph.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_bvgraph.h?rev=203904&r1=203903&r2=203904&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_bvgraph.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_bvgraph.h Fri Mar 14 03:06:15 2014
@@ -60,6 +60,20 @@ class BVGraph {
     return res;
   }
 
+  // *EXPERIMENTAL*
+  // Returns true if all edges from=>to exist.
+  // This function does not use any global state except for 'this' itself,
+  // and thus can be called from different threads w/o locking.
+  // This would be racy.
+  // FIXME: investigate how much we can prove about this race being "benign".
+  bool hasAllEdges(const BV &from, uptr to) {
+    for (typename BV::Iterator it(from); it.hasNext(); ) {
+      uptr idx = it.next();
+      if (!v[idx].getBit(to)) return false;
+    }
+    return true;
+  }
+
   // Returns true if the edge from=>to was removed.
   bool removeEdge(uptr from, uptr to) {
     return v[from].clearBit(to);

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=203904&r1=203903&r2=203904&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector.h Fri Mar 14 03:06:15 2014
@@ -172,6 +172,16 @@ class DeadlockDetector {
     dtls->addLock(cur_idx, current_epoch_);
   }
 
+  // Experimental *racy* fast path function.
+  // Returns true if all edges from the currently held locks to cur_node exist.
+  bool hasAllEdges(DeadlockDetectorTLS<BV> *dtls, uptr cur_node) {
+    if (dtls->getEpoch() == nodeToEpoch(cur_node)) {
+      uptr cur_idx = nodeToIndexUnchecked(cur_node);
+      return g_.hasAllEdges(dtls->getLocks(current_epoch_), cur_idx);
+    }
+    return false;
+  }
+
   // Adds edges from currently held locks to cur_node,
   // returns the number of added edges, and puts the sources of added edges
   // into added_edges[].

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector1.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector1.cc?rev=203904&r1=203903&r2=203904&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector1.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector1.cc Fri Mar 14 03:06:15 2014
@@ -100,6 +100,7 @@ void DD::MutexBeforeLock(DDCallback *cb,
     DDMutex *m, bool wlock) {
   DDLogicalThread *lt = cb->lt;
   if (lt->dd.empty()) return;  // This will be the first lock held by lt.
+  if (dd.hasAllEdges(&lt->dd, m->id)) return;  // We already have all edges.
   SpinMutexLock lk(&mtx);
   MutexEnsureID(lt, m);
   if (dd.isHeld(&lt->dd, m->id))
@@ -131,6 +132,7 @@ void DD::MutexAfterLock(DDCallback *cb,
   // Printf("T%p MutexLock:   %zx\n", lt, m->id);
   if (dd.onFirstLock(&lt->dd, m->id))
     return;
+  // if (dd.hasAllEdges(&lt->dd, m->id)) return;
   SpinMutexLock lk(&mtx);
   MutexEnsureID(lt, m);
   if (wlock)  // Only a recursive rlock may be held.

Modified: compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_bvgraph_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_bvgraph_test.cc?rev=203904&r1=203903&r2=203904&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_bvgraph_test.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_bvgraph_test.cc Fri Mar 14 03:06:15 2014
@@ -320,10 +320,14 @@ void RunAddEdgesTest() {
   from.clear();
   from.setBit(1);
   EXPECT_EQ(1U, g.addEdges(from, 4, added_edges, kMaxEdges));
+  EXPECT_TRUE(g.hasAllEdges(from, 4));
+  EXPECT_FALSE(g.hasAllEdges(from, 5));
   EXPECT_EQ(1U, added_edges[0]);
   from.setBit(2);
   from.setBit(3);
+  EXPECT_FALSE(g.hasAllEdges(from, 4));
   EXPECT_EQ(2U, g.addEdges(from, 4, added_edges, kMaxEdges));
+  EXPECT_TRUE(g.hasAllEdges(from, 4));
   EXPECT_EQ(2U, added_edges[0]);
   EXPECT_EQ(3U, added_edges[1]);
 }





More information about the llvm-commits mailing list