tsan: reduce per-thread memory usage
authorDmitry Vyukov <dvyukov@google.com>
Tue, 22 May 2012 14:34:43 +0000 (14:34 +0000)
committerDmitry Vyukov <dvyukov@google.com>
Tue, 22 May 2012 14:34:43 +0000 (14:34 +0000)
llvm-svn: 157252

compiler-rt/lib/tsan/rtl/tsan_defs.h
compiler-rt/lib/tsan/rtl/tsan_mman.h
compiler-rt/lib/tsan/rtl/tsan_platform_linux.cc
compiler-rt/lib/tsan/rtl/tsan_rtl.cc
compiler-rt/lib/tsan/rtl/tsan_rtl.h
compiler-rt/lib/tsan/rtl/tsan_rtl_report.cc
compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc
compiler-rt/lib/tsan/rtl/tsan_trace.h
compiler-rt/lib/tsan/rtl_tests/tsan_test_util_linux.cc

index e9a801d..2cd205d 100644 (file)
@@ -29,7 +29,7 @@ typedef   signed long long s64;  // NOLINT
 typedef unsigned long uptr;  // NOLINT
 
 const uptr kPageSize = 4096;
-const int kTidBits = 15;
+const int kTidBits = 13;
 const unsigned kMaxTid = 1 << kTidBits;
 const unsigned kMaxTidInClock = kMaxTid * 2;  // This includes msb 'freed' bit.
 const int kClkBits = 40;
index 8b51de6..b0f86c9 100644 (file)
@@ -39,6 +39,7 @@ enum MBlockType {
   MBlockSync,
   MBlockClock,
   MBlockThreadContex,
+  MBlockDeadInfo,
   MBlockRacyStacks,
   MBlockRacyAddresses,
   MBlockAtExit,
index 8bb2b48..7b8be3d 100644 (file)
@@ -241,13 +241,8 @@ void GetThreadStackAndTls(uptr *stk_addr, uptr *stk_size,
   if (*tls_addr > *stk_addr && *tls_addr < *stk_addr + *stk_size) {
     CHECK_GT(*tls_addr + *tls_size, *stk_addr);
     CHECK_LE(*tls_addr + *tls_size, *stk_addr + *stk_size);
-    *stk_size = *tls_addr - *stk_addr;
-    *stk_size = RoundUp(*stk_size, kPageSize);
-    uptr stk_end = *stk_addr + *stk_size;
-    if (stk_end > *tls_addr) {
-      *tls_size -= *tls_addr - stk_end;
-      *tls_addr = stk_end;
-    }
+    *stk_size -= *tls_size;
+    *tls_addr = *stk_addr + *stk_size;
   }
 }
 
index af23edb..05be958 100644 (file)
@@ -76,6 +76,7 @@ ThreadContext::ThreadContext(int tid)
   , reuse_count()
   , epoch0()
   , epoch1()
+  , dead_info()
   , dead_next() {
 }
 
index 9027f85..10f5890 100644 (file)
@@ -207,7 +207,7 @@ class Shadow: public FastState {
 // As if 8-byte write by thread 0xff..f at epoch 0xff..f, races with everything.
 const u64 kShadowFreed = 0xfffffffffffffff8ull;
 
-const int kSigCount = 1024;
+const int kSigCount = 128;
 const int kShadowStackSize = 1024;
 
 struct my_siginfo_t {
@@ -301,8 +301,8 @@ struct ThreadContext {
   u64 epoch0;
   u64 epoch1;
   StackTrace creation_stack;
-  ThreadDeadInfo dead_info;
-  ThreadContextdead_next;  // In dead thread list.
+  ThreadDeadInfo *dead_info;
+  ThreadContext *dead_next;  // In dead thread list.
 
   explicit ThreadContext(int tid);
 };
index 6f6fb9e..d7aad3c 100644 (file)
@@ -175,7 +175,9 @@ static void RestoreStack(int tid, const u64 epoch, StackTrace *stk) {
     trace = &tctx->thr->trace;
   } else if (tctx->status == ThreadStatusFinished
       || tctx->status == ThreadStatusDead) {
-    trace = &tctx->dead_info.trace;
+    if (tctx->dead_info == 0)
+      return;
+    trace = &tctx->dead_info->trace;
   } else {
     return;
   }
index fb44949..c13e6ed 100644 (file)
@@ -20,7 +20,7 @@
 
 namespace __tsan {
 
-const int kThreadQuarantineSize = 100;
+const int kThreadQuarantineSize = 16;
 
 static void MaybeReportThreadLeak(ThreadContext *tctx) {
   if (tctx->detached)
@@ -93,8 +93,7 @@ int ThreadCreate(ThreadState *thr, uptr pc, uptr uid, bool detached) {
     tctx->status = ThreadStatusInvalid;
     tctx->reuse_count++;
     tid = tctx->tid;
-    // The point to reclain dead_info.
-    // delete tctx->dead_info;
+    DestroyAndFree(tctx->dead_info);
   } else {
     StatInc(thr, StatThreadMaxTid);
     tid = ctx->thread_seq++;
@@ -207,13 +206,12 @@ void ThreadFinish(ThreadState *thr) {
   }
 
   // Save from info about the thread.
-  // If dead_info will become dynamically allocated again,
-  // it is the point to allocate it.
-  // tctx->dead_info = new ThreadDeadInfo;
-  internal_memcpy(&tctx->dead_info.trace.events[0],
+  tctx->dead_info = new(internal_alloc(MBlockDeadInfo, sizeof(ThreadDeadInfo)))
+      ThreadDeadInfo();
+  internal_memcpy(&tctx->dead_info->trace.events[0],
       &thr->trace.events[0], sizeof(thr->trace.events));
   for (int i = 0; i < kTraceParts; i++) {
-    tctx->dead_info.trace.headers[i].stack0.CopyFrom(
+    tctx->dead_info->trace.headers[i].stack0.CopyFrom(
         thr->trace.headers[i].stack0);
   }
   tctx->epoch1 = thr->clock.get(tctx->tid);
index 4a1930d..f41a3f3 100644 (file)
@@ -20,7 +20,7 @@
 namespace __tsan {
 
 const int kTraceParts = 8;
-const int kTraceSize = 1024*1024;
+const int kTraceSize = 128*1024;
 const int kTracePartSize = kTraceSize / kTraceParts;
 
 // Must fit into 3 bits.
index 10367ac..0418cfa 100644 (file)
@@ -352,6 +352,7 @@ ScopedThread::ScopedThread(bool detached, bool main) {
     pthread_attr_t attr;
     pthread_attr_init(&attr);
     pthread_attr_setdetachstate(&attr, detached);
+    pthread_attr_setstacksize(&attr, 64*1024);
     pthread_create(&impl_->thread, &attr,
         ScopedThread::Impl::ScopedThreadCallback, impl_);
   }