diff options
author | Kostya Serebryany <kcc@google.com> | 2014-03-14 09:22:01 +0000 |
---|---|---|
committer | Kostya Serebryany <kcc@google.com> | 2014-03-14 09:22:01 +0000 |
commit | 283cb74c1b8ae162f67dc16d71c13b6db7252bda (patch) | |
tree | 8eec63fc7e0849da041fd9d88f1235c3abf62ffd /lib/sanitizer_common/sanitizer_deadlock_detector.h | |
parent | 30fd39fe12a619c9317d0dbd605b63cd044a0f43 (diff) |
[sanitizer] fully implement racy fast path in bitset-based deadlock detector
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@203910 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/sanitizer_common/sanitizer_deadlock_detector.h')
-rw-r--r-- | lib/sanitizer_common/sanitizer_deadlock_detector.h | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/lib/sanitizer_common/sanitizer_deadlock_detector.h b/lib/sanitizer_common/sanitizer_deadlock_detector.h index 6d4cec86c..dfaacb3d2 100644 --- a/lib/sanitizer_common/sanitizer_deadlock_detector.h +++ b/lib/sanitizer_common/sanitizer_deadlock_detector.h @@ -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)); } |