diff options
author | Eric Fiselier <eric@efcs.ca> | 2021-06-09 21:17:56 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2021-06-09 21:17:56 +0000 |
commit | dde880b5d29dd20ff601c58f3a67b95332e2469d (patch) | |
tree | c3ecd9b890fcfbd577d7321c790323867c1848de | |
parent | ed4e8619a4ca644b2a496bbf78f5c1cfe8bf51fb (diff) | |
parent | 7be8fdb50c3e36daac46add51be848bf75a3b572 (diff) | |
download | libcxxabi-dde880b5d29dd20ff601c58f3a67b95332e2469d.tar.gz |
Cleanup new cxa guard implementation. am: 6eae8a4e93 am: e205f7693a am: 0da6bf1fdb am: 7be8fdb50c
Original change: https://android-review.googlesource.com/c/platform/external/libcxxabi/+/1727436
Change-Id: I09d31b542abdeccab99c675e221ffdc47b8014bd
-rw-r--r-- | src/cxa_guard_impl.h | 17 | ||||
-rw-r--r-- | test/guard_test_basic.pass.cpp | 2 | ||||
-rw-r--r-- | test/guard_threaded_test.pass.cpp | 47 |
3 files changed, 58 insertions, 8 deletions
diff --git a/src/cxa_guard_impl.h b/src/cxa_guard_impl.h index 8c31848..ea82d20 100644 --- a/src/cxa_guard_impl.h +++ b/src/cxa_guard_impl.h @@ -70,6 +70,13 @@ # error "Either BUILDING_CXA_GUARD or TESTING_CXA_GUARD must be defined" #endif +#if __has_feature(thread_sanitizer) +extern "C" void __tsan_acquire(void*); +extern "C" void __tsan_release(void*); +#else +#define __tsan_acquire(addr) ((void)0) +#define __tsan_release(addr) ((void)0) +#endif namespace __cxxabiv1 { // Use an anonymous namespace to ensure that the tests and actual implementation @@ -116,7 +123,7 @@ constexpr uint32_t (*PlatformThreadID)() = nullptr; #endif -constexpr bool DoesPlatformSupportThreadID() { +constexpr bool PlatformSupportsThreadID() { #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wtautological-pointer-compare" @@ -265,7 +272,7 @@ struct InitByteGlobalMutex explicit InitByteGlobalMutex(uint32_t *g) : BaseT(g), has_thread_id_support(false) {} explicit InitByteGlobalMutex(uint64_t *g) - : BaseT(g), has_thread_id_support(DoesPlatformSupportThreadID()) {} + : BaseT(g), has_thread_id_support(PlatformSupportsThreadID()) {} public: AcquireResult acquire_init_byte() { @@ -358,9 +365,11 @@ private: void PlatformFutexWait(int* addr, int expect) { constexpr int WAIT = 0; syscall(SYS_futex, addr, WAIT, expect, 0); + __tsan_acquire(addr); } void PlatformFutexWake(int* addr) { constexpr int WAKE = 1; + __tsan_release(addr); syscall(SYS_futex, addr, WAKE, INT_MAX); } #else @@ -368,7 +377,7 @@ constexpr void (*PlatformFutexWait)(int*, int) = nullptr; constexpr void (*PlatformFutexWake)(int*) = nullptr; #endif -constexpr bool DoesPlatformSupportFutex() { +constexpr bool PlatformSupportsFutex() { #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wtautological-pointer-compare" @@ -539,7 +548,7 @@ constexpr Implementation CurrentImplementation = #endif static_assert(CurrentImplementation != Implementation::Futex - || DoesPlatformSupportFutex(), "Futex selected but not supported"); + || PlatformSupportsFutex(), "Futex selected but not supported"); using SelectedImplementation = SelectImplementation<CurrentImplementation>::type; diff --git a/test/guard_test_basic.pass.cpp b/test/guard_test_basic.pass.cpp index 5f1576d..b0dd41f 100644 --- a/test/guard_test_basic.pass.cpp +++ b/test/guard_test_basic.pass.cpp @@ -129,7 +129,7 @@ int main() { #if defined(__APPLE__) || defined(__linux__) assert(PlatformThreadID); #endif - if (+PlatformThreadID) { + if (PlatformSupportsThreadID()) { assert(PlatformThreadID() != 0); assert(PlatformThreadID() == PlatformThreadID()); } diff --git a/test/guard_threaded_test.pass.cpp b/test/guard_threaded_test.pass.cpp index e38e132..e46af56 100644 --- a/test/guard_threaded_test.pass.cpp +++ b/test/guard_threaded_test.pass.cpp @@ -356,14 +356,14 @@ void test_impl() { } } -int main() { +void test_all_impls() { using MutexImpl = SelectImplementation<Implementation::GlobalLock>::type; // Attempt to test the Futex based implementation if it's supported on the // target platform. using RealFutexImpl = SelectImplementation<Implementation::Futex>::type; using FutexImpl = typename std::conditional< - DoesPlatformSupportFutex(), + PlatformSupportsFutex(), RealFutexImpl, MutexImpl >::type; @@ -372,7 +372,48 @@ int main() { const int num_runs = 5; for (int i=0; i < num_runs; ++i) { test_impl<MutexImpl>(); - if (DoesPlatformSupportFutex()) + if (PlatformSupportsFutex()) test_impl<FutexImpl>(); } } + +// A dummy +template <bool Dummy = true> +void test_futex_syscall() { + if (!PlatformSupportsFutex()) + return; + int lock1 = 0; + int lock2 = 0; + int lock3 = 0; + std::thread waiter1([&]() { + int expect = 0; + PlatformFutexWait(&lock1, expect); + assert(lock1 == 1); + }); + std::thread waiter2([&]() { + int expect = 0; + PlatformFutexWait(&lock2, expect); + assert(lock2 == 2); + }); + std::thread waiter3([&]() { + int expect = 42; // not the value + PlatformFutexWait(&lock3, expect); // doesn't block + }); + std::thread waker([&]() { + lock1 = 1; + PlatformFutexWake(&lock1); + lock2 = 2; + PlatformFutexWake(&lock2); + }); + waiter1.join(); + waiter2.join(); + waiter3.join(); + waker.join(); +} + +int main() { + // Test each multi-threaded implementation with real threads. + test_all_impls(); + // Test the basic sanity of the futex syscall wrappers. + test_futex_syscall(); +} |