[compiler-rt] r203910 - [sanitizer] fully implement racy fast path in bitset-based deadlock detector

Kostya Serebryany kcc at google.com
Fri Mar 14 02:22:02 PDT 2014


Author: kcc
Date: Fri Mar 14 04:22:01 2014
New Revision: 203910

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

Modified:
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector1.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=203910&r1=203909&r2=203910&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 04:22:01 2014
@@ -175,9 +175,12 @@ class DeadlockDetector {
   // 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 local_epoch = dtls->getEpoch();
+    // Read from current_epoch_ is racy.
+    if (cur_node && local_epoch == current_epoch_ &&
+        local_epoch == nodeToEpoch(cur_node)) {
       uptr cur_idx = nodeToIndexUnchecked(cur_node);
-      return g_.hasAllEdges(dtls->getLocks(current_epoch_), cur_idx);
+      return g_.hasAllEdges(dtls->getLocks(local_epoch), cur_idx);
     }
     return false;
   }
@@ -267,6 +270,18 @@ class DeadlockDetector {
       dtls->removeLock(nodeToIndexUnchecked(node));
   }
 
+  // Tries to handle the lock event w/o writing to global state.
+  // Returns true on success.
+  // This operation is thread-safe as it only touches the dtls
+  // (modulo racy nature of hasAllEdges).
+  bool onLockFast(DeadlockDetectorTLS<BV> *dtls, uptr node) {
+    if (hasAllEdges(dtls, node)) {
+      dtls->addLock(nodeToIndexUnchecked(node), nodeToEpoch(node));
+      return true;
+    }
+    return false;
+  }
+
   bool isHeld(DeadlockDetectorTLS<BV> *dtls, uptr node) const {
     return dtls->getLocks(current_epoch_).getBit(nodeToIndex(node));
   }

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=203910&r1=203909&r2=203910&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 04:22:01 2014
@@ -132,7 +132,9 @@ 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;
+  if (dd.onLockFast(&lt->dd, m->id))
+    return;
+
   SpinMutexLock lk(&mtx);
   MutexEnsureID(lt, m);
   if (wlock)  // Only a recursive rlock may be held.





More information about the llvm-commits mailing list