diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_mutex.h b/compiler-rt/lib/sanitizer_common/sanitizer_mutex.h --- a/compiler-rt/lib/sanitizer_common/sanitizer_mutex.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_mutex.h @@ -208,6 +208,20 @@ } } + 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 --- 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 @@ 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;