diff options
author | Kuba Brecka <kuba.brecka@gmail.com> | 2015-12-03 15:10:52 +0000 |
---|---|---|
committer | Kuba Brecka <kuba.brecka@gmail.com> | 2015-12-03 15:10:52 +0000 |
commit | 0423e5cd57e0f23bdf17d3ab7f0fb081871a7800 (patch) | |
tree | 8208a337fe40ec728f2f275004b08da42ee810f9 | |
parent | 792b7958ff50bc46bb413b6dae6440c726a36847 (diff) | |
download | bcm5719-llvm-0423e5cd57e0f23bdf17d3ab7f0fb081871a7800.tar.gz bcm5719-llvm-0423e5cd57e0f23bdf17d3ab7f0fb081871a7800.zip |
[tsan] Add interceptors for Darwin-specific locking APIs
On OS X, there are other-than-pthread locking APIs that are used quite extensively - OSSpinLock and os_lock_lock. Let's add interceptors for those.
Differential Revision: http://reviews.llvm.org/D14987
llvm-svn: 254611
-rw-r--r-- | compiler-rt/lib/tsan/CMakeLists.txt | 1 | ||||
-rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_interceptors_mac.cc | 91 | ||||
-rw-r--r-- | compiler-rt/test/tsan/Darwin/osspinlock-norace.cc | 30 |
3 files changed, 122 insertions, 0 deletions
diff --git a/compiler-rt/lib/tsan/CMakeLists.txt b/compiler-rt/lib/tsan/CMakeLists.txt index 076f3c8f44e..2594ab10aa1 100644 --- a/compiler-rt/lib/tsan/CMakeLists.txt +++ b/compiler-rt/lib/tsan/CMakeLists.txt @@ -47,6 +47,7 @@ set(TSAN_CXX_SOURCES if(APPLE) list(APPEND TSAN_SOURCES + rtl/tsan_interceptors_mac.cc rtl/tsan_libdispatch_mac.cc rtl/tsan_platform_mac.cc rtl/tsan_platform_posix.cc) diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_mac.cc b/compiler-rt/lib/tsan/rtl/tsan_interceptors_mac.cc new file mode 100644 index 00000000000..2bf7ad9861c --- /dev/null +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_mac.cc @@ -0,0 +1,91 @@ +//===-- tsan_interceptors_mac.cc ------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of ThreadSanitizer (TSan), a race detector. +// +// Mac-specific interceptors. +//===----------------------------------------------------------------------===// + +#include "sanitizer_common/sanitizer_platform.h" +#if SANITIZER_MAC + +#include "interception/interception.h" +#include "tsan_interceptors.h" + +#include <libkern/OSAtomic.h> + +namespace __tsan { + +TSAN_INTERCEPTOR(void, OSSpinLockLock, volatile OSSpinLock *lock) { + CHECK(!cur_thread()->is_dead); + if (!cur_thread()->is_inited) { + return REAL(OSSpinLockLock)(lock); + } + SCOPED_TSAN_INTERCEPTOR(OSSpinLockLock, lock); + REAL(OSSpinLockLock)(lock); + Acquire(thr, pc, (uptr)lock); +} + +TSAN_INTERCEPTOR(bool, OSSpinLockTry, volatile OSSpinLock *lock) { + CHECK(!cur_thread()->is_dead); + if (!cur_thread()->is_inited) { + return REAL(OSSpinLockTry)(lock); + } + SCOPED_TSAN_INTERCEPTOR(OSSpinLockTry, lock); + bool result = REAL(OSSpinLockTry)(lock); + if (result) + Acquire(thr, pc, (uptr)lock); + return result; +} + +TSAN_INTERCEPTOR(void, OSSpinLockUnlock, volatile OSSpinLock *lock) { + CHECK(!cur_thread()->is_dead); + if (!cur_thread()->is_inited) { + return REAL(OSSpinLockUnlock)(lock); + } + SCOPED_TSAN_INTERCEPTOR(OSSpinLockUnlock, lock); + Release(thr, pc, (uptr)lock); + REAL(OSSpinLockUnlock)(lock); +} + +TSAN_INTERCEPTOR(void, os_lock_lock, void *lock) { + CHECK(!cur_thread()->is_dead); + if (!cur_thread()->is_inited) { + return REAL(os_lock_lock)(lock); + } + SCOPED_TSAN_INTERCEPTOR(os_lock_lock, lock); + REAL(os_lock_lock)(lock); + Acquire(thr, pc, (uptr)lock); +} + +TSAN_INTERCEPTOR(bool, os_lock_trylock, void *lock) { + CHECK(!cur_thread()->is_dead); + if (!cur_thread()->is_inited) { + return REAL(os_lock_trylock)(lock); + } + SCOPED_TSAN_INTERCEPTOR(os_lock_trylock, lock); + bool result = REAL(os_lock_trylock)(lock); + if (result) + Acquire(thr, pc, (uptr)lock); + return result; +} + +TSAN_INTERCEPTOR(void, os_lock_unlock, void *lock) { + CHECK(!cur_thread()->is_dead); + if (!cur_thread()->is_inited) { + return REAL(os_lock_unlock)(lock); + } + SCOPED_TSAN_INTERCEPTOR(os_lock_unlock, lock); + Release(thr, pc, (uptr)lock); + REAL(os_lock_unlock)(lock); +} + +} // namespace __tsan + +#endif // SANITIZER_MAC diff --git a/compiler-rt/test/tsan/Darwin/osspinlock-norace.cc b/compiler-rt/test/tsan/Darwin/osspinlock-norace.cc new file mode 100644 index 00000000000..2ac3989c223 --- /dev/null +++ b/compiler-rt/test/tsan/Darwin/osspinlock-norace.cc @@ -0,0 +1,30 @@ +// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s +#include <libkern/OSAtomic.h> +#include <pthread.h> +#include <stdio.h> + +int Global; +OSSpinLock lock; + +void *Thread(void *x) { + OSSpinLockLock(&lock); + Global++; + OSSpinLockUnlock(&lock); + return NULL; +} + +int main() { + fprintf(stderr, "Hello world.\n"); + + pthread_t t[2]; + pthread_create(&t[0], NULL, Thread, NULL); + pthread_create(&t[1], NULL, Thread, NULL); + pthread_join(t[0], NULL); + pthread_join(t[1], NULL); + + fprintf(stderr, "Done.\n"); +} + +// CHECK: Hello world. +// CHECK: Done. +// CHECK-NOT: WARNING: ThreadSanitizer |