summaryrefslogtreecommitdiff
path: root/lib/tsan/tests
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2014-04-11 15:38:03 +0000
committerDmitry Vyukov <dvyukov@google.com>2014-04-11 15:38:03 +0000
commitfa03a29e8a3d86d528fc81a41dcf2dca113ec55e (patch)
treec45bb9269d8e8da42ae05f20b0440124ef2a7666 /lib/tsan/tests
parent85636ba0636a093fa4e2250e9a2f0ee6c8716827 (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.cc46
-rw-r--r--lib/tsan/tests/unit/tsan_stack_test.cc4
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];