[compiler-rt] r177512 - tsan: move trace header into 0x600000000000 range

Dmitry Vyukov dvyukov at google.com
Wed Mar 20 03:31:54 PDT 2013


Author: dvyukov
Date: Wed Mar 20 05:31:53 2013
New Revision: 177512

URL: http://llvm.org/viewvc/llvm-project?rev=177512&view=rev
Log:
tsan: move trace header into 0x600000000000 range
eliminat thread "dead info" altogether


Modified:
    compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h
    compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h
    compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h?rev=177512&r1=177511&r2=177512&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h Wed Mar 20 05:31:53 2013
@@ -138,7 +138,13 @@ void WriteMemoryProfile(char *buf, uptr
 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;
 }

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc?rev=177512&r1=177511&r2=177512&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc Wed Mar 20 05:31:53 2013
@@ -52,7 +52,9 @@ static char thread_registry_placeholder[
 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, upt
 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,
   // '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"

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h?rev=177512&r1=177511&r2=177512&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h Wed Mar 20 05:31:53 2013
@@ -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 ThreadConte
   // 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,

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc?rev=177512&r1=177511&r2=177512&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc Wed Mar 20 05:31:53 2013
@@ -379,18 +379,11 @@ void RestoreStack(int tid, const u64 epo
       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];

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc?rev=177512&r1=177511&r2=177512&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc Wed Mar 20 05:31:53 2013
@@ -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





More information about the llvm-commits mailing list