[compiler-rt] r193602 - tsan/asan: support pthread_setname_np to set thread names

Kostya Serebryany kcc at google.com
Wed Nov 13 04:58:15 PST 2013


This causes a severe performance degradation if a test with lots of threads
setting their names simultaneously.
Previously, we did not intercept  pthread_setname_np and relied on prctl
interceptor.
Now on every pthread_setname_np we do a mutex lock and O(n_threads)
operations under a lock.
Please fix.


On Tue, Oct 29, 2013 at 2:30 PM, Dmitry Vyukov <dvyukov at google.com> wrote:

> Author: dvyukov
> Date: Tue Oct 29 05:30:39 2013
> New Revision: 193602
>
> URL: http://llvm.org/viewvc/llvm-project?rev=193602&view=rev
> Log:
> tsan/asan: support pthread_setname_np to set thread names
>
>
> Added:
>     compiler-rt/trunk/lib/tsan/lit_tests/thread_name2.cc
> Modified:
>     compiler-rt/trunk/lib/asan/asan_interceptors.cc
>     compiler-rt/trunk/lib/msan/msan_interceptors.cc
>
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
>
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h
>     compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.cc
>     compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.h
>     compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
>     compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc
>     compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h
>
> Modified: compiler-rt/trunk/lib/asan/asan_interceptors.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.cc?rev=193602&r1=193601&r2=193602&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/asan/asan_interceptors.cc (original)
> +++ compiler-rt/trunk/lib/asan/asan_interceptors.cc Tue Oct 29 05:30:39
> 2013
> @@ -130,6 +130,8 @@ DECLARE_REAL_AND_INTERCEPTOR(void, free,
>    do {                                                      \
>    } while (false)
>  #define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) SetThreadName(name)
> +#define COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name) \
> +    asanThreadRegistry().SetThreadNameByUserId(thread, name)
>  #define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name)
>  #define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit()
>  #include "sanitizer_common/sanitizer_common_interceptors.inc"
>
> 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=193602&r1=193601&r2=193602&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/msan/msan_interceptors.cc (original)
> +++ compiler-rt/trunk/lib/msan/msan_interceptors.cc Tue Oct 29 05:30:39
> 2013
> @@ -1224,6 +1224,9 @@ extern "C" int *__errno_location(void);
>  #define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) \
>    do {                                                \
>    } while (false)  // FIXME
> +#define COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name) \
> +  do {                                                         \
> +  } while (false)  // FIXME
>  #define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name)
>  #define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit()
>  #include "sanitizer_common/sanitizer_common_interceptors.inc"
>
> Modified:
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc?rev=193602&r1=193601&r2=193602&view=diff
>
> ==============================================================================
> ---
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
> (original)
> +++
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
> Tue Oct 29 05:30:39 2013
> @@ -23,6 +23,7 @@
>  //   COMMON_INTERCEPTOR_ON_EXIT
>  //   COMMON_INTERCEPTOR_MUTEX_LOCK
>  //   COMMON_INTERCEPTOR_MUTEX_UNLOCK
> +//   COMMON_INTERCEPTOR_SET_PTHREAD_NAME
>
>  //===----------------------------------------------------------------------===//
>  #include "interception/interception.h"
>  #include "sanitizer_platform_interceptors.h"
> @@ -34,19 +35,19 @@
>  #endif // _WIN32
>
>  #ifndef COMMON_INTERCEPTOR_INITIALIZE_RANGE
> -#define COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, p, size)
> +#define COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, p, size) {}
>  #endif
>
>  #ifndef COMMON_INTERCEPTOR_FD_ACCESS
> -#define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd)
> +#define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) {}
>  #endif
>
>  #ifndef COMMON_INTERCEPTOR_MUTEX_LOCK
> -#define COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m)
> +#define COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m) {}
>  #endif
>
>  #ifndef COMMON_INTERCEPTOR_MUTEX_UNLOCK
> -#define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m)
> +#define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) {}
>  #endif
>
>  #if SANITIZER_INTERCEPT_STRCMP
> @@ -2655,6 +2656,18 @@ INTERCEPTOR(char *, tempnam, char *dir,
>  #define INIT_TEMPNAM
>  #endif
>
> +#if SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP
> +INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name) {
> +  void *ctx;
> +  COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name);
> +  COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name);
> +  return REAL(pthread_setname_np)(thread, name);
> +}
> +#define INIT_PTHREAD_SETNAME_NP INTERCEPT_FUNCTION(pthread_setname_np);
> +#else
> +#define INIT_PTHREAD_SETNAME_NP
> +#endif
> +
>
>  #define SANITIZER_COMMON_INTERCEPTORS_INIT \
>    INIT_STRCMP;                             \
> @@ -2757,4 +2770,5 @@ INTERCEPTOR(char *, tempnam, char *dir,
>    INIT_TMPNAM;                             \
>    INIT_TMPNAM_R;                           \
>    INIT_TEMPNAM;                            \
> +  INIT_PTHREAD_SETNAME_NP;                 \
>  /**/
>
> Modified:
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h?rev=193602&r1=193601&r2=193602&view=diff
>
> ==============================================================================
> ---
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h
> (original)
> +++
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h
> Tue Oct 29 05:30:39 2013
> @@ -149,5 +149,6 @@
>
>  # define SANITIZER_INTERCEPT_PHTREAD_MUTEX SI_NOT_WINDOWS
>  # define SANITIZER_INTERCEPT_PTHREAD_COND SI_NOT_WINDOWS
> +# define SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP SI_LINUX_NOT_ANDROID
>
>  #endif  // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H
>
> Modified:
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.cc?rev=193602&r1=193601&r2=193602&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.cc
> (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.cc
> Tue Oct 29 05:30:39 2013
> @@ -200,6 +200,18 @@ void ThreadRegistry::SetThreadName(u32 t
>    tctx->SetName(name);
>  }
>
> +void ThreadRegistry::SetThreadNameByUserId(uptr user_id, const char
> *name) {
> +  BlockingMutexLock l(&mtx_);
> +  for (u32 tid = 0; tid < n_contexts_; tid++) {
> +    ThreadContextBase *tctx = threads_[tid];
> +    if (tctx != 0 && tctx->user_id == user_id &&
> +        tctx->status != ThreadStatusInvalid) {
> +      tctx->SetName(name);
> +      return;
> +    }
> +  }
> +}
> +
>  void ThreadRegistry::DetachThread(u32 tid) {
>    BlockingMutexLock l(&mtx_);
>    CHECK_LT(tid, n_contexts_);
>
> Modified:
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.h
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.h?rev=193602&r1=193601&r2=193602&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.h
> (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.h Tue
> Oct 29 05:30:39 2013
> @@ -109,6 +109,7 @@ class ThreadRegistry {
>    ThreadContextBase *FindThreadContextByOsIDLocked(uptr os_id);
>
>    void SetThreadName(u32 tid, const char *name);
> +  void SetThreadNameByUserId(uptr user_id, const char *name);
>    void DetachThread(u32 tid);
>    void JoinThread(u32 tid, void *arg);
>    void FinishThread(u32 tid);
>
> Added: compiler-rt/trunk/lib/tsan/lit_tests/thread_name2.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/lit_tests/thread_name2.cc?rev=193602&view=auto
>
> ==============================================================================
> --- compiler-rt/trunk/lib/tsan/lit_tests/thread_name2.cc (added)
> +++ compiler-rt/trunk/lib/tsan/lit_tests/thread_name2.cc Tue Oct 29
> 05:30:39 2013
> @@ -0,0 +1,32 @@
> +// RUN: %clangxx_tsan -O1 %s -o %t && not %t 2>&1 | FileCheck %s
> +#include <pthread.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +
> +int Global;
> +
> +void *Thread1(void *x) {
> +  sleep(1);
> +  Global++;
> +  return 0;
> +}
> +
> +void *Thread2(void *x) {
> +  pthread_setname_np(pthread_self(), "foobar2");
> +  Global--;
> +  return 0;
> +}
> +
> +int main() {
> +  pthread_t t[2];
> +  pthread_create(&t[0], 0, Thread1, 0);
> +  pthread_create(&t[1], 0, Thread2, 0);
> +  pthread_setname_np(t[0], "foobar1");
> +  pthread_join(t[0], NULL);
> +  pthread_join(t[1], NULL);
> +}
> +
> +// CHECK: WARNING: ThreadSanitizer: data race
> +// CHECK:   Thread T1 'foobar1'
> +// CHECK:   Thread T2 'foobar2'
> +
>
> 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=193602&r1=193601&r2=193602&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc (original)
> +++ compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc Tue Oct 29
> 05:30:39 2013
> @@ -1837,38 +1837,54 @@ struct TsanInterceptorContext {
>  #define COMMON_INTERCEPTOR_UNPOISON_PARAM(ctx, count) \
>    do {                                                \
>    } while (false)
> +
>  #define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size)
>  \
>    MemoryAccessRange(((TsanInterceptorContext *)ctx)->thr,
> \
>                      ((TsanInterceptorContext *)ctx)->pc, (uptr)ptr, size,
> \
>                      true)
> +
>  #define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size)
>   \
>    MemoryAccessRange(((TsanInterceptorContext *) ctx)->thr,
>    \
>                      ((TsanInterceptorContext *) ctx)->pc, (uptr) ptr,
> size, \
>                      false)
> +
>  #define COMMON_INTERCEPTOR_ENTER(ctx, func, ...)      \
>    SCOPED_TSAN_INTERCEPTOR(func, __VA_ARGS__);         \
>    TsanInterceptorContext _ctx = {thr, caller_pc, pc}; \
>    ctx = (void *)&_ctx;                                \
>    (void) ctx;
> +
>  #define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \
>    FdAcquire(((TsanInterceptorContext *) ctx)->thr, pc, fd)
> +
>  #define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \
>    FdRelease(((TsanInterceptorContext *) ctx)->thr, pc, fd)
> +
>  #define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) \
>    FdAccess(((TsanInterceptorContext *) ctx)->thr, pc, fd)
> +
>  #define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd) \
>    FdSocketAccept(((TsanInterceptorContext *) ctx)->thr, pc, fd, newfd)
> +
>  #define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) \
>    ThreadSetName(((TsanInterceptorContext *) ctx)->thr, name)
> +
> +#define COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name) \
> +  CTX()->thread_registry->SetThreadNameByUserId(thread, name)
> +
>  #define COMMON_INTERCEPTOR_BLOCK_REAL(name) BLOCK_REAL(name)
> +
>  #define COMMON_INTERCEPTOR_ON_EXIT(ctx) \
>    OnExit(((TsanInterceptorContext *) ctx)->thr)
> +
>  #define COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m) \
>    MutexLock(((TsanInterceptorContext *)ctx)->thr, \
>              ((TsanInterceptorContext *)ctx)->pc, (uptr)m)
> +
>  #define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) \
>    MutexUnlock(((TsanInterceptorContext *)ctx)->thr, \
>              ((TsanInterceptorContext *)ctx)->pc, (uptr)m)
> +
>  #include "sanitizer_common/sanitizer_common_interceptors.inc"
>
>  #define TSAN_SYSCALL() \
>
> Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc?rev=193602&r1=193601&r2=193602&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc (original)
> +++ compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc Tue Oct 29 05:30:39 2013
> @@ -182,6 +182,7 @@ void StatOutput(u64 *stat) {
>    name[StatInt_pthread_barrier_wait]     = "  pthread_barrier_wait
>      ";
>    name[StatInt_pthread_once]             = "  pthread_once
>      ";
>    name[StatInt_pthread_getschedparam]    = "  pthread_getschedparam
>     ";
> +  name[StatInt_pthread_setname_np]       = "  pthread_setname_np
>      ";
>    name[StatInt_sem_init]                 = "  sem_init
>      ";
>    name[StatInt_sem_destroy]              = "  sem_destroy
>     ";
>    name[StatInt_sem_wait]                 = "  sem_wait
>      ";
>
> Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h?rev=193602&r1=193601&r2=193602&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h (original)
> +++ compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h Tue Oct 29 05:30:39 2013
> @@ -177,6 +177,7 @@ enum StatType {
>    StatInt_pthread_barrier_wait,
>    StatInt_pthread_once,
>    StatInt_pthread_getschedparam,
> +  StatInt_pthread_setname_np,
>    StatInt_sem_init,
>    StatInt_sem_destroy,
>    StatInt_sem_wait,
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131113/a2cd769a/attachment.html>


More information about the llvm-commits mailing list