[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