summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2013-03-20 10:31:53 +0000
committerDmitry Vyukov <dvyukov@google.com>2013-03-20 10:31:53 +0000
commit9743d74426ae43898e4da55e591b09be18f8aa6e (patch)
tree130f7c74264c817a904a10c089847143b65ebe4a
parent6d6ab9eeea4a99370d7ab18ce80eb96091e2cf3f (diff)
downloadcompiler-rt-9743d74426ae43898e4da55e591b09be18f8aa6e.tar.gz
compiler-rt-9743d74426ae43898e4da55e591b09be18f8aa6e.tar.bz2
compiler-rt-9743d74426ae43898e4da55e591b09be18f8aa6e.tar.xz
tsan: move trace header into 0x600000000000 range
eliminat thread "dead info" altogether git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@177512 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/tsan/rtl/tsan_platform.h8
-rw-r--r--lib/tsan/rtl/tsan_rtl.cc23
-rw-r--r--lib/tsan/rtl/tsan_rtl.h10
-rw-r--r--lib/tsan/rtl/tsan_rtl_report.cc15
-rw-r--r--lib/tsan/rtl/tsan_rtl_thread.cc19
5 files changed, 39 insertions, 36 deletions
diff --git a/lib/tsan/rtl/tsan_platform.h b/lib/tsan/rtl/tsan_platform.h
index 2a075992..15b4d107 100644
--- a/lib/tsan/rtl/tsan_platform.h
+++ b/lib/tsan/rtl/tsan_platform.h
@@ -138,7 +138,13 @@ void WriteMemoryProfile(char *buf, uptr buf_size);
const char *InitializePlatform();
void FinalizePlatform();
uptr ALWAYS_INLINE INLINE GetThreadTrace(int tid) {
- uptr p = kTraceMemBegin + (uptr)tid * kTraceSize * sizeof(Event);
+ uptr p = kTraceMemBegin + (uptr)(tid * 2) * kTraceSize * sizeof(Event);
+ DCHECK_LT(p, kTraceMemBegin + kTraceMemSize);
+ return p;
+}
+
+uptr ALWAYS_INLINE INLINE GetThreadTraceHeader(int tid) {
+ uptr p = kTraceMemBegin + (uptr)(tid * 2 + 1) * kTraceSize * sizeof(Event);
DCHECK_LT(p, kTraceMemBegin + kTraceMemSize);
return p;
}
diff --git a/lib/tsan/rtl/tsan_rtl.cc b/lib/tsan/rtl/tsan_rtl.cc
index 37f65eb6..6efb2877 100644
--- a/lib/tsan/rtl/tsan_rtl.cc
+++ b/lib/tsan/rtl/tsan_rtl.cc
@@ -52,7 +52,9 @@ static char thread_registry_placeholder[sizeof(ThreadRegistry)];
static ThreadContextBase *CreateThreadContext(u32 tid) {
// Map thread trace when context is created.
MapThreadTrace(GetThreadTrace(tid), TraceSize() * sizeof(Event));
- void *mem = MmapOrDie(sizeof(ThreadContext), "ThreadContext");
+ MapThreadTrace(GetThreadTraceHeader(tid), sizeof(Trace));
+ new(ThreadTrace(tid)) Trace();
+ void *mem = internal_alloc(MBlockThreadContex, sizeof(ThreadContext));
return new(mem) ThreadContext(tid);
}
@@ -285,15 +287,20 @@ u32 CurrentStackId(ThreadState *thr, uptr pc) {
void TraceSwitch(ThreadState *thr) {
thr->nomalloc++;
ScopedInRtl in_rtl;
- Lock l(&thr->trace.mtx);
+ Trace *thr_trace = ThreadTrace(thr->tid);
+ Lock l(&thr_trace->mtx);
unsigned trace = (thr->fast_state.epoch() / kTracePartSize) % TraceParts();
- TraceHeader *hdr = &thr->trace.headers[trace];
+ TraceHeader *hdr = &thr_trace->headers[trace];
hdr->epoch0 = thr->fast_state.epoch();
hdr->stack0.ObtainCurrent(thr, 0);
hdr->mset0 = thr->mset;
thr->nomalloc--;
}
+Trace *ThreadTrace(int tid) {
+ return (Trace*)GetThreadTraceHeader(tid);
+}
+
uptr TraceTopPC(ThreadState *thr) {
Event *events = (Event*)GetThreadTrace(thr->tid);
uptr pc = events[thr->fast_state.GetTracePos()];
@@ -377,7 +384,15 @@ void MemoryAccessImpl(ThreadState *thr, uptr addr,
// 'candidates' with 'same' or 'replace', but I think
// it's just not worth it (performance- and complexity-wise).
- Shadow old(0);
+ Shadow old(LoadShadow(shadow_mem));
+Printf("MOP %p -> %p %llu\n", addr, shadow_mem, old.raw());
+ if (old.raw() == kShadowRodata) {
+ // Access to .rodata section, no races here.
+ // Measurements show that it can be 10-20% of all memory accesses.
+ StatInc(thr, StatMopRodata);
+ return;
+ }
+
if (kShadowCnt == 1) {
int idx = 0;
#include "tsan_update_shadow_word_inl.h"
diff --git a/lib/tsan/rtl/tsan_rtl.h b/lib/tsan/rtl/tsan_rtl.h
index 19929def..2b9aaf4e 100644
--- a/lib/tsan/rtl/tsan_rtl.h
+++ b/lib/tsan/rtl/tsan_rtl.h
@@ -137,6 +137,8 @@ Allocator *allocator();
void TsanCheckFailed(const char *file, int line, const char *cond,
u64 v1, u64 v2);
+const u64 kShadowRodata = (u64)-1; // .rodata shadow marker
+
// FastState (from most significant bit):
// ignore : 1
// tid : kTidBits
@@ -404,7 +406,6 @@ struct ThreadState {
uptr *shadow_stack_pos;
u64 *racy_shadow_addr;
u64 racy_state[2];
- Trace trace;
#ifndef TSAN_GO
// C/C++ uses embed shadow stack of fixed size.
uptr shadow_stack[kShadowStackSize];
@@ -458,11 +459,6 @@ INLINE ThreadState *cur_thread() {
}
#endif
-// An info about a thread that is hold for some time after its termination.
-struct ThreadDeadInfo {
- Trace trace;
-};
-
class ThreadContext : public ThreadContextBase {
public:
explicit ThreadContext(int tid);
@@ -479,7 +475,6 @@ class ThreadContext : public ThreadContextBase {
// the event is from a dead thread that shared tid with this thread.
u64 epoch0;
u64 epoch1;
- ThreadDeadInfo *dead_info;
// Override superclass callbacks.
void OnDead();
@@ -719,6 +714,7 @@ void TraceSwitch(ThreadState *thr);
uptr TraceTopPC(ThreadState *thr);
uptr TraceSize();
uptr TraceParts();
+Trace *ThreadTrace(int tid);
extern "C" void __tsan_trace_switch();
void ALWAYS_INLINE INLINE TraceAddEvent(ThreadState *thr, FastState fs,
diff --git a/lib/tsan/rtl/tsan_rtl_report.cc b/lib/tsan/rtl/tsan_rtl_report.cc
index 2df42346..b343ff3d 100644
--- a/lib/tsan/rtl/tsan_rtl_report.cc
+++ b/lib/tsan/rtl/tsan_rtl_report.cc
@@ -379,18 +379,11 @@ void RestoreStack(int tid, const u64 epoch, StackTrace *stk, MutexSet *mset) {
ctx->thread_registry->GetThreadLocked(tid));
if (tctx == 0)
return;
- Trace* trace = 0;
- if (tctx->status == ThreadStatusRunning) {
- CHECK(tctx->thr);
- trace = &tctx->thr->trace;
- } else if (tctx->status == ThreadStatusFinished
- || tctx->status == ThreadStatusDead) {
- if (tctx->dead_info == 0)
- return;
- trace = &tctx->dead_info->trace;
- } else {
+ if (tctx->status != ThreadStatusRunning
+ && tctx->status != ThreadStatusFinished
+ && tctx->status != ThreadStatusDead)
return;
- }
+ Trace* trace = ThreadTrace(tctx->tid);
Lock l(&trace->mtx);
const int partidx = (epoch / kTracePartSize) % TraceParts();
TraceHeader* hdr = &trace->headers[partidx];
diff --git a/lib/tsan/rtl/tsan_rtl_thread.cc b/lib/tsan/rtl/tsan_rtl_thread.cc
index 476b670b..3be9b83c 100644
--- a/lib/tsan/rtl/tsan_rtl_thread.cc
+++ b/lib/tsan/rtl/tsan_rtl_thread.cc
@@ -27,8 +27,7 @@ ThreadContext::ThreadContext(int tid)
, thr()
, sync()
, epoch0()
- , epoch1()
- , dead_info() {
+ , epoch1() {
}
#ifndef TSAN_GO
@@ -75,8 +74,8 @@ void ThreadContext::OnCreated(void *arg) {
void ThreadContext::OnReset() {
sync.Reset();
- if (dead_info)
- DestroyAndFree(dead_info);
+ FlushUnneededShadowMemory(GetThreadTrace(tid), TraceSize() * sizeof(Event));
+ //!!! FlushUnneededShadowMemory(GetThreadTraceHeader(tid), sizeof(Trace));
}
struct OnStartedArgs {
@@ -113,8 +112,10 @@ void ThreadContext::OnStarted(void *arg) {
thr->clock.acquire(&sync);
thr->fast_state.SetHistorySize(flags()->history_size);
const uptr trace = (epoch0 / kTracePartSize) % TraceParts();
- thr->trace.headers[trace].epoch0 = epoch0;
+ Trace *thr_trace = ThreadTrace(thr->tid);
+ thr_trace->headers[trace].epoch0 = epoch0;
StatInc(thr, StatSyncAcquire);
+ sync.Reset();
DPrintf("#%d: ThreadStart epoch=%zu stk_addr=%zx stk_size=%zx "
"tls_addr=%zx tls_size=%zx\n",
tid, (uptr)epoch0, args->stk_addr, args->stk_size,
@@ -132,14 +133,6 @@ void ThreadContext::OnFinished() {
thr->clock.release(&sync);
StatInc(thr, StatSyncRelease);
}
- // Save from info about the thread.
- dead_info = new(internal_alloc(MBlockDeadInfo, sizeof(ThreadDeadInfo)))
- ThreadDeadInfo();
- for (uptr i = 0; i < TraceParts(); i++) {
- dead_info->trace.headers[i].epoch0 = thr->trace.headers[i].epoch0;
- dead_info->trace.headers[i].stack0.CopyFrom(
- thr->trace.headers[i].stack0);
- }
epoch1 = thr->fast_state.epoch();
#ifndef TSAN_GO