summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_deadlock_detector.h19
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_deadlock_detector1.cc4
2 files changed, 20 insertions, 3 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_deadlock_detector.h b/compiler-rt/lib/sanitizer_common/sanitizer_deadlock_detector.h
index 6d4cec86c4e..dfaacb3d22d 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_deadlock_detector.h
+++ b/compiler-rt/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));
}
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_deadlock_detector1.cc b/compiler-rt/lib/sanitizer_common/sanitizer_deadlock_detector1.cc
index 3f02b3417a2..201ad149d11 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_deadlock_detector1.cc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_deadlock_detector1.cc
@@ -132,7 +132,9 @@ void DD::MutexAfterLock(DDCallback *cb, DDMutex *m, bool wlock, bool trylock) {
// 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.
OpenPOWER on IntegriCloud