void __tsan_finalizer_goroutine(int goid) {
ThreadState *thr = goroutines[goid];
- ThreadFinalizerGoroutine(thr);
+ AcquireGlobal(thr, 0);
}
#ifdef _WIN32
ThreadClock::ThreadClock() {
nclk_ = 0;
- disabled_ = false;
for (uptr i = 0; i < (uptr)kMaxTidInClock; i++)
clk_[i] = 0;
}
DCHECK(nclk_ <= kMaxTid);
DCHECK(dst->clk_.Size() <= kMaxTid);
- if (disabled_)
- return;
if (dst->clk_.Size() < nclk_)
dst->clk_.Resize(nclk_);
for (uptr i = 0; i < nclk_; i++) {
DCHECK(nclk_ <= kMaxTid);
DCHECK(dst->clk_.Size() <= kMaxTid);
- if (disabled_)
- return;
if (dst->clk_.Size() < nclk_)
dst->clk_.Resize(nclk_);
for (uptr i = 0; i < nclk_; i++)
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()
: clk_(MBlockClock) {
}
void set(unsigned tid, u64 v) {
DCHECK_LT(tid, kMaxTid);
- DCHECK(v >= clk_[tid] || disabled_);
+ DCHECK_GE(v, clk_[tid]);
clk_[tid] = v;
if (nclk_ <= tid)
nclk_ = tid + 1;
nclk_ = tid + 1;
}
- void Disable(unsigned tid);
-
uptr size() const {
return nclk_;
}
private:
uptr nclk_;
- bool disabled_;
u64 clk_[kMaxTidInClock];
};
void ThreadJoin(ThreadState *thr, uptr pc, int tid);
void ThreadDetach(ThreadState *thr, uptr pc, int tid);
void ThreadFinalize(ThreadState *thr);
-void ThreadFinalizerGoroutine(ThreadState *thr);
void MutexCreate(ThreadState *thr, uptr pc, uptr addr,
bool rw, bool recursive, bool linker_init);
void MutexReadOrWriteUnlock(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 ReleaseStore(ThreadState *thr, uptr pc, uptr addr);
void AfterSleep(ThreadState *thr, uptr pc);
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) {
CHECK_GT(thr->in_rtl, 0);
DPrintf("#%d: Release %zx\n", thr->tid, addr);
}
}
-void ThreadFinalizerGoroutine(ThreadState *thr) {
- thr->clock.Disable(thr->tid);
-}
-
void MemoryAccessRange(ThreadState *thr, uptr pc, uptr addr,
uptr size, bool is_write) {
if (size == 0)