[llvm-commits] [compiler-rt] r157248 - in /compiler-rt/trunk/lib/tsan/rtl: tsan_flags.cc tsan_flags.h tsan_interceptors.cc tsan_mutex.cc tsan_platform.h tsan_platform_linux.cc tsan_rtl.cc tsan_sync.cc tsan_sync.h

Dmitry Vyukov dvyukov at google.com
Tue May 22 04:33:04 PDT 2012


Author: dvyukov
Date: Tue May 22 06:33:03 2012
New Revision: 157248

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

Modified:
    compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_flags.h
    compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_mutex.cc
    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
    compiler-rt/trunk/lib/tsan/rtl/tsan_sync.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_sync.h

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc?rev=157248&r1=157247&r2=157248&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc Tue May 22 06:33:03 2012
@@ -46,6 +46,7 @@
   f->log_fileno = 2;
   f->atexit_sleep_ms = 1000;
   f->verbosity = 0;
+  f->profile_memory = "";
 
   // Let a frontend override.
   OverrideFlags(f);
@@ -63,6 +64,7 @@
   Flag(env, &f->log_fileno, "log_fileno");
   Flag(env, &f->atexit_sleep_ms, "atexit_sleep_ms");
   Flag(env, &f->verbosity, "verbosity");
+  Flag(env, &f->profile_memory, "profile_memory");
 }
 
 static const char *GetFlagValue(const char *env, const char *name,

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_flags.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_flags.h?rev=157248&r1=157247&r2=157248&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_flags.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_flags.h Tue May 22 06:33:03 2012
@@ -46,6 +46,8 @@
   int atexit_sleep_ms;
   // Verbosity level (0 - silent, 1 - a bit of output, 2+ - more output).
   int verbosity;
+  // If set, periodically write memory profile to that file.
+  const char *profile_memory;
 };
 
 Flags *flags();

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc?rev=157248&r1=157247&r2=157248&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc Tue May 22 06:33:03 2012
@@ -1551,4 +1551,10 @@
   return (const char*)REAL(strchr)((void*)where, what);
 }
 
+void internal_start_thread(void(*func)(void *arg), void *arg) {
+  void *th;
+  REAL(pthread_create)(&th, 0, (void*(*)(void *arg))func, arg);
+  REAL(pthread_detach)(th);
+}
+
 }  // namespace __tsan

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_mutex.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_mutex.cc?rev=157248&r1=157247&r2=157248&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_mutex.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_mutex.cc Tue May 22 06:33:03 2012
@@ -163,7 +163,7 @@
     if (iter_++ < kActiveSpinIters)
       proc_yield(kActiveSpinCnt);
     else
-      sched_yield();
+      internal_yield();
     return true;
   }
 

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=157248&r1=157247&r2=157248&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h Tue May 22 06:33:03 2012
@@ -64,11 +64,16 @@
 #endif
 }
 
+uptr GetShadowMemoryConsumption();
+
 const char *InitializePlatform();
 void FinalizePlatform();
 int GetPid();
 
-void sched_yield();
+void internal_yield();
+void internal_sleep_ms(u32 ms);
+
+void internal_start_thread(void(*func)(void*), void *arg);
 
 typedef int fd_t;
 const fd_t kInvalidFd = -1;

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=157248&r1=157247&r2=157248&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc Tue May 22 06:33:03 2012
@@ -59,6 +59,10 @@
   _exit(1);
 }
 
+uptr GetShadowMemoryConsumption() {
+  return 0;
+}
+
 static void *my_mmap(void *addr, size_t length, int prot, int flags,
                     int fd, u64 offset) {
   ScopedInRtl in_rtl;
@@ -69,11 +73,15 @@
 # endif
 }
 
-void sched_yield() {
+void internal_yield() {
   ScopedInRtl in_rtl;
   syscall(__NR_sched_yield);
 }
 
+void internal_sleep_ms(u32 ms) {
+  usleep(ms * 1000);
+}
+
 fd_t internal_open(const char *name, bool write) {
   ScopedInRtl in_rtl;
   return syscall(__NR_open, name,

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=157248&r1=157247&r2=157248&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc Tue May 22 06:33:03 2012
@@ -79,6 +79,64 @@
   , dead_next() {
 }
 
+static void WriteMemoryProfile(char *buf, uptr buf_size, int num) {
+  uptr shadow = GetShadowMemoryConsumption();
+
+  int nthread = 0;
+  int nlivethread = 0;
+  uptr threadmem = 0;
+  {
+    Lock l(&ctx->thread_mtx);
+    for (unsigned i = 0; i < kMaxTid; i++) {
+      ThreadContext *tctx = ctx->threads[i];
+      if (tctx == 0)
+        continue;
+      nthread += 1;
+      threadmem += sizeof(ThreadContext);
+      if (tctx->status != ThreadStatusRunning)
+        continue;
+      nlivethread += 1;
+      threadmem += sizeof(ThreadState);
+    }
+  }
+
+  uptr nsync = 0;
+  uptr syncmem = CTX()->synctab.GetMemoryConsumption(&nsync);
+
+  Snprintf(buf, buf_size, "%d: shadow=%luMB"
+                          " thread=%luMB(total=%d/live=%d)"
+                          " sync=%luMB(cnt=%lu)\n",
+    num,
+    shadow >> 20,
+    threadmem >> 20, nthread, nlivethread,
+    syncmem >> 20, nsync);
+}
+
+static void MemoryProfileThread(void *arg) {
+  ScopedInRtl in_rtl;
+  fd_t fd = (fd_t)(uptr)arg;
+  for (int i = 0; ; i++) {
+    InternalScopedBuf<char> buf(4096);
+    WriteMemoryProfile(buf.Ptr(), buf.Size(), i);
+    internal_write(fd, buf.Ptr(), internal_strlen(buf.Ptr()));
+    internal_sleep_ms(1000);
+  }
+}
+
+static void InitializeMemoryProfile() {
+  if (flags()->profile_memory == 0 || flags()->profile_memory[0] == 0)
+    return;
+  InternalScopedBuf<char> filename(4096);
+  Snprintf(filename.Ptr(), filename.Size(), "%s.%d",
+      flags()->profile_memory, GetPid());
+  fd_t fd = internal_open(filename.Ptr(), true);
+  if (fd == kInvalidFd) {
+    Printf("Failed to open memory profile file '%s'\n", &filename[0]);
+    Die();
+  }
+  internal_start_thread(&MemoryProfileThread, (void*)(uptr)fd);
+}
+
 void Initialize(ThreadState *thr) {
   // Thread safe because done before all threads exist.
   static bool is_initialized = false;
@@ -97,6 +155,7 @@
   ctx->dead_list_tail = 0;
   InitializeFlags(&ctx->flags, env);
   InitializeSuppressions();
+  InitializeMemoryProfile();
 
   if (ctx->flags.verbosity)
     Printf("***** Running under ThreadSanitizer v2 (pid=%d) *****\n", GetPid());

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_sync.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_sync.cc?rev=157248&r1=157247&r2=157248&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_sync.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_sync.cc Tue May 22 06:33:03 2012
@@ -107,6 +107,26 @@
   return res;
 }
 
+uptr SyncVar::GetMemoryConsumption() {
+  return sizeof(*this)
+      + clock.size() * sizeof(u64)
+      + read_clock.size() * sizeof(u64)
+      + creation_stack.Size() * sizeof(uptr);
+}
+
+uptr SyncTab::GetMemoryConsumption(uptr *nsync) {
+  uptr mem = 0;
+  for (int i = 0; i < kPartCount; i++) {
+    Part *p = &tab_[i];
+    Lock l(&p->mtx);
+    for (SyncVar *s = p->val; s; s = s->next) {
+      *nsync += 1;
+      mem += s->GetMemoryConsumption();
+    }
+  }
+  return mem;
+}
+
 int SyncTab::PartIdx(uptr addr) {
   return (addr >> 3) % kPartCount;
 }

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_sync.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_sync.h?rev=157248&r1=157247&r2=157248&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_sync.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_sync.h Tue May 22 06:33:03 2012
@@ -52,14 +52,16 @@
   Mutex mtx;
   const uptr addr;
   SyncClock clock;
-  StackTrace creation_stack;
   SyncClock read_clock;  // Used for rw mutexes only.
+  StackTrace creation_stack;
   int owner_tid;  // Set only by exclusive owners.
   int recursion;
   bool is_rw;
   bool is_recursive;
   bool is_broken;
   SyncVar *next;  // In SyncTab hashtable.
+
+  uptr GetMemoryConsumption();
 };
 
 class SyncTab {
@@ -74,6 +76,8 @@
   // If the SyncVar does not exist, returns 0.
   SyncVar* GetAndRemove(ThreadState *thr, uptr pc, uptr addr);
 
+  uptr GetMemoryConsumption(uptr *nsync);
+
  private:
   struct Part {
     Mutex mtx;





More information about the llvm-commits mailing list