From ea624e697bbe1d2924b69208102c64c4c01e1400 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Fri, 1 Apr 2022 16:30:55 +0200 Subject: [PATCH] sanitizer_common: add Mutex::TryLock Will be used in future changes. Reviewed By: melver Differential Revision: https://reviews.llvm.org/D122905 --- compiler-rt/lib/sanitizer_common/sanitizer_mutex.h | 14 ++++++++++++++ .../lib/sanitizer_common/tests/sanitizer_mutex_test.cpp | 9 +++++++++ 2 files changed, 23 insertions(+) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_mutex.h b/compiler-rt/lib/sanitizer_common/sanitizer_mutex.h index c16f5cd..d2188a9 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_mutex.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_mutex.h @@ -208,6 +208,20 @@ class SANITIZER_MUTEX Mutex : CheckedMutex { } } + bool TryLock() SANITIZER_TRY_ACQUIRE(true) { + u64 state = atomic_load_relaxed(&state_); + for (;;) { + if (UNLIKELY(state & (kWriterLock | kReaderLockMask))) + return false; + // The mutex is not read-/write-locked, try to lock. + if (LIKELY(atomic_compare_exchange_weak( + &state_, &state, state | kWriterLock, memory_order_acquire))) { + CheckedMutex::Lock(); + return true; + } + } + } + void Unlock() SANITIZER_RELEASE() { CheckedMutex::Unlock(); bool wake_writer; diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_mutex_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_mutex_test.cpp index 9955d76..9604276 100644 --- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_mutex_test.cpp +++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_mutex_test.cpp @@ -155,6 +155,15 @@ TEST(SanitizerCommon, Mutex) { for (int i = 0; i < kThreads; i++) PTHREAD_JOIN(threads[i], 0); } +TEST(SanitizerCommon, MutexTry) { + Mutex mtx; + TestData data(&mtx); + pthread_t threads[kThreads]; + for (int i = 0; i < kThreads; i++) + PTHREAD_CREATE(&threads[i], 0, try_thread, &data); + for (int i = 0; i < kThreads; i++) PTHREAD_JOIN(threads[i], 0); +} + struct SemaphoreData { Semaphore *sem; bool done; -- 2.7.4