summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Fiselier <eric@efcs.ca>2021-06-09 21:17:56 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2021-06-09 21:17:56 +0000
commitdde880b5d29dd20ff601c58f3a67b95332e2469d (patch)
treec3ecd9b890fcfbd577d7321c790323867c1848de
parented4e8619a4ca644b2a496bbf78f5c1cfe8bf51fb (diff)
parent7be8fdb50c3e36daac46add51be848bf75a3b572 (diff)
downloadlibcxxabi-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.h17
-rw-r--r--test/guard_test_basic.pass.cpp2
-rw-r--r--test/guard_threaded_test.pass.cpp47
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();
+}