summaryrefslogtreecommitdiff
path: root/runtime/base/mutex.h
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/base/mutex.h')
-rw-r--r--runtime/base/mutex.h28
1 files changed, 22 insertions, 6 deletions
diff --git a/runtime/base/mutex.h b/runtime/base/mutex.h
index 87e9525557..dc9b885bf7 100644
--- a/runtime/base/mutex.h
+++ b/runtime/base/mutex.h
@@ -103,10 +103,11 @@ class BaseMutex {
BaseMutex(const char* name, LockLevel level);
virtual ~BaseMutex();
- // Add this mutex to those owned by self, and perform appropriate checking.
- // For this call only, self may also be another suspended thread.
- void RegisterAsLocked(Thread* self);
- void RegisterAsLockedImpl(Thread* self, LockLevel level);
+ // Add this mutex to those owned by self, and optionally perform lock order checking. Caller
+ // may wish to disable checking for trylock calls that cannot result in deadlock. For this call
+ // only, self may also be another suspended thread.
+ void RegisterAsLocked(Thread* self, bool check = kDebugLocking);
+ void RegisterAsLockedImpl(Thread* self, LockLevel level, bool check);
void RegisterAsUnlocked(Thread* self);
void RegisterAsUnlockedImpl(Thread* self, LockLevel level);
@@ -183,7 +184,10 @@ class LOCKABLE Mutex : public BaseMutex {
void ExclusiveLock(Thread* self) ACQUIRE();
void Lock(Thread* self) ACQUIRE() { ExclusiveLock(self); }
- // Returns true if acquires exclusive access, false otherwise.
+ // Returns true if acquires exclusive access, false otherwise. The `check` argument specifies
+ // whether lock level checking should be performed. Should be defaulted unless we are using
+ // TryLock instead of Lock for deadlock avoidance.
+ template <bool kCheck = kDebugLocking>
bool ExclusiveTryLock(Thread* self) TRY_ACQUIRE(true);
bool TryLock(Thread* self) TRY_ACQUIRE(true) { return ExclusiveTryLock(self); }
// Equivalent to ExclusiveTryLock, but retry for a short period before giving up.
@@ -342,7 +346,7 @@ class SHARED_LOCKABLE ReaderWriterMutex : public BaseMutex {
void ReaderLock(Thread* self) ACQUIRE_SHARED() { SharedLock(self); }
// Try to acquire share of ReaderWriterMutex.
- bool SharedTryLock(Thread* self) SHARED_TRYLOCK_FUNCTION(true);
+ bool SharedTryLock(Thread* self, bool check = kDebugLocking) SHARED_TRYLOCK_FUNCTION(true);
// Release a share of the access.
void SharedUnlock(Thread* self) RELEASE_SHARED() ALWAYS_INLINE;
@@ -520,6 +524,18 @@ class SCOPED_CAPABILITY MutexLock {
DISALLOW_COPY_AND_ASSIGN(MutexLock);
};
+// Pretend to acquire a mutex for checking purposes, without actually doing so. Use with
+// extreme caution when it is known the condition that the mutex would guard against cannot arise.
+class SCOPED_CAPABILITY FakeMutexLock {
+ public:
+ explicit FakeMutexLock(Mutex& mu) ACQUIRE(mu) NO_THREAD_SAFETY_ANALYSIS {}
+
+ ~FakeMutexLock() RELEASE() NO_THREAD_SAFETY_ANALYSIS {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(FakeMutexLock);
+};
+
// Scoped locker/unlocker for a ReaderWriterMutex that acquires read access to mu upon
// construction and releases it upon destruction.
class SCOPED_CAPABILITY ReaderMutexLock {