diff --git a/llvm/include/llvm/Support/RWMutex.h b/llvm/include/llvm/Support/RWMutex.h index 32987c3b98f1c..8d221aaab9ab9 100644 --- a/llvm/include/llvm/Support/RWMutex.h +++ b/llvm/include/llvm/Support/RWMutex.h @@ -63,6 +63,10 @@ class RWMutexImpl { /// Unconditionally release the lock in reader mode. bool unlock_shared(); + /// Attempts to acquire the lock in reader mode. Returns immediately. + /// @returns true on successful lock acquisition, false otherwise. + bool try_lock_shared(); + /// Attempts to unconditionally acquire the lock in reader mode. If the /// lock is held by any readers, this method will wait until it can /// acquire the lock. @@ -75,6 +79,10 @@ class RWMutexImpl { /// Unconditionally release the lock in write mode. bool unlock(); + /// Attempts to acquire the lock in writer mode. Returns immediately. + /// @returns true on successful lock acquisition, false otherwise. + bool try_lock(); + //@} /// @name Platform Dependent Data /// @{ @@ -123,6 +131,8 @@ template class SmartRWMutex { return true; } + bool try_lock_shared() { return impl.try_lock_shared(); } + bool lock() { if (!mt_only || llvm_is_multithreaded()) { impl.lock(); @@ -148,6 +158,8 @@ template class SmartRWMutex { --writers; return true; } + + bool try_lock() { return impl.try_lock(); } }; typedef SmartRWMutex RWMutex; diff --git a/llvm/lib/Support/RWMutex.cpp b/llvm/lib/Support/RWMutex.cpp index 5accf73e5f940..d6fa956da634d 100644 --- a/llvm/lib/Support/RWMutex.cpp +++ b/llvm/lib/Support/RWMutex.cpp @@ -26,8 +26,10 @@ RWMutexImpl::~RWMutexImpl() = default; bool RWMutexImpl::lock_shared() { return true; } bool RWMutexImpl::unlock_shared() { return true; } +bool RWMutexImpl::try_lock_shared() { return true; } bool RWMutexImpl::lock() { return true; } bool RWMutexImpl::unlock() { return true; } +bool RWMutexImpl::try_lock() { return true; } #else @@ -87,6 +89,14 @@ RWMutexImpl::unlock_shared() return errorcode == 0; } +bool RWMutexImpl::try_lock_shared() { + pthread_rwlock_t *rwlock = static_cast(data_); + assert(rwlock != nullptr); + + int errorcode = pthread_rwlock_tryrdlock(rwlock); + return errorcode == 0; +} + bool RWMutexImpl::lock() { @@ -107,6 +117,14 @@ RWMutexImpl::unlock() return errorcode == 0; } +bool RWMutexImpl::try_lock() { + pthread_rwlock_t *rwlock = static_cast(data_); + assert(rwlock != nullptr); + + int errorcode = pthread_rwlock_trywrlock(rwlock); + return errorcode == 0; +} + #else RWMutexImpl::RWMutexImpl() : data_(new MutexImpl(false)) { } @@ -123,6 +141,10 @@ bool RWMutexImpl::unlock_shared() { return static_cast(data_)->release(); } +bool RWMutexImpl::try_lock_shared() { + return static_cast(data_)->tryacquire(); +} + bool RWMutexImpl::lock() { return static_cast(data_)->acquire(); } @@ -131,6 +153,10 @@ bool RWMutexImpl::unlock() { return static_cast(data_)->release(); } +bool RWMutexImpl::try_lock() { + return static_cast(data_)->tryacquire(); +} + #endif #endif #endif