[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