[compiler-rt] r193163 - [msan] Drain allocator cache when leaving thread.

Evgeniy Stepanov eugeni.stepanov at gmail.com
Tue Oct 22 07:31:31 PDT 2013


Author: eugenis
Date: Tue Oct 22 09:31:30 2013
New Revision: 193163

URL: http://llvm.org/viewvc/llvm-project?rev=193163&view=rev
Log:
[msan] Drain allocator cache when leaving thread.

Modified:
    compiler-rt/trunk/lib/msan/msan.h
    compiler-rt/trunk/lib/msan/msan_allocator.cc
    compiler-rt/trunk/lib/msan/msan_interceptors.cc

Modified: compiler-rt/trunk/lib/msan/msan.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan.h?rev=193163&r1=193162&r2=193163&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan.h (original)
+++ compiler-rt/trunk/lib/msan/msan.h Tue Oct 22 09:31:30 2013
@@ -44,6 +44,7 @@ bool InitShadow(bool prot1, bool prot2,
 char *GetProcSelfMaps();
 void InitializeInterceptors();
 
+void MsanAllocatorThreadFinish();
 void *MsanReallocate(StackTrace *stack, void *oldp, uptr size,
                      uptr alignment, bool zeroise);
 void MsanDeallocate(StackTrace *stack, void *ptr);

Modified: compiler-rt/trunk/lib/msan/msan_allocator.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan_allocator.cc?rev=193163&r1=193162&r2=193163&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan_allocator.cc (original)
+++ compiler-rt/trunk/lib/msan/msan_allocator.cc Tue Oct 22 09:31:30 2013
@@ -46,6 +46,10 @@ static inline void Init() {
   allocator.Init();
 }
 
+void MsanAllocatorThreadFinish() {
+  allocator.SwallowCache(&cache);
+}
+
 static void *MsanAllocate(StackTrace *stack, uptr size,
                           uptr alignment, bool zeroise) {
   Init();

Modified: compiler-rt/trunk/lib/msan/msan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan_interceptors.cc?rev=193163&r1=193162&r2=193163&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/msan/msan_interceptors.cc Tue Oct 22 09:31:30 2013
@@ -37,6 +37,8 @@ using __sanitizer::atomic_load;
 using __sanitizer::atomic_store;
 using __sanitizer::atomic_uintptr_t;
 
+static unsigned g_thread_finalize_key;
+
 // True if this is a nested interceptor.
 static THREADLOCAL int in_interceptor_scope;
 
@@ -1040,6 +1042,39 @@ extern "C" int pthread_attr_init(void *a
 extern "C" int pthread_attr_destroy(void *attr);
 extern "C" int pthread_attr_setstacksize(void *attr, uptr stacksize);
 extern "C" int pthread_attr_getstack(void *attr, uptr *stack, uptr *stacksize);
+extern "C" int pthread_setspecific(unsigned key, const void *v);
+extern "C" int pthread_yield();
+
+static void thread_finalize(void *v) {
+  uptr iter = (uptr)v;
+  if (iter > 1) {
+    if (pthread_setspecific(g_thread_finalize_key, (void*)(iter - 1))) {
+      Printf("MemorySanitizer: failed to set thread key\n");
+      Die();
+    }
+    return;
+  }
+  MsanAllocatorThreadFinish();
+}
+
+struct ThreadParam {
+  void* (*callback)(void *arg);
+  void *param;
+  atomic_uintptr_t done;
+};
+
+static void *MsanThreadStartFunc(void *arg) {
+  ThreadParam *p = (ThreadParam *)arg;
+  void* (*callback)(void *arg) = p->callback;
+  void *param = p->param;
+  if (pthread_setspecific(g_thread_finalize_key,
+          (void *)kPthreadDestructorIterations)) {
+    Printf("MemorySanitizer: failed to set thread key\n");
+    Die();
+  }
+  atomic_store(&p->done, 1, memory_order_release);
+  return callback(param);
+}
 
 INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*),
             void * param) {
@@ -1052,7 +1087,17 @@ INTERCEPTOR(int, pthread_create, void *t
 
   AdjustStackSizeLinux(attr);
 
-  int res = REAL(pthread_create)(th, attr, callback, param);
+  ThreadParam p;
+  p.callback = callback;
+  p.param = param;
+  atomic_store(&p.done, 0, memory_order_relaxed);
+
+  int res = REAL(pthread_create)(th, attr, MsanThreadStartFunc, (void *)&p);
+  if (res == 0) {
+    while (atomic_load(&p.done, memory_order_acquire) != 1)
+      pthread_yield();
+  }
+
   if (attr == &myattr)
     pthread_attr_destroy(&myattr);
   if (!res) {
@@ -1387,6 +1432,12 @@ void InitializeInterceptors() {
   INTERCEPT_FUNCTION(pthread_join);
   INTERCEPT_FUNCTION(tzset);
   INTERCEPT_FUNCTION(__cxa_atexit);
+
+  if (REAL(pthread_key_create)(&g_thread_finalize_key, &thread_finalize)) {
+    Printf("MemorySanitizer: failed to create thread key\n");
+    Die();
+  }
+
   inited = 1;
 }
 }  // namespace __msan





More information about the llvm-commits mailing list