From 4a9b747bfb5579f69514a13b643684714343d4e7 Mon Sep 17 00:00:00 2001 From: Julian Lettner Date: Fri, 16 Aug 2019 22:41:25 +0000 Subject: [PATCH] [TSan] Add interceptors for os_unfair_lock llvm-svn: 369164 --- .../lib/tsan/rtl/tsan_interceptors_mac.cpp | 53 +++++++++++++++++++ compiler-rt/test/tsan/Darwin/os_unfair_lock.c | 30 +++++++++++ 2 files changed, 83 insertions(+) create mode 100644 compiler-rt/test/tsan/Darwin/os_unfair_lock.c diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_mac.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_mac.cpp index 332e1392e75c..7b9173650ef4 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_mac.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_mac.cpp @@ -243,6 +243,59 @@ TSAN_INTERCEPTOR(void, os_lock_unlock, void *lock) { REAL(os_lock_unlock)(lock); } +extern "C" { + #define _LOCK_AVAILABILITY \ + __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) \ + __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) + + _LOCK_AVAILABILITY void os_unfair_lock_lock(void *lock); + // NOTE: `options` actually has type `os_unfair_lock_options_t` but this + // should be ABI compatible. + _LOCK_AVAILABILITY void os_unfair_lock_lock_with_options(void *lock, + u32 options); + _LOCK_AVAILABILITY bool os_unfair_lock_trylock(void *lock); + _LOCK_AVAILABILITY void os_unfair_lock_unlock(void *lock); +} + +TSAN_INTERCEPTOR(void, os_unfair_lock_lock, void *lock) { + if (!cur_thread()->is_inited || cur_thread()->is_dead) { + return REAL(os_unfair_lock_lock)(lock); + } + SCOPED_TSAN_INTERCEPTOR(os_unfair_lock_lock, lock); + REAL(os_unfair_lock_lock)(lock); + Acquire(thr, pc, (uptr)lock); +} + +TSAN_INTERCEPTOR(void, os_unfair_lock_lock_with_options, void *lock, + u32 options) { + if (!cur_thread()->is_inited || cur_thread()->is_dead) { + return REAL(os_unfair_lock_lock_with_options)(lock, options); + } + SCOPED_TSAN_INTERCEPTOR(os_unfair_lock_lock_with_options, lock, options); + REAL(os_unfair_lock_lock_with_options)(lock, options); + Acquire(thr, pc, (uptr)lock); +} + +TSAN_INTERCEPTOR(bool, os_unfair_lock_trylock, void *lock) { + if (!cur_thread()->is_inited || cur_thread()->is_dead) { + return REAL(os_unfair_lock_trylock)(lock); + } + SCOPED_TSAN_INTERCEPTOR(os_unfair_lock_trylock, lock); + bool result = REAL(os_unfair_lock_trylock)(lock); + if (result) + Acquire(thr, pc, (uptr)lock); + return result; +} + +TSAN_INTERCEPTOR(void, os_unfair_lock_unlock, void *lock) { + if (!cur_thread()->is_inited || cur_thread()->is_dead) { + return REAL(os_unfair_lock_unlock)(lock); + } + SCOPED_TSAN_INTERCEPTOR(os_unfair_lock_unlock, lock); + Release(thr, pc, (uptr)lock); + REAL(os_unfair_lock_unlock)(lock); +} + TSAN_INTERCEPTOR(void, xpc_connection_set_event_handler, xpc_connection_t connection, xpc_handler_t handler) { SCOPED_TSAN_INTERCEPTOR(xpc_connection_set_event_handler, connection, diff --git a/compiler-rt/test/tsan/Darwin/os_unfair_lock.c b/compiler-rt/test/tsan/Darwin/os_unfair_lock.c new file mode 100644 index 000000000000..e7f0cd52c062 --- /dev/null +++ b/compiler-rt/test/tsan/Darwin/os_unfair_lock.c @@ -0,0 +1,30 @@ +// RUN: %clang_tsan %s -o %t -mmacosx-version-min=10.12 +// RUN: %run %t 2>&1 | FileCheck %s --implicit-check-not='ThreadSanitizer' + +// UNSUPPORTED: ios + +#include +#include +#include + +long global_variable; +os_unfair_lock lock = OS_UNFAIR_LOCK_INIT; + +void *Thread(void *a) { + os_unfair_lock_lock(&lock); + global_variable++; + os_unfair_lock_unlock(&lock); + return NULL; +} + +int main() { + pthread_t t1, t2; + global_variable = 0; + pthread_create(&t1, NULL, Thread, NULL); + pthread_create(&t2, NULL, Thread, NULL); + pthread_join(t1, NULL); + pthread_join(t2, NULL); + fprintf(stderr, "global_variable = %ld\n", global_variable); +} + +// CHECK: global_variable = 2