tsan: more precise handling of finalizers

llvm-svn: 167530
This commit is contained in:
Dmitry Vyukov 2012-11-07 15:08:20 +00:00
parent 157a515376
commit e11f2920c9
6 changed files with 17 additions and 23 deletions

View File

@ -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

View File

@ -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) {
} }

View File

@ -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];
}; };

View File

@ -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);

View File

@ -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);

View File

@ -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)