Skip to content

Commit 180d211

Browse files
committed
tsan: Adding releaseAcquire() to ThreadClock
realeaseAcquire() is a new function added to TSan in support of the Go data-race detector. It's semantics is: void ThreadClock::releaseAcquire(SyncClock *sc) const { for (int i = 0; i < kMaxThreads; i++) { tmp = clock[i]; clock[i] = max(clock[i], sc->clock[i]); sc->clock[i] = tmp; } } For context see: https://go-review.googlesource.com/c/go/+/220419 Reviewed-in: https://reviews.llvm.org/D76322 Author: dfava (Daniel Fava)
1 parent 080d046 commit 180d211

File tree

7 files changed

+69
-0
lines changed

7 files changed

+69
-0
lines changed

compiler-rt/lib/tsan/go/test.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ void __tsan_malloc(void *thr, void *pc, void *p, unsigned long sz);
3232
void __tsan_free(void *p, unsigned long sz);
3333
void __tsan_acquire(void *thr, void *addr);
3434
void __tsan_release(void *thr, void *addr);
35+
void __tsan_release_acquire(void *thr, void *addr);
3536
void __tsan_release_merge(void *thr, void *addr);
3637

3738
void *current_proc;
@@ -77,6 +78,7 @@ int main(void) {
7778
__tsan_func_enter(thr0, (char*)&main + 1);
7879
__tsan_malloc(thr0, (char*)&barfoo + 1, buf, 10);
7980
__tsan_release(thr0, buf);
81+
__tsan_release_acquire(thr0, buf);
8082
__tsan_release_merge(thr0, buf);
8183
void *thr1 = 0;
8284
__tsan_go_start(thr0, &thr1, (char*)&barfoo + 1);

compiler-rt/lib/tsan/go/tsan_go.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,10 @@ void __tsan_acquire(ThreadState *thr, void *addr) {
244244
Acquire(thr, 0, (uptr)addr);
245245
}
246246

247+
void __tsan_release_acquire(ThreadState *thr, void *addr) {
248+
ReleaseStoreAcquire(thr, 0, (uptr)addr);
249+
}
250+
247251
void __tsan_release(ThreadState *thr, void *addr) {
248252
ReleaseStore(thr, 0, (uptr)addr);
249253
}

compiler-rt/lib/tsan/rtl/tsan_clock.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@
3030
// dst->clock[i] = max(dst->clock[i], clock[i]);
3131
// }
3232
//
33+
// void ThreadClock::releaseStoreAcquire(SyncClock *sc) const {
34+
// for (int i = 0; i < kMaxThreads; i++) {
35+
// tmp = clock[i];
36+
// clock[i] = max(clock[i], sc->clock[i]);
37+
// sc->clock[i] = tmp;
38+
// }
39+
// }
40+
//
3341
// void ThreadClock::ReleaseStore(SyncClock *dst) const {
3442
// for (int i = 0; i < kMaxThreads; i++)
3543
// dst->clock[i] = clock[i];
@@ -177,6 +185,36 @@ void ThreadClock::acquire(ClockCache *c, SyncClock *src) {
177185
}
178186
}
179187

188+
void ThreadClock::releaseStoreAcquire(ClockCache *c, SyncClock *sc) {
189+
DCHECK_LE(nclk_, kMaxTid);
190+
DCHECK_LE(dst->size_, kMaxTid);
191+
192+
if (sc->size_ == 0) {
193+
// ReleaseStore will correctly set release_store_tid_,
194+
// which can be important for future operations.
195+
ReleaseStore(c, sc);
196+
return;
197+
}
198+
199+
// Check if we need to resize dst.
200+
if (sc->size_ < nclk_)
201+
sc->Resize(c, nclk_);
202+
203+
sc->Unshare(c);
204+
// Update sc->clk_.
205+
sc->FlushDirty();
206+
uptr i = 0;
207+
for (ClockElem &ce : *sc) {
208+
u64 tmp = clk_[i];
209+
clk_[i] = max(ce.epoch, clk_[i]);
210+
ce.epoch = tmp;
211+
ce.reused = 0;
212+
i++;
213+
}
214+
sc->release_store_tid_ = kInvalidTid;
215+
sc->release_store_reused_ = 0;
216+
}
217+
180218
void ThreadClock::release(ClockCache *c, SyncClock *dst) {
181219
DCHECK_LE(nclk_, kMaxTid);
182220
DCHECK_LE(dst->size_, kMaxTid);

compiler-rt/lib/tsan/rtl/tsan_clock.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ class ThreadClock {
134134
uptr size() const;
135135

136136
void acquire(ClockCache *c, SyncClock *src);
137+
void releaseStoreAcquire(ClockCache *c, SyncClock *src);
137138
void release(ClockCache *c, SyncClock *dst);
138139
void acq_rel(ClockCache *c, SyncClock *dst);
139140
void ReleaseStore(ClockCache *c, SyncClock *dst);

compiler-rt/lib/tsan/rtl/tsan_rtl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,10 +813,12 @@ void Acquire(ThreadState *thr, uptr pc, uptr addr);
813813
// approximation of the actual required synchronization.
814814
void AcquireGlobal(ThreadState *thr, uptr pc);
815815
void Release(ThreadState *thr, uptr pc, uptr addr);
816+
void ReleaseStoreAcquire(ThreadState *thr, uptr pc, uptr addr);
816817
void ReleaseStore(ThreadState *thr, uptr pc, uptr addr);
817818
void AfterSleep(ThreadState *thr, uptr pc);
818819
void AcquireImpl(ThreadState *thr, uptr pc, SyncClock *c);
819820
void ReleaseImpl(ThreadState *thr, uptr pc, SyncClock *c);
821+
void ReleaseStoreAcquireImpl(ThreadState *thr, uptr pc, SyncClock *c);
820822
void ReleaseStoreImpl(ThreadState *thr, uptr pc, SyncClock *c);
821823
void AcquireReleaseImpl(ThreadState *thr, uptr pc, SyncClock *c);
822824

compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,18 @@ void AcquireGlobal(ThreadState *thr, uptr pc) {
429429
UpdateClockCallback, thr);
430430
}
431431

432+
void ReleaseStoreAcquire(ThreadState *thr, uptr pc, uptr addr) {
433+
DPrintf("#%d: ReleaseStoreAcquire %zx\n", thr->tid, addr);
434+
if (thr->ignore_sync)
435+
return;
436+
SyncVar *s = ctx->metamap.GetOrCreateAndLock(thr, pc, addr, true);
437+
thr->fast_state.IncrementEpoch();
438+
// Can't increment epoch w/o writing to the trace as well.
439+
TraceAddEvent(thr, thr->fast_state, EventTypeMop, 0);
440+
ReleaseStoreAcquireImpl(thr, pc, &s->clock);
441+
s->mtx.Unlock();
442+
}
443+
432444
void Release(ThreadState *thr, uptr pc, uptr addr) {
433445
DPrintf("#%d: Release %zx\n", thr->tid, addr);
434446
if (thr->ignore_sync)
@@ -482,6 +494,15 @@ void AcquireImpl(ThreadState *thr, uptr pc, SyncClock *c) {
482494
StatInc(thr, StatSyncAcquire);
483495
}
484496

497+
void ReleaseStoreAcquireImpl(ThreadState *thr, uptr pc, SyncClock *c) {
498+
if (thr->ignore_sync)
499+
return;
500+
thr->clock.set(thr->fast_state.epoch());
501+
thr->fast_synch_epoch = thr->fast_state.epoch();
502+
thr->clock.releaseStoreAcquire(&thr->proc()->clock_cache, c);
503+
StatInc(thr, StatSyncReleaseStoreAcquire);
504+
}
505+
485506
void ReleaseImpl(ThreadState *thr, uptr pc, SyncClock *c) {
486507
if (thr->ignore_sync)
487508
return;

compiler-rt/lib/tsan/rtl/tsan_stat.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ enum StatType {
6868
StatSyncDestroyed,
6969
StatSyncAcquire,
7070
StatSyncRelease,
71+
StatSyncReleaseStoreAcquire,
7172

7273
// Clocks - acquire.
7374
StatClockAcquire,

0 commit comments

Comments
 (0)