[compiler-rt] r177627 - tsan: use a single background thread for memory profiler and memory flush (and later for symbolizer flush)

Dmitry Vyukov dvyukov at google.com
Wed Mar 20 23:24:31 PDT 2013


Author: dvyukov
Date: Thu Mar 21 01:24:31 2013
New Revision: 177627

URL: http://llvm.org/viewvc/llvm-project?rev=177627&view=rev
Log:
tsan: use a single background thread for memory profiler and memory flush (and later for symbolizer flush)


Modified:
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h?rev=177627&r1=177626&r2=177627&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h Thu Mar 21 01:24:31 2013
@@ -140,6 +140,7 @@ uptr GetTlsSize();
 // Other
 void SleepForSeconds(int seconds);
 void SleepForMillis(int millis);
+u64 NanoTime();
 int Atexit(void (*function)(void));
 void SortArray(uptr *array, uptr size);
 

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc?rev=177627&r1=177626&r2=177627&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc Thu Mar 21 01:24:31 2013
@@ -44,6 +44,12 @@
 #include <sys/signal.h>
 #endif
 
+// <linux/time.h>
+struct kernel_timeval {
+  long tv_sec;
+  long tv_usec;
+};
+
 // <linux/futex.h> is broken on some linux distributions.
 const int FUTEX_WAIT = 0;
 const int FUTEX_WAKE = 1;
@@ -177,6 +183,12 @@ uptr GetTid() {
   return syscall(__NR_gettid);
 }
 
+u64 NanoTime() {
+  kernel_timeval tv;
+  syscall(__NR_gettimeofday, &tv, 0);
+  return (u64)tv.tv_sec * 1000*1000*1000 + tv.tv_usec * 1000;
+}
+
 void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,
                                 uptr *stack_bottom) {
   static const uptr kMaxThreadStackSize = 256 * (1 << 20);  // 256M

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=177627&r1=177626&r2=177627&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc Thu Mar 21 01:24:31 2013
@@ -95,36 +95,49 @@ ThreadState::ThreadState(Context *ctx, i
   , tls_size(tls_size) {
 }
 
-static void MemoryProfileThread(void *arg) {
-  ScopedInRtl in_rtl;
-  fd_t fd = (fd_t)(uptr)arg;
+static void MemoryProfiler(int i, fd_t fd) {
   Context *ctx = CTX();
+  InternalScopedBuffer<char> buf(4096);
+  uptr n_threads;
+  uptr n_running_threads;
+  ctx->thread_registry->GetNumberOfThreads(&n_threads, &n_running_threads);
+  internal_snprintf(buf.data(), buf.size(), "%d: nthr=%d nlive=%d\n",
+      i, n_threads, n_running_threads);
+  internal_write(fd, buf.data(), internal_strlen(buf.data()));
+  WriteMemoryProfile(buf.data(), buf.size());
+  internal_write(fd, buf.data(), internal_strlen(buf.data()));
+}
+
+static void BackgroundThread(void *arg) {
+  ScopedInRtl in_rtl;
+
+  fd_t mprof_fd = kInvalidFd;
+  if (flags()->profile_memory && flags()->profile_memory[0]) {
+    InternalScopedBuffer<char> filename(4096);
+    internal_snprintf(filename.data(), filename.size(), "%s.%d",
+        flags()->profile_memory, GetPid());
+    mprof_fd = OpenFile(filename.data(), true);
+    if (mprof_fd == kInvalidFd) {
+      Printf("ThreadSanitizer: failed to open memory profile file '%s'\n",
+          &filename[0]);
+    }
+  }
+
+  u64 last_flush = NanoTime();
   for (int i = 0; ; i++) {
-    InternalScopedBuffer<char> buf(4096);
-    uptr n_threads;
-    uptr n_running_threads;
-    ctx->thread_registry->GetNumberOfThreads(&n_threads, &n_running_threads);
-    internal_snprintf(buf.data(), buf.size(), "%d: nthr=%d nlive=%d\n",
-        i, n_threads, n_running_threads);
-    internal_write(fd, buf.data(), internal_strlen(buf.data()));
-    WriteMemoryProfile(buf.data(), buf.size());
-    internal_write(fd, buf.data(), internal_strlen(buf.data()));
     SleepForSeconds(1);
-  }
-}
+    u64 now = NanoTime();
 
-static void InitializeMemoryProfile() {
-  if (flags()->profile_memory == 0 || flags()->profile_memory[0] == 0)
-    return;
-  InternalScopedBuffer<char> filename(4096);
-  internal_snprintf(filename.data(), filename.size(), "%s.%d",
-      flags()->profile_memory, GetPid());
-  fd_t fd = OpenFile(filename.data(), true);
-  if (fd == kInvalidFd) {
-    Printf("Failed to open memory profile file '%s'\n", &filename[0]);
-    Die();
+    if (flags()->flush_memory_ms) {
+      if (last_flush + flags()->flush_memory_ms * 1000*1000 > now) {
+        FlushShadowMemory();
+        last_flush = NanoTime();
+      }
+    }
+
+    if (mprof_fd != kInvalidFd)
+      MemoryProfiler(i, mprof_fd);
   }
-  internal_start_thread(&MemoryProfileThread, (void*)(uptr)fd);
 }
 
 void DontNeedShadowFor(uptr addr, uptr size) {
@@ -133,22 +146,6 @@ void DontNeedShadowFor(uptr addr, uptr s
   FlushUnneededShadowMemory(shadow_beg, shadow_end - shadow_beg);
 }
 
-static void MemoryFlushThread(void *arg) {
-  ScopedInRtl in_rtl;
-  for (int i = 0; ; i++) {
-    SleepForMillis(flags()->flush_memory_ms);
-    FlushShadowMemory();
-  }
-}
-
-static void InitializeMemoryFlush() {
-  if (flags()->flush_memory_ms == 0)
-    return;
-  if (flags()->flush_memory_ms < 100)
-    flags()->flush_memory_ms = 100;
-  internal_start_thread(&MemoryFlushThread, 0);
-}
-
 void MapShadow(uptr addr, uptr size) {
   MmapFixedNoReserve(MemToShadow(addr), size * kShadowMultiplier);
 }
@@ -205,8 +202,7 @@ void Initialize(ThreadState *thr) {
     }
   }
 #endif
-  InitializeMemoryProfile();
-  InitializeMemoryFlush();
+  internal_start_thread(&BackgroundThread, 0);
 
   if (ctx->flags.verbosity)
     Printf("***** Running under ThreadSanitizer v2 (pid %d) *****\n",





More information about the llvm-commits mailing list