mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-09 17:43:57 +00:00
[sanitizer] partially implement racy fast path in bitset-based deadlock detector
llvm-svn: 203904
This commit is contained in:
parent
39aa6af23f
commit
61a0f1c564
@ -60,6 +60,20 @@ class BVGraph {
|
||||
return res;
|
||||
}
|
||||
|
||||
// *EXPERIMENTAL*
|
||||
// Returns true if all edges from=>to exist.
|
||||
// This function does not use any global state except for 'this' itself,
|
||||
// and thus can be called from different threads w/o locking.
|
||||
// This would be racy.
|
||||
// FIXME: investigate how much we can prove about this race being "benign".
|
||||
bool hasAllEdges(const BV &from, uptr to) {
|
||||
for (typename BV::Iterator it(from); it.hasNext(); ) {
|
||||
uptr idx = it.next();
|
||||
if (!v[idx].getBit(to)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns true if the edge from=>to was removed.
|
||||
bool removeEdge(uptr from, uptr to) {
|
||||
return v[from].clearBit(to);
|
||||
|
@ -172,6 +172,16 @@ class DeadlockDetector {
|
||||
dtls->addLock(cur_idx, current_epoch_);
|
||||
}
|
||||
|
||||
// Experimental *racy* fast path function.
|
||||
// Returns true if all edges from the currently held locks to cur_node exist.
|
||||
bool hasAllEdges(DeadlockDetectorTLS<BV> *dtls, uptr cur_node) {
|
||||
if (dtls->getEpoch() == nodeToEpoch(cur_node)) {
|
||||
uptr cur_idx = nodeToIndexUnchecked(cur_node);
|
||||
return g_.hasAllEdges(dtls->getLocks(current_epoch_), cur_idx);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Adds edges from currently held locks to cur_node,
|
||||
// returns the number of added edges, and puts the sources of added edges
|
||||
// into added_edges[].
|
||||
|
@ -100,6 +100,7 @@ void DD::MutexBeforeLock(DDCallback *cb,
|
||||
DDMutex *m, bool wlock) {
|
||||
DDLogicalThread *lt = cb->lt;
|
||||
if (lt->dd.empty()) return; // This will be the first lock held by lt.
|
||||
if (dd.hasAllEdges(<->dd, m->id)) return; // We already have all edges.
|
||||
SpinMutexLock lk(&mtx);
|
||||
MutexEnsureID(lt, m);
|
||||
if (dd.isHeld(<->dd, m->id))
|
||||
@ -131,6 +132,7 @@ void DD::MutexAfterLock(DDCallback *cb, DDMutex *m, bool wlock, bool trylock) {
|
||||
// Printf("T%p MutexLock: %zx\n", lt, m->id);
|
||||
if (dd.onFirstLock(<->dd, m->id))
|
||||
return;
|
||||
// if (dd.hasAllEdges(<->dd, m->id)) return;
|
||||
SpinMutexLock lk(&mtx);
|
||||
MutexEnsureID(lt, m);
|
||||
if (wlock) // Only a recursive rlock may be held.
|
||||
|
@ -320,10 +320,14 @@ void RunAddEdgesTest() {
|
||||
from.clear();
|
||||
from.setBit(1);
|
||||
EXPECT_EQ(1U, g.addEdges(from, 4, added_edges, kMaxEdges));
|
||||
EXPECT_TRUE(g.hasAllEdges(from, 4));
|
||||
EXPECT_FALSE(g.hasAllEdges(from, 5));
|
||||
EXPECT_EQ(1U, added_edges[0]);
|
||||
from.setBit(2);
|
||||
from.setBit(3);
|
||||
EXPECT_FALSE(g.hasAllEdges(from, 4));
|
||||
EXPECT_EQ(2U, g.addEdges(from, 4, added_edges, kMaxEdges));
|
||||
EXPECT_TRUE(g.hasAllEdges(from, 4));
|
||||
EXPECT_EQ(2U, added_edges[0]);
|
||||
EXPECT_EQ(3U, added_edges[1]);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user