forked from OSchip/llvm-project
tsan: more precise handling of finalizers
llvm-svn: 167530
This commit is contained in:
parent
157a515376
commit
e11f2920c9
|
@ -192,7 +192,7 @@ void __tsan_release_merge(int goid, void *addr) {
|
||||||
|
|
||||||
void __tsan_finalizer_goroutine(int goid) {
|
void __tsan_finalizer_goroutine(int goid) {
|
||||||
ThreadState *thr = goroutines[goid];
|
ThreadState *thr = goroutines[goid];
|
||||||
ThreadFinalizerGoroutine(thr);
|
AcquireGlobal(thr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
|
@ -58,7 +58,6 @@ namespace __tsan {
|
||||||
|
|
||||||
ThreadClock::ThreadClock() {
|
ThreadClock::ThreadClock() {
|
||||||
nclk_ = 0;
|
nclk_ = 0;
|
||||||
disabled_ = false;
|
|
||||||
for (uptr i = 0; i < (uptr)kMaxTidInClock; i++)
|
for (uptr i = 0; i < (uptr)kMaxTidInClock; i++)
|
||||||
clk_[i] = 0;
|
clk_[i] = 0;
|
||||||
}
|
}
|
||||||
|
@ -81,8 +80,6 @@ void ThreadClock::release(SyncClock *dst) const {
|
||||||
DCHECK(nclk_ <= kMaxTid);
|
DCHECK(nclk_ <= kMaxTid);
|
||||||
DCHECK(dst->clk_.Size() <= kMaxTid);
|
DCHECK(dst->clk_.Size() <= kMaxTid);
|
||||||
|
|
||||||
if (disabled_)
|
|
||||||
return;
|
|
||||||
if (dst->clk_.Size() < nclk_)
|
if (dst->clk_.Size() < nclk_)
|
||||||
dst->clk_.Resize(nclk_);
|
dst->clk_.Resize(nclk_);
|
||||||
for (uptr i = 0; i < nclk_; i++) {
|
for (uptr i = 0; i < nclk_; i++) {
|
||||||
|
@ -95,8 +92,6 @@ void ThreadClock::ReleaseStore(SyncClock *dst) const {
|
||||||
DCHECK(nclk_ <= kMaxTid);
|
DCHECK(nclk_ <= kMaxTid);
|
||||||
DCHECK(dst->clk_.Size() <= kMaxTid);
|
DCHECK(dst->clk_.Size() <= kMaxTid);
|
||||||
|
|
||||||
if (disabled_)
|
|
||||||
return;
|
|
||||||
if (dst->clk_.Size() < nclk_)
|
if (dst->clk_.Size() < nclk_)
|
||||||
dst->clk_.Resize(nclk_);
|
dst->clk_.Resize(nclk_);
|
||||||
for (uptr i = 0; i < nclk_; i++)
|
for (uptr i = 0; i < nclk_; i++)
|
||||||
|
@ -110,14 +105,6 @@ void ThreadClock::acq_rel(SyncClock *dst) {
|
||||||
release(dst);
|
release(dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThreadClock::Disable(unsigned tid) {
|
|
||||||
disabled_ = true;
|
|
||||||
u64 c0 = clk_[tid];
|
|
||||||
for (uptr i = 0; i < kMaxTidInClock; i++)
|
|
||||||
clk_[i] = (u64)-1;
|
|
||||||
clk_[tid] = c0;
|
|
||||||
}
|
|
||||||
|
|
||||||
SyncClock::SyncClock()
|
SyncClock::SyncClock()
|
||||||
: clk_(MBlockClock) {
|
: clk_(MBlockClock) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ struct ThreadClock {
|
||||||
|
|
||||||
void set(unsigned tid, u64 v) {
|
void set(unsigned tid, u64 v) {
|
||||||
DCHECK_LT(tid, kMaxTid);
|
DCHECK_LT(tid, kMaxTid);
|
||||||
DCHECK(v >= clk_[tid] || disabled_);
|
DCHECK_GE(v, clk_[tid]);
|
||||||
clk_[tid] = v;
|
clk_[tid] = v;
|
||||||
if (nclk_ <= tid)
|
if (nclk_ <= tid)
|
||||||
nclk_ = tid + 1;
|
nclk_ = tid + 1;
|
||||||
|
@ -61,8 +61,6 @@ struct ThreadClock {
|
||||||
nclk_ = tid + 1;
|
nclk_ = tid + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Disable(unsigned tid);
|
|
||||||
|
|
||||||
uptr size() const {
|
uptr size() const {
|
||||||
return nclk_;
|
return nclk_;
|
||||||
}
|
}
|
||||||
|
@ -74,7 +72,6 @@ struct ThreadClock {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uptr nclk_;
|
uptr nclk_;
|
||||||
bool disabled_;
|
|
||||||
u64 clk_[kMaxTidInClock];
|
u64 clk_[kMaxTidInClock];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -497,7 +497,6 @@ int ThreadTid(ThreadState *thr, uptr pc, uptr uid);
|
||||||
void ThreadJoin(ThreadState *thr, uptr pc, int tid);
|
void ThreadJoin(ThreadState *thr, uptr pc, int tid);
|
||||||
void ThreadDetach(ThreadState *thr, uptr pc, int tid);
|
void ThreadDetach(ThreadState *thr, uptr pc, int tid);
|
||||||
void ThreadFinalize(ThreadState *thr);
|
void ThreadFinalize(ThreadState *thr);
|
||||||
void ThreadFinalizerGoroutine(ThreadState *thr);
|
|
||||||
|
|
||||||
void MutexCreate(ThreadState *thr, uptr pc, uptr addr,
|
void MutexCreate(ThreadState *thr, uptr pc, uptr addr,
|
||||||
bool rw, bool recursive, bool linker_init);
|
bool rw, bool recursive, bool linker_init);
|
||||||
|
@ -509,6 +508,7 @@ void MutexReadUnlock(ThreadState *thr, uptr pc, uptr addr);
|
||||||
void MutexReadOrWriteUnlock(ThreadState *thr, uptr pc, uptr addr);
|
void MutexReadOrWriteUnlock(ThreadState *thr, uptr pc, uptr addr);
|
||||||
|
|
||||||
void Acquire(ThreadState *thr, uptr pc, uptr addr);
|
void Acquire(ThreadState *thr, uptr pc, uptr addr);
|
||||||
|
void AcquireGlobal(ThreadState *thr, uptr pc);
|
||||||
void Release(ThreadState *thr, uptr pc, uptr addr);
|
void Release(ThreadState *thr, uptr pc, uptr addr);
|
||||||
void ReleaseStore(ThreadState *thr, uptr pc, uptr addr);
|
void ReleaseStore(ThreadState *thr, uptr pc, uptr addr);
|
||||||
void AfterSleep(ThreadState *thr, uptr pc);
|
void AfterSleep(ThreadState *thr, uptr pc);
|
||||||
|
|
|
@ -231,6 +231,20 @@ void Acquire(ThreadState *thr, uptr pc, uptr addr) {
|
||||||
s->mtx.ReadUnlock();
|
s->mtx.ReadUnlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AcquireGlobal(ThreadState *thr, uptr pc) {
|
||||||
|
Context *ctx = CTX();
|
||||||
|
Lock l(&ctx->thread_mtx);
|
||||||
|
for (unsigned i = 0; i < kMaxTid; i++) {
|
||||||
|
ThreadContext *tctx = ctx->threads[i];
|
||||||
|
if (tctx == 0)
|
||||||
|
continue;
|
||||||
|
if (tctx->status == ThreadStatusRunning)
|
||||||
|
thr->clock.set(i, tctx->thr->fast_state.epoch());
|
||||||
|
else
|
||||||
|
thr->clock.set(i, tctx->epoch1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Release(ThreadState *thr, uptr pc, uptr addr) {
|
void Release(ThreadState *thr, uptr pc, uptr addr) {
|
||||||
CHECK_GT(thr->in_rtl, 0);
|
CHECK_GT(thr->in_rtl, 0);
|
||||||
DPrintf("#%d: Release %zx\n", thr->tid, addr);
|
DPrintf("#%d: Release %zx\n", thr->tid, addr);
|
||||||
|
|
|
@ -303,10 +303,6 @@ void ThreadDetach(ThreadState *thr, uptr pc, int tid) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThreadFinalizerGoroutine(ThreadState *thr) {
|
|
||||||
thr->clock.Disable(thr->tid);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MemoryAccessRange(ThreadState *thr, uptr pc, uptr addr,
|
void MemoryAccessRange(ThreadState *thr, uptr pc, uptr addr,
|
||||||
uptr size, bool is_write) {
|
uptr size, bool is_write) {
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
|
|
Loading…
Reference in New Issue