summaryrefslogtreecommitdiffstats
path: root/compiler-rt/lib
diff options
context:
space:
mode:
authorKuba Mracek <mracek@apple.com>2016-12-15 16:45:28 +0000
committerKuba Mracek <mracek@apple.com>2016-12-15 16:45:28 +0000
commit659949cb03c7c49a1a9c7096cf211311f5171846 (patch)
tree49cf1fb227dd29a88605538fc749f4128000f4e5 /compiler-rt/lib
parentba4642269438839a8710a7e4e3db64fa41170086 (diff)
downloadbcm5719-llvm-659949cb03c7c49a1a9c7096cf211311f5171846.tar.gz
bcm5719-llvm-659949cb03c7c49a1a9c7096cf211311f5171846.zip
[tsan] Add interceptor for libcxx __shared_count::__release_shared()
We already have an interceptor for __shared_weak_count::__release_shared, this patch handles __shared_count::__release_shared in the same way. This should get rid of TSan false positives when using std::future. Differential Revision: https://reviews.llvm.org/D27797 llvm-svn: 289831
Diffstat (limited to 'compiler-rt/lib')
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_interceptors_mac.cc22
1 files changed, 19 insertions, 3 deletions
diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_mac.cc b/compiler-rt/lib/tsan/rtl/tsan_interceptors_mac.cc
index 015e48eb52b..fc5eb049907 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_mac.cc
+++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_mac.cc
@@ -297,18 +297,20 @@ struct fake_shared_weak_count {
};
} // namespace
-// This adds a libc++ interceptor for:
+// The following code adds libc++ interceptors for:
// void __shared_weak_count::__release_shared() _NOEXCEPT;
+// bool __shared_count::__release_shared() _NOEXCEPT;
// Shared and weak pointers in C++ maintain reference counts via atomics in
// libc++.dylib, which are TSan-invisible, and this leads to false positives in
-// destructor code. This interceptor re-implements the whole function so that
+// destructor code. These interceptors re-implements the whole functions so that
// the mo_acq_rel semantics of the atomic decrement are visible.
//
-// Unfortunately, this interceptor cannot simply Acquire/Release some sync
+// Unfortunately, the interceptors cannot simply Acquire/Release some sync
// object and call the original function, because it would have a race between
// the sync and the destruction of the object. Calling both under a lock will
// not work because the destructor can invoke this interceptor again (and even
// in a different thread, so recursive locks don't help).
+
STDCXX_INTERCEPTOR(void, _ZNSt3__119__shared_weak_count16__release_sharedEv,
fake_shared_weak_count *o) {
if (!flags()->shared_ptr_interceptor)
@@ -327,6 +329,20 @@ STDCXX_INTERCEPTOR(void, _ZNSt3__119__shared_weak_count16__release_sharedEv,
}
}
+STDCXX_INTERCEPTOR(bool, _ZNSt3__114__shared_count16__release_sharedEv,
+ fake_shared_weak_count *o) {
+ if (!flags()->shared_ptr_interceptor)
+ return REAL(_ZNSt3__114__shared_count16__release_sharedEv)(o);
+
+ SCOPED_TSAN_INTERCEPTOR(_ZNSt3__114__shared_count16__release_sharedEv, o);
+ if (__tsan_atomic64_fetch_add(&o->shared_owners, -1, mo_release) == 0) {
+ Acquire(thr, pc, (uptr)&o->shared_owners);
+ o->on_zero_shared();
+ return true;
+ }
+ return false;
+}
+
namespace {
struct call_once_callback_args {
void (*orig_func)(void *arg);
OpenPOWER on IntegriCloud