[compiler-rt] r201505 - [sanitizer] simplify DeadlockDetectorTLS
Kostya Serebryany
kcc at google.com
Mon Feb 17 00:47:48 PST 2014
Author: kcc
Date: Mon Feb 17 02:47:48 2014
New Revision: 201505
URL: http://llvm.org/viewvc/llvm-project?rev=201505&view=rev
Log:
[sanitizer] simplify DeadlockDetectorTLS
Modified:
compiler-rt/trunk/lib/sanitizer_common/sanitizer_bvgraph.h
compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector.h
compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_deadlock_detector_test.cc
compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h
compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_bvgraph.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_bvgraph.h?rev=201505&r1=201504&r2=201505&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_bvgraph.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_bvgraph.h Mon Feb 17 02:47:48 2014
@@ -39,6 +39,16 @@ class BVGraph {
return v[from].setBit(to);
}
+ // Returns true if at least one new edge was added.
+ bool addEdges(const BV &from, uptr to) {
+ bool res = false;
+ t1.copyFrom(from);
+ while (!t1.empty())
+ if (v[t1.getAndClearFirstOne()].setBit(to))
+ res = true;
+ return res;
+ }
+
bool hasEdge(uptr from, uptr to) const {
check(from, to);
return v[from].getBit(to);
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=201505&r1=201504&r2=201505&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector.h Mon Feb 17 02:47:48 2014
@@ -26,38 +26,36 @@ namespace __sanitizer {
// Thread-local state for DeadlockDetector.
// It contains the locks currently held by the owning thread.
+template <class BV>
class DeadlockDetectorTLS {
public:
// No CTOR.
- void clear() { n_locks_ = 0; }
-
- void addLock(uptr node) {
- CHECK_LT(n_locks_, ARRAY_SIZE(locks_));
- locks_[n_locks_++] = node;
+ void clear() {
+ bv_.clear();
+ epoch_ = 0;
}
- void removeLock(uptr node) {
- CHECK_NE(n_locks_, 0U);
- for (sptr i = n_locks_ - 1; i >= 0; i--) {
- if (locks_[i] == node) {
- locks_[i] = locks_[n_locks_ - 1];
- n_locks_--;
- return;
- }
+ void addLock(uptr lock_id, uptr current_epoch) {
+ if (current_epoch != epoch_) {
+ bv_.clear();
+ epoch_ = current_epoch;
}
- CHECK(0);
+ bv_.setBit(lock_id);
}
- uptr numLocks() const { return n_locks_; }
-
- uptr getLock(uptr idx) const {
- CHECK_LT(idx, n_locks_);
- return locks_[idx];
+ void removeLock(uptr lock_id, uptr current_epoch) {
+ if (current_epoch != epoch_) {
+ bv_.clear();
+ epoch_ = current_epoch;
+ }
+ bv_.clearBit(lock_id);
}
+ const BV &getLocks() const { return bv_; }
+
private:
- uptr n_locks_;
- uptr locks_[64];
+ BV bv_;
+ uptr epoch_;
};
// DeadlockDetector.
@@ -115,24 +113,17 @@ class DeadlockDetector {
// Handle the lock event, return true if there is a cycle.
// FIXME: handle RW locks, recusive locks, etc.
- bool onLock(DeadlockDetectorTLS *dtls, uptr cur_node) {
- BV &cur_locks = t1;
- cur_locks.clear();
+ bool onLock(DeadlockDetectorTLS<BV> *dtls, uptr cur_node) {
uptr cur_idx = nodeToIndex(cur_node);
- for (uptr i = 0, n = dtls->numLocks(); i < n; i++) {
- uptr prev_node = dtls->getLock(i);
- uptr prev_idx = nodeToIndex(prev_node);
- g_.addEdge(prev_idx, cur_idx);
- cur_locks.setBit(prev_idx);
- // Printf("OnLock %zx; prev %zx\n", cur_node, dtls->getLock(i));
- }
- dtls->addLock(cur_node);
- return g_.isReachable(cur_idx, cur_locks);
+ bool is_reachable = g_.isReachable(cur_idx, dtls->getLocks());
+ dtls->addLock(cur_idx, current_epoch_);
+ g_.addEdges(dtls->getLocks(), cur_idx);
+ return is_reachable;
}
// Handle the unlock event.
- void onUnlock(DeadlockDetectorTLS *dtls, uptr node) {
- dtls->removeLock(node);
+ void onUnlock(DeadlockDetectorTLS<BV> *dtls, uptr node) {
+ dtls->removeLock(nodeToIndex(node), current_epoch_);
}
private:
@@ -143,12 +134,12 @@ class DeadlockDetector {
CHECK_EQ(current_epoch_, node / size() * size());
}
- uptr indexToNode(uptr idx) {
+ uptr indexToNode(uptr idx) const {
check_idx(idx);
return idx + current_epoch_;
}
- uptr nodeToIndex(uptr node) {
+ uptr nodeToIndex(uptr node) const {
check_node(node);
return node % size();
}
@@ -164,7 +155,6 @@ class DeadlockDetector {
BV recycled_nodes_;
BVGraph<BV> g_;
uptr data_[BV::kSize];
- BV t1; // Temporary object which we can not keep on stack.
};
} // namespace __sanitizer
Modified: compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_deadlock_detector_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_deadlock_detector_test.cc?rev=201505&r1=201504&r2=201505&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_deadlock_detector_test.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_deadlock_detector_test.cc Mon Feb 17 02:47:48 2014
@@ -36,7 +36,7 @@ template <class BV>
void BasicTest() {
ScopedDD<BV> sdd;
DeadlockDetector<BV> &d = *sdd.dp;
- DeadlockDetectorTLS dtls;
+ DeadlockDetectorTLS<BV> dtls;
d.clear();
set<uptr> s;
for (size_t i = 0; i < d.size() * 3; i++) {
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h?rev=201505&r1=201504&r2=201505&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h Mon Feb 17 02:47:48 2014
@@ -390,6 +390,8 @@ class Shadow : public FastState {
struct SignalContext;
+typedef TwoLevelBitVector<> DDBV; // DeadlockDetector's bit vector.
+
struct JmpBuf {
uptr sp;
uptr mangled_sp;
@@ -451,7 +453,7 @@ struct ThreadState {
ThreadContext *tctx;
InternalDeadlockDetector internal_deadlock_detector;
- __sanitizer::DeadlockDetectorTLS deadlock_detector_tls;
+ __sanitizer::DeadlockDetectorTLS<DDBV> deadlock_detector_tls;
bool in_signal_handler;
SignalContext *signal_ctx;
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc?rev=201505&r1=201504&r2=201505&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_mutex.cc Mon Feb 17 02:47:48 2014
@@ -22,7 +22,7 @@
namespace __tsan {
-static __sanitizer::DeadlockDetector<TwoLevelBitVector<> > g_deadlock_detector;
+static __sanitizer::DeadlockDetector<DDBV> g_deadlock_detector;
static void EnsureDeadlockDetectorID(ThreadState *thr, SyncVar *s) {
if (!s->deadlock_detector_id)
More information about the llvm-commits
mailing list