[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