[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