[compiler-rt] r177286 - tsan: better memory profiler

Dmitry Vyukov dvyukov at google.com
Mon Mar 18 06:55:33 PDT 2013


Author: dvyukov
Date: Mon Mar 18 08:55:33 2013
New Revision: 177286

URL: http://llvm.org/viewvc/llvm-project?rev=177286&view=rev
Log:
tsan: better memory profiler


Modified:
    compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h
    compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.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=177286&r1=177285&r2=177286&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h Mon Mar 18 08:55:33 2013
@@ -132,8 +132,8 @@ static inline uptr AlternativeAddress(up
 #endif
 }
 
-uptr GetShadowMemoryConsumption();
 void FlushShadowMemory();
+void WriteMemoryProfile(char *buf, uptr buf_size);
 
 const char *InitializePlatform();
 void FinalizePlatform();

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc?rev=177286&r1=177285&r2=177286&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc Mon Mar 18 08:55:33 2013
@@ -42,8 +42,10 @@
 #include <dlfcn.h>
 #define __need_res_state
 #include <resolv.h>
+#include <malloc.h>
 
 extern "C" int arch_prctl(int code, __sanitizer::uptr *addr);
+extern "C" struct mallinfo __libc_mallinfo();
 
 namespace __tsan {
 
@@ -68,8 +70,75 @@ ScopedInRtl::~ScopedInRtl() {
 }
 #endif
 
-uptr GetShadowMemoryConsumption() {
-  return 0;
+static bool ishex(char c) {
+  return (c >= '0' && c <= '9')
+      || (c >= 'a' && c <= 'f');
+}
+
+static uptr readhex(const char *p) {
+  uptr v = 0;
+  for (; ishex(p[0]); p++) {
+    if (p[0] >= '0' && p[0] <= '9')
+      v = v * 16 + p[0] - '0';
+    else
+      v = v * 16 + p[0] - 'a' + 10;
+  }
+  return v;
+}
+
+static uptr readdec(const char *p) {
+  uptr v = 0;
+  for (; p[0] >= '0' && p[0] <= '9' ; p++)
+    v = v * 10 + p[0] - '0';
+  return v;
+}
+
+void WriteMemoryProfile(char *buf, uptr buf_size) {
+  char *smaps = 0;
+  uptr smaps_cap = 0;
+  uptr smaps_len = ReadFileToBuffer("/proc/self/smaps",
+      &smaps, &smaps_cap, 64<<20);
+  uptr mem[6] = {};
+  uptr total = 0;
+  uptr start = 0;
+  bool file = false;
+  const char *pos = smaps;
+  while (pos < smaps + smaps_len) {
+    if (ishex(pos[0])) {
+      start = readhex(pos);
+      for (; *pos != '/' && *pos > '\n'; pos++) {}
+      file = *pos == '/';
+    } else if (internal_strncmp(pos, "Rss:", 4) == 0) {
+      for (; *pos < '0' || *pos > '9'; pos++) {}
+      uptr rss = readdec(pos) * 1024;
+      total += rss;
+      start >>= 40;
+      if (start < 0x10)  // shadow
+        mem[0] += rss;
+      else if (start >= 0x20 && start < 0x30)  // compat modules
+        mem[file ? 1 : 2] += rss;
+      else if (start >= 0x7e)  // modules
+        mem[file ? 1 : 2] += rss;
+      else if (start >= 0x60 && start < 0x62)  // traces
+        mem[3] += rss;
+      else if (start >= 0x7d && start < 0x7e)  // heap
+        mem[4] += rss;
+      else  // other
+        mem[5] += rss;
+    }
+    while (*pos++ != '\n') {}
+  }
+  UnmapOrDie(smaps, smaps_cap);
+  char *buf_pos = buf;
+  char *buf_end = buf + buf_size;
+  buf_pos += internal_snprintf(buf_pos, buf_end - buf_pos,
+      "RSS %zd MB: shadow:%zd file:%zd mmap:%zd trace:%zd heap:%zd other:%zd\n",
+      total >> 20, mem[0] >> 20, mem[1] >> 20, mem[2] >> 20,
+      mem[3] >> 20, mem[4] >> 20, mem[5] >> 20);
+  struct mallinfo mi = __libc_mallinfo();
+  buf_pos += internal_snprintf(buf_pos, buf_end - buf_pos,
+      "mallinfo: arena=%d mmap=%d fordblks=%d keepcost=%d\n",
+      mi.arena >> 20, mi.hblkhd >> 20, mi.fordblks >> 20, mi.keepcost >> 20);
 }
 
 void FlushShadowMemory() {

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=177286&r1=177285&r2=177286&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc Mon Mar 18 08:55:33 2013
@@ -93,23 +93,19 @@ ThreadState::ThreadState(Context *ctx, i
   , tls_size(tls_size) {
 }
 
-static void WriteMemoryProfile(char *buf, uptr buf_size, int num) {
-  uptr n_threads;
-  uptr n_running_threads;
-  ctx->thread_registry->GetNumberOfThreads(&n_threads, &n_running_threads);
-  uptr threadmem = n_threads * sizeof(ThreadContext) +
-                   n_running_threads * sizeof(ThreadState);
-
-  internal_snprintf(buf, buf_size, "%d: thread=%zuMB(total=%d/live=%d)\n",
-    num, threadmem >> 20, n_threads, n_running_threads);
-}
-
 static void MemoryProfileThread(void *arg) {
   ScopedInRtl in_rtl;
   fd_t fd = (fd_t)(uptr)arg;
+  Context *ctx = CTX();
   for (int i = 0; ; i++) {
     InternalScopedBuffer<char> buf(4096);
-    WriteMemoryProfile(buf.data(), buf.size(), i);
+    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);
   }





More information about the llvm-commits mailing list