[compiler-rt] r201306 - [sanitizer] findPath for deadlock detector

Kostya Serebryany kcc at google.com
Thu Feb 13 01:52:16 PST 2014


Author: kcc
Date: Thu Feb 13 03:52:15 2014
New Revision: 201306

URL: http://llvm.org/viewvc/llvm-project?rev=201306&view=rev
Log:
[sanitizer] findPath for deadlock detector

Modified:
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_bitvector.h
    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_bvgraph_test.cc

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_bitvector.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_bitvector.h?rev=201306&r1=201305&r2=201306&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_bitvector.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_bitvector.h Thu Feb 13 03:52:15 2014
@@ -56,6 +56,8 @@ class BasicBitVector {
     return bits_ != old;
   }
 
+  void copyFrom(const BasicBitVector &v) { bits_ = v.bits_; }
+
   // Returns true if 'this' intersects with 'v'.
   bool intersectsWith(const BasicBitVector &v) const { return bits_ & v.bits_; }
 
@@ -165,6 +167,11 @@ class TwoLevelBitVector {
     return res;
   }
 
+  void copyFrom(const TwoLevelBitVector &v) {
+    clear();
+    setUnion(v);
+  }
+
   // Returns true if 'this' intersects with 'v'.
   bool intersectsWith(const TwoLevelBitVector &v) const {
     for (uptr i0 = 0; i0 < kLevel1Size; i0++) {

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=201306&r1=201305&r2=201306&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_bvgraph.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_bvgraph.h Thu Feb 13 03:52:15 2014
@@ -47,8 +47,7 @@ class BVGraph {
   // to any of the nodes in 'targets'.
   bool isReachable(uptr from, const BV &targets) {
     BV to_visit, visited;
-    to_visit.clear();
-    to_visit.setUnion(v[from]);
+    to_visit.copyFrom(v[from]);
     visited.clear();
     visited.setBit(from);
     while (!to_visit.empty()) {
@@ -59,6 +58,25 @@ class BVGraph {
     return targets.intersectsWith(visited);
   }
 
+  // Finds a path from 'from' to one of the nodes in 'target',
+  // stores up to 'path_size' items of the path into 'path',
+  // returns the path length, or 0 if there is no path of size 'path_size'.
+  uptr findPath(uptr from, const BV &targets, uptr *path, uptr path_size) {
+    if (path_size == 0)
+      return 0;
+    path[0] = from;
+    if (targets.getBit(from))
+      return 1;
+    BV t;
+    t.copyFrom(v[from]);
+    while (!t.empty()) {
+      uptr idx = t.getAndClearFirstOne();
+      if (uptr res = findPath(idx, targets, path + 1, path_size - 1))
+        return res + 1;
+    }
+    return 0;
+  }
+
  private:
   void check(uptr idx) const { CHECK_LE(idx, size()); }
   BV v[kSize];

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=201306&r1=201305&r2=201306&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_deadlock_detector.h Thu Feb 13 03:52:15 2014
@@ -59,6 +59,8 @@ class DeadlockDetectorTLS {
 // DeadlockDetector.
 // For deadlock detection to work we need one global DeadlockDetector object
 // and one DeadlockDetectorTLS object per evey thread.
+// This class is not thread safe, all concurrent accesses should be guarded
+// by an external lock.
 template <class BV>
 class DeadlockDetector {
  public:

Modified: compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_bvgraph_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_bvgraph_test.cc?rev=201306&r1=201305&r2=201306&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_bvgraph_test.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/tests/sanitizer_bvgraph_test.cc Thu Feb 13 03:52:15 2014
@@ -61,7 +61,16 @@ TEST(SanitizerCommon, BVGraph) {
       from = my_rand() % g.size();
       bool is_reachable = g.isReachable(from, target);
       if (is_reachable) {
-        // printf("reachable: %d %zd\n", it, from);
+        uptr path[BV::kSize];
+        uptr len;
+        for (len = 1; len < BV::kSize; len++) {
+          if (g.findPath(from, target, path, len) == len)
+            break;
+        }
+        EXPECT_LT(len, BV::kSize);
+        EXPECT_TRUE(target.getBit(path[len - 1]));
+        // fprintf(stderr, "reachable: %zd; path %zd {%zd %zd %zd}\n",
+        //        from, len, path[0], path[1], path[2]);
         num_reachable++;
       }
     }
@@ -71,6 +80,7 @@ TEST(SanitizerCommon, BVGraph) {
 
 TEST(SanitizerCommon, BVGraph_isReachable) {
   typedef TwoLevelBitVector<> BV;
+  uptr path[5];
   BVGraph<BV> g;
   g.clear();
   BV target;
@@ -103,6 +113,13 @@ TEST(SanitizerCommon, BVGraph_isReachabl
   EXPECT_TRUE(g.isReachable(f1, target));
   EXPECT_FALSE(g.isReachable(f2, target));
   EXPECT_FALSE(g.isReachable(f3, target));
+  EXPECT_EQ(g.findPath(f0, target, path, ARRAY_SIZE(path)), 3U);
+  EXPECT_EQ(path[0], f0);
+  EXPECT_EQ(path[1], f1);
+  EXPECT_EQ(path[2], t0);
+  EXPECT_EQ(g.findPath(f1, target, path, ARRAY_SIZE(path)), 2U);
+  EXPECT_EQ(path[0], f1);
+  EXPECT_EQ(path[1], t0);
 
   g.addEdge(f3, t1);
   EXPECT_TRUE(g.isReachable(f0, target));





More information about the llvm-commits mailing list