diff options
| author | Kuba Mracek <mracek@apple.com> | 2016-12-15 16:45:28 +0000 |
|---|---|---|
| committer | Kuba Mracek <mracek@apple.com> | 2016-12-15 16:45:28 +0000 |
| commit | 659949cb03c7c49a1a9c7096cf211311f5171846 (patch) | |
| tree | 49cf1fb227dd29a88605538fc749f4128000f4e5 /compiler-rt/lib | |
| parent | ba4642269438839a8710a7e4e3db64fa41170086 (diff) | |
| download | bcm5719-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.cc | 22 |
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); |

