[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