sanitizer_common: add Mutex::TryLock
authorDmitry Vyukov <dvyukov@google.com>
Fri, 1 Apr 2022 14:30:55 +0000 (16:30 +0200)
committerDmitry Vyukov <dvyukov@google.com>
Fri, 1 Apr 2022 15:56:19 +0000 (17:56 +0200)
Will be used in future changes.

Reviewed By: melver

Differential Revision: https://reviews.llvm.org/D122905

compiler-rt/lib/sanitizer_common/sanitizer_mutex.h
compiler-rt/lib/sanitizer_common/tests/sanitizer_mutex_test.cpp

index c16f5cd..d2188a9 100644 (file)
@@ -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;
index 9955d76..9604276 100644 (file)
@@ -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<Mutex> data(&mtx);
+  pthread_t threads[kThreads];
+  for (int i = 0; i < kThreads; i++)
+    PTHREAD_CREATE(&threads[i], 0, try_thread<Mutex>, &data);
+  for (int i = 0; i < kThreads; i++) PTHREAD_JOIN(threads[i], 0);
+}
+
 struct SemaphoreData {
   Semaphore *sem;
   bool done;