summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2017-07-12 12:45:20 +0000
committerDmitry Vyukov <dvyukov@google.com>2017-07-12 12:45:20 +0000
commit6e32365b3ee6d2661034d83a3e80eb2dea6da1a4 (patch)
tree36696fd375b78db37af626b45578fc475332b40d
parent25473b0d43f8e612291b1eff7dde00b51ab4127e (diff)
downloadcompiler-rt-6e32365b3ee6d2661034d83a3e80eb2dea6da1a4.tar.gz
tsan: prepare clock for future changes
Pass ClockCache to ThreadClock::set and introduce ThreadCache::ResetCached. For now both are unused, but will reduce future diffs. git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@307784 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/tsan/rtl/tsan_clock.cc5
-rw-r--r--lib/tsan/rtl/tsan_clock.h3
-rw-r--r--lib/tsan/rtl/tsan_mman.cc2
-rw-r--r--lib/tsan/rtl/tsan_rtl_mutex.cc12
-rw-r--r--lib/tsan/rtl/tsan_rtl_thread.cc4
-rw-r--r--lib/tsan/tests/unit/tsan_clock_test.cc32
6 files changed, 35 insertions, 23 deletions
diff --git a/lib/tsan/rtl/tsan_clock.cc b/lib/tsan/rtl/tsan_clock.cc
index 32435adfd..362921878 100644
--- a/lib/tsan/rtl/tsan_clock.cc
+++ b/lib/tsan/rtl/tsan_clock.cc
@@ -101,6 +101,9 @@ ThreadClock::ThreadClock(unsigned tid, unsigned reused)
clk_[tid_].reused = reused_;
}
+void ThreadClock::ResetCached(ClockCache *c) {
+}
+
void ThreadClock::acquire(ClockCache *c, const SyncClock *src) {
DCHECK_LE(nclk_, kMaxTid);
DCHECK_LE(src->size_, kMaxTid);
@@ -346,7 +349,7 @@ void SyncClock::Resize(ClockCache *c, uptr nclk) {
// Sets a single element in the vector clock.
// This function is called only from weird places like AcquireGlobal.
-void ThreadClock::set(unsigned tid, u64 v) {
+void ThreadClock::set(ClockCache *c, unsigned tid, u64 v) {
DCHECK_LT(tid, kMaxTid);
DCHECK_GE(v, clk_[tid].epoch);
clk_[tid].epoch = v;
diff --git a/lib/tsan/rtl/tsan_clock.h b/lib/tsan/rtl/tsan_clock.h
index 4e352cb81..90eaca28a 100644
--- a/lib/tsan/rtl/tsan_clock.h
+++ b/lib/tsan/rtl/tsan_clock.h
@@ -89,7 +89,7 @@ struct ThreadClock {
return clk_[tid].epoch;
}
- void set(unsigned tid, u64 v);
+ void set(ClockCache *c, unsigned tid, u64 v);
void set(u64 v) {
DCHECK_GE(v, clk_[tid_].epoch);
@@ -108,6 +108,7 @@ struct ThreadClock {
void release(ClockCache *c, SyncClock *dst) const;
void acq_rel(ClockCache *c, SyncClock *dst);
void ReleaseStore(ClockCache *c, SyncClock *dst) const;
+ void ResetCached(ClockCache *c);
void DebugReset();
void DebugDump(int(*printf)(const char *s, ...));
diff --git a/lib/tsan/rtl/tsan_mman.cc b/lib/tsan/rtl/tsan_mman.cc
index 7169d5b02..1434cf688 100644
--- a/lib/tsan/rtl/tsan_mman.cc
+++ b/lib/tsan/rtl/tsan_mman.cc
@@ -294,6 +294,8 @@ uptr __sanitizer_get_allocated_size(const void *p) {
void __tsan_on_thread_idle() {
ThreadState *thr = cur_thread();
+ thr->clock.ResetCached(&thr->proc()->clock_cache);
+ thr->last_sleep_clock.ResetCached(&thr->proc()->clock_cache);
allocator()->SwallowCache(&thr->proc()->alloc_cache);
internal_allocator()->SwallowCache(&thr->proc()->internal_alloc_cache);
ctx->metamap.OnProcIdle(thr->proc());
diff --git a/lib/tsan/rtl/tsan_rtl_mutex.cc b/lib/tsan/rtl/tsan_rtl_mutex.cc
index 54938f37e..2f8581162 100644
--- a/lib/tsan/rtl/tsan_rtl_mutex.cc
+++ b/lib/tsan/rtl/tsan_rtl_mutex.cc
@@ -413,10 +413,10 @@ void Acquire(ThreadState *thr, uptr pc, uptr addr) {
static void UpdateClockCallback(ThreadContextBase *tctx_base, void *arg) {
ThreadState *thr = reinterpret_cast<ThreadState*>(arg);
ThreadContext *tctx = static_cast<ThreadContext*>(tctx_base);
+ u64 epoch = tctx->epoch1;
if (tctx->status == ThreadStatusRunning)
- thr->clock.set(tctx->tid, tctx->thr->fast_state.epoch());
- else
- thr->clock.set(tctx->tid, tctx->epoch1);
+ epoch = tctx->thr->fast_state.epoch();
+ thr->clock.set(&thr->proc()->clock_cache, tctx->tid, epoch);
}
void AcquireGlobal(ThreadState *thr, uptr pc) {
@@ -456,10 +456,10 @@ void ReleaseStore(ThreadState *thr, uptr pc, uptr addr) {
static void UpdateSleepClockCallback(ThreadContextBase *tctx_base, void *arg) {
ThreadState *thr = reinterpret_cast<ThreadState*>(arg);
ThreadContext *tctx = static_cast<ThreadContext*>(tctx_base);
+ u64 epoch = tctx->epoch1;
if (tctx->status == ThreadStatusRunning)
- thr->last_sleep_clock.set(tctx->tid, tctx->thr->fast_state.epoch());
- else
- thr->last_sleep_clock.set(tctx->tid, tctx->epoch1);
+ epoch = tctx->thr->fast_state.epoch();
+ thr->last_sleep_clock.set(&thr->proc()->clock_cache, tctx->tid, epoch);
}
void AfterSleep(ThreadState *thr, uptr pc) {
diff --git a/lib/tsan/rtl/tsan_rtl_thread.cc b/lib/tsan/rtl/tsan_rtl_thread.cc
index 67eebf5d0..83fab082a 100644
--- a/lib/tsan/rtl/tsan_rtl_thread.cc
+++ b/lib/tsan/rtl/tsan_rtl_thread.cc
@@ -142,6 +142,10 @@ void ThreadContext::OnFinished() {
if (common_flags()->detect_deadlocks)
ctx->dd->DestroyLogicalThread(thr->dd_lt);
+ thr->clock.ResetCached(&thr->proc()->clock_cache);
+#if !SANITIZER_GO
+ thr->last_sleep_clock.ResetCached(&thr->proc()->clock_cache);
+#endif
thr->~ThreadState();
#if TSAN_COLLECT_STATS
StatAggregate(ctx->stat, thr->stat);
diff --git a/lib/tsan/tests/unit/tsan_clock_test.cc b/lib/tsan/tests/unit/tsan_clock_test.cc
index 34850faaa..73104dd6b 100644
--- a/lib/tsan/tests/unit/tsan_clock_test.cc
+++ b/lib/tsan/tests/unit/tsan_clock_test.cc
@@ -26,13 +26,13 @@ TEST(Clock, VectorBasic) {
clk.tick();
ASSERT_EQ(clk.size(), 1U);
ASSERT_EQ(clk.get(0), 1U);
- clk.set(3, clk.get(3) + 1);
+ clk.set(&cache, 3, clk.get(3) + 1);
ASSERT_EQ(clk.size(), 4U);
ASSERT_EQ(clk.get(0), 1U);
ASSERT_EQ(clk.get(1), 0U);
ASSERT_EQ(clk.get(2), 0U);
ASSERT_EQ(clk.get(3), 1U);
- clk.set(3, clk.get(3) + 1);
+ clk.set(&cache, 3, clk.get(3) + 1);
ASSERT_EQ(clk.get(3), 2U);
}
@@ -86,24 +86,26 @@ TEST(Clock, RepeatedAcquire) {
TEST(Clock, ManyThreads) {
SyncClock chunked;
- for (unsigned i = 0; i < 100; i++) {
+ for (unsigned i = 0; i < 200; i++) {
ThreadClock vector(0);
vector.tick();
- vector.set(i, 1);
+ vector.set(&cache, i, i + 1);
vector.release(&cache, &chunked);
ASSERT_EQ(i + 1, chunked.size());
vector.acquire(&cache, &chunked);
ASSERT_EQ(i + 1, vector.size());
}
- for (unsigned i = 0; i < 100; i++)
- ASSERT_EQ(1U, chunked.get(i));
+ for (unsigned i = 0; i < 200; i++) {
+ printf("i=%d\n", i);
+ ASSERT_EQ(i + 1, chunked.get(i));
+ }
ThreadClock vector(1);
vector.acquire(&cache, &chunked);
- ASSERT_EQ(100U, vector.size());
- for (unsigned i = 0; i < 100; i++)
- ASSERT_EQ(1U, vector.get(i));
+ ASSERT_EQ(200U, vector.size());
+ for (unsigned i = 0; i < 200; i++)
+ ASSERT_EQ(i + 1, vector.get(i));
chunked.Reset(&cache);
}
@@ -151,7 +153,7 @@ TEST(Clock, Growth) {
{
ThreadClock vector(10);
vector.tick();
- vector.set(5, 42);
+ vector.set(&cache, 5, 42);
SyncClock sync;
vector.release(&cache, &sync);
ASSERT_EQ(sync.size(), 11U);
@@ -180,8 +182,8 @@ TEST(Clock, Growth) {
{
ThreadClock vector(100);
vector.tick();
- vector.set(5, 42);
- vector.set(90, 84);
+ vector.set(&cache, 5, 42);
+ vector.set(&cache, 90, 84);
SyncClock sync;
vector.release(&cache, &sync);
ASSERT_EQ(sync.size(), 101U);
@@ -224,19 +226,19 @@ TEST(Clock, Growth2) {
SyncClock sync;
ThreadClock vector(0);
for (uptr i = 0; i < from; i++)
- vector.set(i, i + 1);
+ vector.set(&cache, i, i + 1);
if (from != 0)
vector.release(&cache, &sync);
ASSERT_EQ(sync.size(), from);
for (uptr i = 0; i < from; i++)
ASSERT_EQ(sync.get(i), i + 1);
for (uptr i = 0; i < to; i++)
- vector.set(i, i + 1);
+ vector.set(&cache, i, i + 1);
vector.release(&cache, &sync);
ASSERT_EQ(sync.size(), to);
for (uptr i = 0; i < to; i++)
ASSERT_EQ(sync.get(i), i + 1);
- vector.set(to + 1, to + 1);
+ vector.set(&cache, to + 1, to + 1);
vector.release(&cache, &sync);
ASSERT_EQ(sync.size(), to + 2);
for (uptr i = 0; i < to; i++)