[compiler-rt] 3b222ef - tsan: fixes to ThreadClock::releaseStoreAcquire and tests
Daniel S Fava via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 16 13:54:10 PDT 2020
Author: Daniel S Fava
Date: 2020-04-16T22:53:26+02:00
New Revision: 3b222ef246ef9298e57d00b7c8c1ffd92d0fb44d
URL: https://github.com/llvm/llvm-project/commit/3b222ef246ef9298e57d00b7c8c1ffd92d0fb44d
DIFF: https://github.com/llvm/llvm-project/commit/3b222ef246ef9298e57d00b7c8c1ffd92d0fb44d.diff
LOG: tsan: fixes to ThreadClock::releaseStoreAcquire and tests
Fixes:
1. Setting the number of entries in a thread's clock to max between
the thread and the SyncClock the thread is acquiring from
2. Setting last_acquire_
Unit- and stress-test for releaseStoreAcquire added to
tests/unit/tsan_clock_test.cpp
Added:
Modified:
compiler-rt/lib/tsan/rtl/tsan_clock.cpp
compiler-rt/lib/tsan/tests/unit/tsan_clock_test.cpp
Removed:
################################################################################
diff --git a/compiler-rt/lib/tsan/rtl/tsan_clock.cpp b/compiler-rt/lib/tsan/rtl/tsan_clock.cpp
index 96bbfa1d4cc2..acbcf804194a 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_clock.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_clock.cpp
@@ -196,23 +196,36 @@ void ThreadClock::releaseStoreAcquire(ClockCache *c, SyncClock *sc) {
return;
}
- // Check if we need to resize dst.
+ nclk_ = max(nclk_, (uptr) sc->size_);
+
+ // Check if we need to resize sc.
if (sc->size_ < nclk_)
sc->Resize(c, nclk_);
+ bool acquired = false;
+
sc->Unshare(c);
// Update sc->clk_.
sc->FlushDirty();
uptr i = 0;
for (ClockElem &ce : *sc) {
u64 tmp = clk_[i];
- clk_[i] = max(ce.epoch, clk_[i]);
+ if (clk_[i] < ce.epoch) {
+ clk_[i] = ce.epoch;
+ acquired = true;
+ }
ce.epoch = tmp;
ce.reused = 0;
i++;
}
sc->release_store_tid_ = kInvalidTid;
sc->release_store_reused_ = 0;
+
+ if (acquired) {
+ CPP_STAT_INC(StatClockAcquiredSomething);
+ last_acquire_ = clk_[tid_];
+ ResetCached(c);
+ }
}
void ThreadClock::release(ClockCache *c, SyncClock *dst) {
diff --git a/compiler-rt/lib/tsan/tests/unit/tsan_clock_test.cpp b/compiler-rt/lib/tsan/tests/unit/tsan_clock_test.cpp
index 6d835ba85c3b..cdaaf30b1b20 100644
--- a/compiler-rt/lib/tsan/tests/unit/tsan_clock_test.cpp
+++ b/compiler-rt/lib/tsan/tests/unit/tsan_clock_test.cpp
@@ -108,6 +108,31 @@ TEST(Clock, RepeatedAcquire) {
sync.Reset(&cache);
}
+TEST(Clock, releaseStoreAcquire) {
+ ThreadClock thr0(0);
+ thr0.tick();
+ ThreadClock thr1(1);
+ thr1.tick();
+ SyncClock syncA;
+ SyncClock syncB;
+ ASSERT_EQ(syncA.size(), 0U);
+ ASSERT_EQ(syncB.size(), 0U);
+ thr1.releaseStoreAcquire(&cache, &syncB);
+ ASSERT_EQ(syncB.size(), 2U); // T0 and T1
+ // releaseStoreAcquire to an empty SyncClock
+ thr0.releaseStoreAcquire(&cache, &syncA);
+ ASSERT_EQ(syncA.size(), 1U);
+ // releaseStoreAcquire from a non-empty SyncClock
+ // T0 learns about T1
+ thr0.releaseStoreAcquire(&cache, &syncB);
+ // releaseStoreAcquire to the originally empty SyncClock
+ // T0 deposits info about T1 into syncA
+ thr0.releaseStoreAcquire(&cache, &syncA);
+ ASSERT_EQ(syncA.size(), 2U);
+ syncA.Reset(&cache);
+ syncB.Reset(&cache);
+}
+
TEST(Clock, ManyThreads) {
SyncClock chunked;
for (unsigned i = 0; i < 200; i++) {
@@ -336,6 +361,18 @@ struct SimpleThreadClock {
dst->clock[i] = max(dst->clock[i], clock[i]);
}
+ void releaseStoreAcquire(SimpleSyncClock *sc) {
+ if (sc->size < size)
+ sc->size = size;
+ else
+ size = sc->size;
+ for (uptr i = 0; i < kThreads; i++) {
+ uptr tmp = clock[i];
+ clock[i] = max(sc->clock[i], clock[i]);
+ sc->clock[i] = tmp;
+ }
+ }
+
void acq_rel(SimpleSyncClock *dst) {
acquire(dst);
release(dst);
@@ -390,7 +427,7 @@ static bool ClockFuzzer(bool printing) {
thr0[tid]->tick();
thr1[tid]->tick();
- switch (rand() % 6) {
+ switch (rand() % 7) {
case 0:
if (printing)
printf("acquire thr%d <- clk%d\n", tid, cid);
@@ -422,6 +459,12 @@ static bool ClockFuzzer(bool printing) {
sync1[cid]->Reset(&cache);
break;
case 5:
+ if (printing)
+ printf("releaseStoreAcquire thr%d -> clk%d\n", tid, cid);
+ thr0[tid]->releaseStoreAcquire(sync0[cid]);
+ thr1[tid]->releaseStoreAcquire(&cache, sync1[cid]);
+ break;
+ case 6:
if (printing)
printf("reset thr%d\n", tid);
u64 epoch = thr0[tid]->clock[tid] + 1;
More information about the llvm-commits
mailing list