summaryrefslogtreecommitdiff
path: root/lib/sanitizer_common/sanitizer_deadlock_detector.h
diff options
context:
space:
mode:
authorKostya Serebryany <kcc@google.com>2014-02-18 13:41:49 +0000
committerKostya Serebryany <kcc@google.com>2014-02-18 13:41:49 +0000
commit47fe1ee3d6bb8b6f3dd789895028ec4c308872c6 (patch)
tree4f0ff2aacd52af647e24b2273ad109a0961a4e42 /lib/sanitizer_common/sanitizer_deadlock_detector.h
parentc379a21cf7b6fb5414d10391b263c150d25989db (diff)
[sanitizer] make sure the deadlock detector survives the change of epochs; add a test and a comment
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@201572 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/sanitizer_common/sanitizer_deadlock_detector.h')
-rw-r--r--lib/sanitizer_common/sanitizer_deadlock_detector.h15
1 files changed, 14 insertions, 1 deletions
diff --git a/lib/sanitizer_common/sanitizer_deadlock_detector.h b/lib/sanitizer_common/sanitizer_deadlock_detector.h
index 8391442da..48ea022a5 100644
--- a/lib/sanitizer_common/sanitizer_deadlock_detector.h
+++ b/lib/sanitizer_common/sanitizer_deadlock_detector.h
@@ -12,6 +12,13 @@
// When a lock event happens, the detector checks if the locks already held by
// the current thread are reachable from the newly acquired lock.
//
+// The detector can handle only a fixed amount of simultaneously live locks
+// (a lock is alive if it has been locked at least once and has not been
+// destroyed). When the maximal number of locks is reached the entire graph
+// is flushed and the new lock epoch is started. The node ids from the old
+// epochs can not be used with any of the detector methods except for
+// nodeBelongsToCurrentEpoch().
+//
// FIXME: this is work in progress, nothing really works yet.
//
//===----------------------------------------------------------------------===//
@@ -37,6 +44,7 @@ class DeadlockDetectorTLS {
void addLock(uptr lock_id, uptr current_epoch) {
// Printf("addLock: %zx %zx\n", lock_id, current_epoch);
+ CHECK_LE(epoch_, current_epoch);
if (current_epoch != epoch_) {
bv_.clear();
epoch_ = current_epoch;
@@ -46,11 +54,12 @@ class DeadlockDetectorTLS {
void removeLock(uptr lock_id, uptr current_epoch) {
// Printf("remLock: %zx %zx\n", lock_id, current_epoch);
+ CHECK_LE(epoch_, current_epoch);
if (current_epoch != epoch_) {
bv_.clear();
epoch_ = current_epoch;
}
- CHECK(bv_.clearBit(lock_id));
+ bv_.clearBit(lock_id); // May already be cleared due to epoch update.
}
const BV &getLocks() const { return bv_; }
@@ -107,6 +116,10 @@ class DeadlockDetector {
// Get data associated with the node created by newNode().
uptr getData(uptr node) const { return data_[nodeToIndex(node)]; }
+ bool nodeBelongsToCurrentEpoch(uptr node) {
+ return node && (node / size() * size()) == current_epoch_;
+ }
+
void removeNode(uptr node) {
uptr idx = nodeToIndex(node);
CHECK(!available_nodes_.getBit(idx));