diff options
author | Dmitry Vyukov <dvyukov@google.com> | 2014-04-11 15:38:03 +0000 |
---|---|---|
committer | Dmitry Vyukov <dvyukov@google.com> | 2014-04-11 15:38:03 +0000 |
commit | fa03a29e8a3d86d528fc81a41dcf2dca113ec55e (patch) | |
tree | c45bb9269d8e8da42ae05f20b0440124ef2a7666 /lib/tsan/tests | |
parent | 85636ba0636a093fa4e2250e9a2f0ee6c8716827 (diff) |
tsan: fix vector clocks
the new optimizations break when thread ids gets reused (clocks go backwards)
add the necessary tests as well
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@206035 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/tsan/tests')
-rw-r--r-- | lib/tsan/tests/unit/tsan_clock_test.cc | 46 | ||||
-rw-r--r-- | lib/tsan/tests/unit/tsan_stack_test.cc | 4 |
2 files changed, 45 insertions, 5 deletions
diff --git a/lib/tsan/tests/unit/tsan_clock_test.cc b/lib/tsan/tests/unit/tsan_clock_test.cc index 127f0efa5..ea36eb3ac 100644 --- a/lib/tsan/tests/unit/tsan_clock_test.cc +++ b/lib/tsan/tests/unit/tsan_clock_test.cc @@ -13,6 +13,7 @@ #include "tsan_clock.h" #include "tsan_rtl.h" #include "gtest/gtest.h" +#include <time.h> namespace __tsan { @@ -63,6 +64,19 @@ TEST(Clock, AcquireRelease) { ASSERT_EQ(vector2.get(100), 1U); } +TEST(Clock, RepeatedAcquire) { + ThreadClock thr1(1); + thr1.tick(); + ThreadClock thr2(2); + thr2.tick(); + + SyncClock sync; + thr1.ReleaseStore(&sync); + + thr2.acquire(&sync); + thr2.acquire(&sync); +} + TEST(Clock, ManyThreads) { SyncClock chunked; for (unsigned i = 0; i < 100; i++) { @@ -130,6 +144,10 @@ struct SimpleSyncClock { uptr size; SimpleSyncClock() { + Reset(); + } + + void Reset() { size = 0; for (uptr i = 0; i < kThreads; i++) clock[i] = 0; @@ -211,9 +229,11 @@ static bool ClockFuzzer(bool printing) { // Create kThreads thread clocks. SimpleThreadClock *thr0[kThreads]; ThreadClock *thr1[kThreads]; + unsigned reused[kThreads]; for (unsigned i = 0; i < kThreads; i++) { + reused[i] = 0; thr0[i] = new SimpleThreadClock(i); - thr1[i] = new ThreadClock(i); + thr1[i] = new ThreadClock(i, reused[i]); } // Create kClocks sync clocks. @@ -232,7 +252,7 @@ static bool ClockFuzzer(bool printing) { thr0[tid]->tick(); thr1[tid]->tick(); - switch (rand() % 4) { + switch (rand() % 6) { case 0: if (printing) printf("acquire thr%d <- clk%d\n", tid, cid); @@ -257,6 +277,24 @@ static bool ClockFuzzer(bool printing) { thr0[tid]->ReleaseStore(sync0[cid]); thr1[tid]->ReleaseStore(sync1[cid]); break; + case 4: + if (printing) + printf("reset clk%d\n", cid); + sync0[cid]->Reset(); + sync1[cid]->Reset(); + break; + case 5: + if (printing) + printf("reset thr%d\n", tid); + u64 epoch = thr0[tid]->clock[tid] + 1; + reused[tid]++; + delete thr0[tid]; + thr0[tid] = new SimpleThreadClock(tid); + thr0[tid]->clock[tid] = epoch; + delete thr1[tid]; + thr1[tid] = new ThreadClock(tid, reused[tid]); + thr1[tid]->set(epoch); + break; } if (printing) { @@ -297,7 +335,9 @@ static bool ClockFuzzer(bool printing) { } TEST(Clock, Fuzzer) { - int seed = time(0); + timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + int seed = ts.tv_sec + ts.tv_nsec; printf("seed=%d\n", seed); srand(seed); if (!ClockFuzzer(false)) { diff --git a/lib/tsan/tests/unit/tsan_stack_test.cc b/lib/tsan/tests/unit/tsan_stack_test.cc index c1dc2fde5..fc4d6c3b4 100644 --- a/lib/tsan/tests/unit/tsan_stack_test.cc +++ b/lib/tsan/tests/unit/tsan_stack_test.cc @@ -18,7 +18,7 @@ namespace __tsan { static void TestStackTrace(StackTrace *trace) { - ThreadState thr(0, 0, 0, 0, 0, 0, 0, 0); + ThreadState thr(0, 0, 0, 0, 0, 0, 0, 0, 0); uptr stack[128]; thr.shadow_stack = &stack[0]; thr.shadow_stack_pos = &stack[0]; @@ -62,7 +62,7 @@ TEST(StackTrace, StaticTrim) { uptr buf[2]; StackTrace trace(buf, 2); - ThreadState thr(0, 0, 0, 0, 0, 0, 0, 0); + ThreadState thr(0, 0, 0, 0, 0, 0, 0, 0, 0); uptr stack[128]; thr.shadow_stack = &stack[0]; thr.shadow_stack_pos = &stack[0]; |