diff options
author | Kostya Serebryany <kcc@google.com> | 2014-03-13 10:26:03 +0000 |
---|---|---|
committer | Kostya Serebryany <kcc@google.com> | 2014-03-13 10:26:03 +0000 |
commit | 9e3d8e217529ca919355bf369f6755513e57bc50 (patch) | |
tree | 8b5acb3943b828f2a6e2d66c56b0950b88871312 /lib/sanitizer_common/sanitizer_deadlock_detector.h | |
parent | 466a11b1a30610984ba55186464f1ee6cb7cbd12 (diff) |
[sanitizer] support recursive rwlocks in bitset-based deadlock detector
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@203779 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 | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/lib/sanitizer_common/sanitizer_deadlock_detector.h b/lib/sanitizer_common/sanitizer_deadlock_detector.h index 68cd1a532..d2f7b5d70 100644 --- a/lib/sanitizer_common/sanitizer_deadlock_detector.h +++ b/lib/sanitizer_common/sanitizer_deadlock_detector.h @@ -40,6 +40,7 @@ class DeadlockDetectorTLS { void clear() { bv_.clear(); epoch_ = 0; + n_recursive_locks = 0; } bool empty() const { return bv_.empty(); } @@ -52,14 +53,30 @@ class DeadlockDetectorTLS { uptr getEpoch() const { return epoch_; } - void addLock(uptr lock_id, uptr current_epoch) { + // Returns true if this is the first (non-recursive) acquisition of this lock. + bool addLock(uptr lock_id, uptr current_epoch) { // Printf("addLock: %zx %zx\n", lock_id, current_epoch); CHECK_EQ(epoch_, current_epoch); - CHECK(bv_.setBit(lock_id)); + if (!bv_.setBit(lock_id)) { + // The lock is already held by this thread, it must be recursive. + CHECK_LT(n_recursive_locks, ARRAY_SIZE(recursive_locks)); + recursive_locks[n_recursive_locks++] = lock_id; + return false; + } + return true; } void removeLock(uptr lock_id) { // Printf("remLock: %zx %zx\n", lock_id, current_epoch); + if (n_recursive_locks) { + for (sptr i = n_recursive_locks - 1; i >= 0; i--) { + if (recursive_locks[i] == lock_id) { + n_recursive_locks--; + Swap(recursive_locks[i], recursive_locks[n_recursive_locks]); + return; + } + } + } CHECK(bv_.clearBit(lock_id)); } @@ -71,6 +88,8 @@ class DeadlockDetectorTLS { private: BV bv_; uptr epoch_; + uptr recursive_locks[64]; + uptr n_recursive_locks; }; // DeadlockDetector. @@ -143,8 +162,7 @@ class DeadlockDetector { uptr cur_idx = nodeToIndex(cur_node); bool is_reachable = g_.isReachable(cur_idx, dtls->getLocks(current_epoch_)); g_.addEdges(dtls->getLocks(current_epoch_), cur_idx); - dtls->addLock(cur_idx, current_epoch_); - return is_reachable; + return dtls->addLock(cur_idx, current_epoch_) && is_reachable; } // Handles the try_lock event, returns false. |