1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2011 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker #ifndef ART_RUNTIME_BASE_MUTEX_H_ 18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_BASE_MUTEX_H_ 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker #include <limits.h> // for INT_MAX 21*795d594fSAndroid Build Coastguard Worker #include <pthread.h> 22*795d594fSAndroid Build Coastguard Worker #include <stdint.h> 23*795d594fSAndroid Build Coastguard Worker #include <unistd.h> // for pid_t 24*795d594fSAndroid Build Coastguard Worker 25*795d594fSAndroid Build Coastguard Worker #include <iosfwd> 26*795d594fSAndroid Build Coastguard Worker #include <string> 27*795d594fSAndroid Build Coastguard Worker 28*795d594fSAndroid Build Coastguard Worker #include <android-base/logging.h> 29*795d594fSAndroid Build Coastguard Worker 30*795d594fSAndroid Build Coastguard Worker #include "base/aborting.h" 31*795d594fSAndroid Build Coastguard Worker #include "base/atomic.h" 32*795d594fSAndroid Build Coastguard Worker #include "runtime_globals.h" 33*795d594fSAndroid Build Coastguard Worker #include "base/macros.h" 34*795d594fSAndroid Build Coastguard Worker #include "locks.h" 35*795d594fSAndroid Build Coastguard Worker 36*795d594fSAndroid Build Coastguard Worker #if defined(__linux__) 37*795d594fSAndroid Build Coastguard Worker #define ART_USE_FUTEXES 1 38*795d594fSAndroid Build Coastguard Worker #else 39*795d594fSAndroid Build Coastguard Worker #define ART_USE_FUTEXES 0 40*795d594fSAndroid Build Coastguard Worker #endif 41*795d594fSAndroid Build Coastguard Worker 42*795d594fSAndroid Build Coastguard Worker // Currently Darwin doesn't support locks with timeouts. 43*795d594fSAndroid Build Coastguard Worker #if !defined(__APPLE__) 44*795d594fSAndroid Build Coastguard Worker #define HAVE_TIMED_RWLOCK 1 45*795d594fSAndroid Build Coastguard Worker #else 46*795d594fSAndroid Build Coastguard Worker #define HAVE_TIMED_RWLOCK 0 47*795d594fSAndroid Build Coastguard Worker #endif 48*795d594fSAndroid Build Coastguard Worker 49*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN { 50*795d594fSAndroid Build Coastguard Worker 51*795d594fSAndroid Build Coastguard Worker class SHARED_LOCKABLE ReaderWriterMutex; 52*795d594fSAndroid Build Coastguard Worker class SHARED_LOCKABLE MutatorMutex; 53*795d594fSAndroid Build Coastguard Worker class ScopedContentionRecorder; 54*795d594fSAndroid Build Coastguard Worker class Thread; 55*795d594fSAndroid Build Coastguard Worker class LOCKABLE Mutex; 56*795d594fSAndroid Build Coastguard Worker 57*795d594fSAndroid Build Coastguard Worker constexpr bool kDebugLocking = kIsDebugBuild; 58*795d594fSAndroid Build Coastguard Worker 59*795d594fSAndroid Build Coastguard Worker // Record Log contention information, dumpable via SIGQUIT. 60*795d594fSAndroid Build Coastguard Worker #if ART_USE_FUTEXES 61*795d594fSAndroid Build Coastguard Worker // To enable lock contention logging, set this to true. 62*795d594fSAndroid Build Coastguard Worker constexpr bool kLogLockContentions = false; 63*795d594fSAndroid Build Coastguard Worker // FUTEX_WAKE first argument: 64*795d594fSAndroid Build Coastguard Worker constexpr int kWakeOne = 1; 65*795d594fSAndroid Build Coastguard Worker constexpr int kWakeAll = INT_MAX; 66*795d594fSAndroid Build Coastguard Worker #else 67*795d594fSAndroid Build Coastguard Worker // Keep this false as lock contention logging is supported only with 68*795d594fSAndroid Build Coastguard Worker // futex. 69*795d594fSAndroid Build Coastguard Worker constexpr bool kLogLockContentions = false; 70*795d594fSAndroid Build Coastguard Worker #endif 71*795d594fSAndroid Build Coastguard Worker constexpr size_t kContentionLogSize = 4; 72*795d594fSAndroid Build Coastguard Worker constexpr size_t kContentionLogDataSize = kLogLockContentions ? 1 : 0; 73*795d594fSAndroid Build Coastguard Worker constexpr size_t kAllMutexDataSize = kLogLockContentions ? 1 : 0; 74*795d594fSAndroid Build Coastguard Worker 75*795d594fSAndroid Build Coastguard Worker // Base class for all Mutex implementations 76*795d594fSAndroid Build Coastguard Worker class BaseMutex { 77*795d594fSAndroid Build Coastguard Worker public: GetName()78*795d594fSAndroid Build Coastguard Worker const char* GetName() const { 79*795d594fSAndroid Build Coastguard Worker return name_; 80*795d594fSAndroid Build Coastguard Worker } 81*795d594fSAndroid Build Coastguard Worker IsMutex()82*795d594fSAndroid Build Coastguard Worker virtual bool IsMutex() const { return false; } IsReaderWriterMutex()83*795d594fSAndroid Build Coastguard Worker virtual bool IsReaderWriterMutex() const { return false; } IsMutatorMutex()84*795d594fSAndroid Build Coastguard Worker virtual bool IsMutatorMutex() const { return false; } 85*795d594fSAndroid Build Coastguard Worker 86*795d594fSAndroid Build Coastguard Worker virtual void Dump(std::ostream& os) const = 0; 87*795d594fSAndroid Build Coastguard Worker 88*795d594fSAndroid Build Coastguard Worker static void DumpAll(std::ostream& os); 89*795d594fSAndroid Build Coastguard Worker ShouldRespondToEmptyCheckpointRequest()90*795d594fSAndroid Build Coastguard Worker bool ShouldRespondToEmptyCheckpointRequest() const { 91*795d594fSAndroid Build Coastguard Worker return should_respond_to_empty_checkpoint_request_; 92*795d594fSAndroid Build Coastguard Worker } 93*795d594fSAndroid Build Coastguard Worker SetShouldRespondToEmptyCheckpointRequest(bool value)94*795d594fSAndroid Build Coastguard Worker void SetShouldRespondToEmptyCheckpointRequest(bool value) { 95*795d594fSAndroid Build Coastguard Worker should_respond_to_empty_checkpoint_request_ = value; 96*795d594fSAndroid Build Coastguard Worker } 97*795d594fSAndroid Build Coastguard Worker 98*795d594fSAndroid Build Coastguard Worker virtual void WakeupToRespondToEmptyCheckpoint() = 0; 99*795d594fSAndroid Build Coastguard Worker 100*795d594fSAndroid Build Coastguard Worker protected: 101*795d594fSAndroid Build Coastguard Worker friend class ConditionVariable; 102*795d594fSAndroid Build Coastguard Worker 103*795d594fSAndroid Build Coastguard Worker BaseMutex(const char* name, LockLevel level); 104*795d594fSAndroid Build Coastguard Worker virtual ~BaseMutex(); 105*795d594fSAndroid Build Coastguard Worker 106*795d594fSAndroid Build Coastguard Worker // Add this mutex to those owned by self, and optionally perform lock order checking. Caller 107*795d594fSAndroid Build Coastguard Worker // may wish to disable checking for trylock calls that cannot result in deadlock. For this call 108*795d594fSAndroid Build Coastguard Worker // only, self may also be another suspended thread. 109*795d594fSAndroid Build Coastguard Worker void RegisterAsLocked(Thread* self, bool check = kDebugLocking); 110*795d594fSAndroid Build Coastguard Worker void RegisterAsLockedImpl(Thread* self, LockLevel level, bool check); 111*795d594fSAndroid Build Coastguard Worker 112*795d594fSAndroid Build Coastguard Worker void RegisterAsUnlocked(Thread* self); 113*795d594fSAndroid Build Coastguard Worker void RegisterAsUnlockedImpl(Thread* self, LockLevel level); 114*795d594fSAndroid Build Coastguard Worker 115*795d594fSAndroid Build Coastguard Worker void CheckSafeToWait(Thread* self); 116*795d594fSAndroid Build Coastguard Worker 117*795d594fSAndroid Build Coastguard Worker friend class ScopedContentionRecorder; 118*795d594fSAndroid Build Coastguard Worker 119*795d594fSAndroid Build Coastguard Worker void RecordContention(uint64_t blocked_tid, uint64_t owner_tid, uint64_t nano_time_blocked); 120*795d594fSAndroid Build Coastguard Worker void DumpContention(std::ostream& os) const; 121*795d594fSAndroid Build Coastguard Worker 122*795d594fSAndroid Build Coastguard Worker const char* const name_; 123*795d594fSAndroid Build Coastguard Worker 124*795d594fSAndroid Build Coastguard Worker // A log entry that records contention but makes no guarantee that either tid will be held live. 125*795d594fSAndroid Build Coastguard Worker struct ContentionLogEntry { ContentionLogEntryContentionLogEntry126*795d594fSAndroid Build Coastguard Worker ContentionLogEntry() : blocked_tid(0), owner_tid(0) {} 127*795d594fSAndroid Build Coastguard Worker uint64_t blocked_tid; 128*795d594fSAndroid Build Coastguard Worker uint64_t owner_tid; 129*795d594fSAndroid Build Coastguard Worker AtomicInteger count; 130*795d594fSAndroid Build Coastguard Worker }; 131*795d594fSAndroid Build Coastguard Worker struct ContentionLogData { 132*795d594fSAndroid Build Coastguard Worker ContentionLogEntry contention_log[kContentionLogSize]; 133*795d594fSAndroid Build Coastguard Worker // The next entry in the contention log to be updated. Value ranges from 0 to 134*795d594fSAndroid Build Coastguard Worker // kContentionLogSize - 1. 135*795d594fSAndroid Build Coastguard Worker AtomicInteger cur_content_log_entry; 136*795d594fSAndroid Build Coastguard Worker // Number of times the Mutex has been contended. 137*795d594fSAndroid Build Coastguard Worker AtomicInteger contention_count; 138*795d594fSAndroid Build Coastguard Worker // Sum of time waited by all contenders in ns. 139*795d594fSAndroid Build Coastguard Worker Atomic<uint64_t> wait_time; 140*795d594fSAndroid Build Coastguard Worker void AddToWaitTime(uint64_t value); ContentionLogDataContentionLogData141*795d594fSAndroid Build Coastguard Worker ContentionLogData() : wait_time(0) {} 142*795d594fSAndroid Build Coastguard Worker }; 143*795d594fSAndroid Build Coastguard Worker ContentionLogData contention_log_data_[kContentionLogDataSize]; 144*795d594fSAndroid Build Coastguard Worker 145*795d594fSAndroid Build Coastguard Worker const LockLevel level_; // Support for lock hierarchy. 146*795d594fSAndroid Build Coastguard Worker bool should_respond_to_empty_checkpoint_request_; 147*795d594fSAndroid Build Coastguard Worker 148*795d594fSAndroid Build Coastguard Worker public: HasEverContended()149*795d594fSAndroid Build Coastguard Worker bool HasEverContended() const { 150*795d594fSAndroid Build Coastguard Worker if (kLogLockContentions) { 151*795d594fSAndroid Build Coastguard Worker return contention_log_data_->contention_count.load(std::memory_order_seq_cst) > 0; 152*795d594fSAndroid Build Coastguard Worker } 153*795d594fSAndroid Build Coastguard Worker return false; 154*795d594fSAndroid Build Coastguard Worker } 155*795d594fSAndroid Build Coastguard Worker }; 156*795d594fSAndroid Build Coastguard Worker 157*795d594fSAndroid Build Coastguard Worker // A Mutex is used to achieve mutual exclusion between threads. A Mutex can be used to gain 158*795d594fSAndroid Build Coastguard Worker // exclusive access to what it guards. A Mutex can be in one of two states: 159*795d594fSAndroid Build Coastguard Worker // - Free - not owned by any thread, 160*795d594fSAndroid Build Coastguard Worker // - Exclusive - owned by a single thread. 161*795d594fSAndroid Build Coastguard Worker // 162*795d594fSAndroid Build Coastguard Worker // The effect of locking and unlocking operations on the state is: 163*795d594fSAndroid Build Coastguard Worker // State | ExclusiveLock | ExclusiveUnlock 164*795d594fSAndroid Build Coastguard Worker // ------------------------------------------- 165*795d594fSAndroid Build Coastguard Worker // Free | Exclusive | error 166*795d594fSAndroid Build Coastguard Worker // Exclusive | Block* | Free 167*795d594fSAndroid Build Coastguard Worker // * Mutex is not reentrant unless recursive is true. An attempt to ExclusiveLock on a 168*795d594fSAndroid Build Coastguard Worker // recursive=false Mutex on a thread already owning the Mutex results in an error. 169*795d594fSAndroid Build Coastguard Worker // 170*795d594fSAndroid Build Coastguard Worker // TODO(b/140590186): Remove support for recursive == true. 171*795d594fSAndroid Build Coastguard Worker // 172*795d594fSAndroid Build Coastguard Worker // Some mutexes, including those associated with Java monitors may be accessed (in particular 173*795d594fSAndroid Build Coastguard Worker // acquired) by a thread in suspended state. Suspending all threads does NOT prevent mutex state 174*795d594fSAndroid Build Coastguard Worker // from changing. 175*795d594fSAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& os, const Mutex& mu); 176*795d594fSAndroid Build Coastguard Worker class EXPORT LOCKABLE Mutex : public BaseMutex { 177*795d594fSAndroid Build Coastguard Worker public: 178*795d594fSAndroid Build Coastguard Worker explicit Mutex(const char* name, LockLevel level = kDefaultMutexLevel, bool recursive = false); 179*795d594fSAndroid Build Coastguard Worker ~Mutex(); 180*795d594fSAndroid Build Coastguard Worker IsMutex()181*795d594fSAndroid Build Coastguard Worker bool IsMutex() const override { return true; } 182*795d594fSAndroid Build Coastguard Worker 183*795d594fSAndroid Build Coastguard Worker // Block until mutex is free then acquire exclusive access. 184*795d594fSAndroid Build Coastguard Worker void ExclusiveLock(Thread* self) ACQUIRE(); Lock(Thread * self)185*795d594fSAndroid Build Coastguard Worker void Lock(Thread* self) ACQUIRE() { ExclusiveLock(self); } 186*795d594fSAndroid Build Coastguard Worker 187*795d594fSAndroid Build Coastguard Worker // Returns true if acquires exclusive access, false otherwise. The `check` argument specifies 188*795d594fSAndroid Build Coastguard Worker // whether lock level checking should be performed. Should be defaulted unless we are using 189*795d594fSAndroid Build Coastguard Worker // TryLock instead of Lock for deadlock avoidance. 190*795d594fSAndroid Build Coastguard Worker template <bool kCheck = kDebugLocking> 191*795d594fSAndroid Build Coastguard Worker bool ExclusiveTryLock(Thread* self) TRY_ACQUIRE(true); TryLock(Thread * self)192*795d594fSAndroid Build Coastguard Worker bool TryLock(Thread* self) TRY_ACQUIRE(true) { return ExclusiveTryLock(self); } 193*795d594fSAndroid Build Coastguard Worker // Equivalent to ExclusiveTryLock, but retry for a short period before giving up. 194*795d594fSAndroid Build Coastguard Worker bool ExclusiveTryLockWithSpinning(Thread* self) TRY_ACQUIRE(true); 195*795d594fSAndroid Build Coastguard Worker 196*795d594fSAndroid Build Coastguard Worker // Release exclusive access. 197*795d594fSAndroid Build Coastguard Worker void ExclusiveUnlock(Thread* self) RELEASE(); Unlock(Thread * self)198*795d594fSAndroid Build Coastguard Worker void Unlock(Thread* self) RELEASE() { ExclusiveUnlock(self); } 199*795d594fSAndroid Build Coastguard Worker 200*795d594fSAndroid Build Coastguard Worker // Is the current thread the exclusive holder of the Mutex. 201*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE bool IsExclusiveHeld(const Thread* self) const; 202*795d594fSAndroid Build Coastguard Worker 203*795d594fSAndroid Build Coastguard Worker // Assert that the Mutex is exclusively held by the current thread. 204*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE void AssertExclusiveHeld(const Thread* self) const ASSERT_CAPABILITY(this); 205*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE void AssertHeld(const Thread* self) const ASSERT_CAPABILITY(this); 206*795d594fSAndroid Build Coastguard Worker 207*795d594fSAndroid Build Coastguard Worker // Assert that the Mutex is not held by the current thread. AssertNotHeldExclusive(const Thread * self)208*795d594fSAndroid Build Coastguard Worker void AssertNotHeldExclusive(const Thread* self) ASSERT_CAPABILITY(!*this) { 209*795d594fSAndroid Build Coastguard Worker if (kDebugLocking && (gAborting == 0)) { 210*795d594fSAndroid Build Coastguard Worker CHECK(!IsExclusiveHeld(self)) << *this; 211*795d594fSAndroid Build Coastguard Worker } 212*795d594fSAndroid Build Coastguard Worker } AssertNotHeld(const Thread * self)213*795d594fSAndroid Build Coastguard Worker void AssertNotHeld(const Thread* self) ASSERT_CAPABILITY(!*this) { 214*795d594fSAndroid Build Coastguard Worker AssertNotHeldExclusive(self); 215*795d594fSAndroid Build Coastguard Worker } 216*795d594fSAndroid Build Coastguard Worker 217*795d594fSAndroid Build Coastguard Worker // Id associated with exclusive owner. No memory ordering semantics if called from a thread 218*795d594fSAndroid Build Coastguard Worker // other than the owner. GetTid() == GetExclusiveOwnerTid() is a reliable way to determine 219*795d594fSAndroid Build Coastguard Worker // whether we hold the lock; any other information may be invalidated before we return. 220*795d594fSAndroid Build Coastguard Worker pid_t GetExclusiveOwnerTid() const; 221*795d594fSAndroid Build Coastguard Worker 222*795d594fSAndroid Build Coastguard Worker // Returns how many times this Mutex has been locked, it is typically better to use 223*795d594fSAndroid Build Coastguard Worker // AssertHeld/NotHeld. For a simply held mutex this method returns 1. Should only be called 224*795d594fSAndroid Build Coastguard Worker // while holding the mutex or threads are suspended. GetDepth()225*795d594fSAndroid Build Coastguard Worker unsigned int GetDepth() const { 226*795d594fSAndroid Build Coastguard Worker return recursion_count_; 227*795d594fSAndroid Build Coastguard Worker } 228*795d594fSAndroid Build Coastguard Worker 229*795d594fSAndroid Build Coastguard Worker void Dump(std::ostream& os) const override; 230*795d594fSAndroid Build Coastguard Worker 231*795d594fSAndroid Build Coastguard Worker void DumpStack(Thread *self, uint64_t wait_start_ms, uint64_t try_times = 1); 232*795d594fSAndroid Build Coastguard Worker 233*795d594fSAndroid Build Coastguard Worker static bool IsDumpFrequent(Thread *self, uint64_t try_times = 1); 234*795d594fSAndroid Build Coastguard Worker setEnableMonitorTimeout()235*795d594fSAndroid Build Coastguard Worker void setEnableMonitorTimeout() { 236*795d594fSAndroid Build Coastguard Worker enable_monitor_timeout_ = true; 237*795d594fSAndroid Build Coastguard Worker } 238*795d594fSAndroid Build Coastguard Worker setMonitorId(uint32_t monitorId)239*795d594fSAndroid Build Coastguard Worker void setMonitorId(uint32_t monitorId) { 240*795d594fSAndroid Build Coastguard Worker monitor_id_ = monitorId; 241*795d594fSAndroid Build Coastguard Worker } 242*795d594fSAndroid Build Coastguard Worker 243*795d594fSAndroid Build Coastguard Worker // For negative capabilities in clang annotations. 244*795d594fSAndroid Build Coastguard Worker const Mutex& operator!() const { return *this; } 245*795d594fSAndroid Build Coastguard Worker 246*795d594fSAndroid Build Coastguard Worker void WakeupToRespondToEmptyCheckpoint() override; 247*795d594fSAndroid Build Coastguard Worker 248*795d594fSAndroid Build Coastguard Worker #if ART_USE_FUTEXES 249*795d594fSAndroid Build Coastguard Worker // Acquire the mutex, possibly on behalf of another thread. Acquisition must be 250*795d594fSAndroid Build Coastguard Worker // uncontended. New_owner must be current thread or suspended. 251*795d594fSAndroid Build Coastguard Worker // Mutex must be at level kMonitorLock. 252*795d594fSAndroid Build Coastguard Worker // Not implementable for the pthreads version, so we must avoid calling it there. 253*795d594fSAndroid Build Coastguard Worker void ExclusiveLockUncontendedFor(Thread* new_owner); 254*795d594fSAndroid Build Coastguard Worker 255*795d594fSAndroid Build Coastguard Worker // Undo the effect of the previous calling, setting the mutex back to unheld. 256*795d594fSAndroid Build Coastguard Worker // Still assumes no concurrent access. 257*795d594fSAndroid Build Coastguard Worker void ExclusiveUnlockUncontended(); 258*795d594fSAndroid Build Coastguard Worker #endif // ART_USE_FUTEXES 259*795d594fSAndroid Build Coastguard Worker 260*795d594fSAndroid Build Coastguard Worker private: 261*795d594fSAndroid Build Coastguard Worker #if ART_USE_FUTEXES 262*795d594fSAndroid Build Coastguard Worker // Low order bit: 0 is unheld, 1 is held. 263*795d594fSAndroid Build Coastguard Worker // High order bits: Number of waiting contenders. 264*795d594fSAndroid Build Coastguard Worker AtomicInteger state_and_contenders_; 265*795d594fSAndroid Build Coastguard Worker 266*795d594fSAndroid Build Coastguard Worker static constexpr int32_t kHeldMask = 1; 267*795d594fSAndroid Build Coastguard Worker 268*795d594fSAndroid Build Coastguard Worker static constexpr int32_t kContenderShift = 1; 269*795d594fSAndroid Build Coastguard Worker 270*795d594fSAndroid Build Coastguard Worker static constexpr int32_t kContenderIncrement = 1 << kContenderShift; 271*795d594fSAndroid Build Coastguard Worker increment_contenders()272*795d594fSAndroid Build Coastguard Worker void increment_contenders() { 273*795d594fSAndroid Build Coastguard Worker state_and_contenders_.fetch_add(kContenderIncrement); 274*795d594fSAndroid Build Coastguard Worker } 275*795d594fSAndroid Build Coastguard Worker decrement_contenders()276*795d594fSAndroid Build Coastguard Worker void decrement_contenders() { 277*795d594fSAndroid Build Coastguard Worker state_and_contenders_.fetch_sub(kContenderIncrement); 278*795d594fSAndroid Build Coastguard Worker } 279*795d594fSAndroid Build Coastguard Worker get_contenders()280*795d594fSAndroid Build Coastguard Worker int32_t get_contenders() { 281*795d594fSAndroid Build Coastguard Worker // Result is guaranteed to include any contention added by this thread; otherwise approximate. 282*795d594fSAndroid Build Coastguard Worker // Treat contenders as unsigned because we're concerned about overflow; should never matter. 283*795d594fSAndroid Build Coastguard Worker return static_cast<uint32_t>(state_and_contenders_.load(std::memory_order_relaxed)) 284*795d594fSAndroid Build Coastguard Worker >> kContenderShift; 285*795d594fSAndroid Build Coastguard Worker } 286*795d594fSAndroid Build Coastguard Worker 287*795d594fSAndroid Build Coastguard Worker // Exclusive owner. 288*795d594fSAndroid Build Coastguard Worker Atomic<pid_t> exclusive_owner_; 289*795d594fSAndroid Build Coastguard Worker #else 290*795d594fSAndroid Build Coastguard Worker pthread_mutex_t mutex_; 291*795d594fSAndroid Build Coastguard Worker Atomic<pid_t> exclusive_owner_; // Guarded by mutex_. Asynchronous reads are OK. 292*795d594fSAndroid Build Coastguard Worker #endif 293*795d594fSAndroid Build Coastguard Worker 294*795d594fSAndroid Build Coastguard Worker unsigned int recursion_count_; 295*795d594fSAndroid Build Coastguard Worker const bool recursive_; // Can the lock be recursively held? 296*795d594fSAndroid Build Coastguard Worker 297*795d594fSAndroid Build Coastguard Worker bool enable_monitor_timeout_ = false; 298*795d594fSAndroid Build Coastguard Worker 299*795d594fSAndroid Build Coastguard Worker uint32_t monitor_id_; 300*795d594fSAndroid Build Coastguard Worker 301*795d594fSAndroid Build Coastguard Worker friend class ConditionVariable; 302*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(Mutex); 303*795d594fSAndroid Build Coastguard Worker }; 304*795d594fSAndroid Build Coastguard Worker 305*795d594fSAndroid Build Coastguard Worker // A ReaderWriterMutex is used to achieve mutual exclusion between threads, similar to a Mutex. 306*795d594fSAndroid Build Coastguard Worker // Unlike a Mutex a ReaderWriterMutex can be used to gain exclusive (writer) or shared (reader) 307*795d594fSAndroid Build Coastguard Worker // access to what it guards. A flaw in relation to a Mutex is that it cannot be used with a 308*795d594fSAndroid Build Coastguard Worker // condition variable. A ReaderWriterMutex can be in one of three states: 309*795d594fSAndroid Build Coastguard Worker // - Free - not owned by any thread, 310*795d594fSAndroid Build Coastguard Worker // - Exclusive - owned by a single thread, 311*795d594fSAndroid Build Coastguard Worker // - Shared(n) - shared amongst n threads. 312*795d594fSAndroid Build Coastguard Worker // 313*795d594fSAndroid Build Coastguard Worker // The effect of locking and unlocking operations on the state is: 314*795d594fSAndroid Build Coastguard Worker // 315*795d594fSAndroid Build Coastguard Worker // State | ExclusiveLock | ExclusiveUnlock | SharedLock | SharedUnlock 316*795d594fSAndroid Build Coastguard Worker // ---------------------------------------------------------------------------- 317*795d594fSAndroid Build Coastguard Worker // Free | Exclusive | error | SharedLock(1) | error 318*795d594fSAndroid Build Coastguard Worker // Exclusive | Block | Free | Block | error 319*795d594fSAndroid Build Coastguard Worker // Shared(n) | Block | error | SharedLock(n+1)* | Shared(n-1) or Free 320*795d594fSAndroid Build Coastguard Worker // * for large values of n the SharedLock may block. 321*795d594fSAndroid Build Coastguard Worker EXPORT std::ostream& operator<<(std::ostream& os, const ReaderWriterMutex& mu); 322*795d594fSAndroid Build Coastguard Worker class EXPORT SHARED_LOCKABLE ReaderWriterMutex : public BaseMutex { 323*795d594fSAndroid Build Coastguard Worker public: 324*795d594fSAndroid Build Coastguard Worker explicit ReaderWriterMutex(const char* name, LockLevel level = kDefaultMutexLevel); 325*795d594fSAndroid Build Coastguard Worker ~ReaderWriterMutex(); 326*795d594fSAndroid Build Coastguard Worker IsReaderWriterMutex()327*795d594fSAndroid Build Coastguard Worker bool IsReaderWriterMutex() const override { return true; } 328*795d594fSAndroid Build Coastguard Worker 329*795d594fSAndroid Build Coastguard Worker // Block until ReaderWriterMutex is free then acquire exclusive access. 330*795d594fSAndroid Build Coastguard Worker void ExclusiveLock(Thread* self) ACQUIRE(); WriterLock(Thread * self)331*795d594fSAndroid Build Coastguard Worker void WriterLock(Thread* self) ACQUIRE() { ExclusiveLock(self); } 332*795d594fSAndroid Build Coastguard Worker 333*795d594fSAndroid Build Coastguard Worker // Release exclusive access. 334*795d594fSAndroid Build Coastguard Worker void ExclusiveUnlock(Thread* self) RELEASE(); WriterUnlock(Thread * self)335*795d594fSAndroid Build Coastguard Worker void WriterUnlock(Thread* self) RELEASE() { ExclusiveUnlock(self); } 336*795d594fSAndroid Build Coastguard Worker 337*795d594fSAndroid Build Coastguard Worker // Block until ReaderWriterMutex is free and acquire exclusive access. Returns true on success 338*795d594fSAndroid Build Coastguard Worker // or false if timeout is reached. 339*795d594fSAndroid Build Coastguard Worker #if HAVE_TIMED_RWLOCK 340*795d594fSAndroid Build Coastguard Worker bool ExclusiveLockWithTimeout(Thread* self, int64_t ms, int32_t ns) 341*795d594fSAndroid Build Coastguard Worker EXCLUSIVE_TRYLOCK_FUNCTION(true); 342*795d594fSAndroid Build Coastguard Worker #endif 343*795d594fSAndroid Build Coastguard Worker 344*795d594fSAndroid Build Coastguard Worker // Block until ReaderWriterMutex is shared or free then acquire a share on the access. 345*795d594fSAndroid Build Coastguard Worker void SharedLock(Thread* self) ACQUIRE_SHARED() ALWAYS_INLINE; ReaderLock(Thread * self)346*795d594fSAndroid Build Coastguard Worker void ReaderLock(Thread* self) ACQUIRE_SHARED() { SharedLock(self); } 347*795d594fSAndroid Build Coastguard Worker 348*795d594fSAndroid Build Coastguard Worker // Try to acquire share of ReaderWriterMutex. 349*795d594fSAndroid Build Coastguard Worker bool SharedTryLock(Thread* self, bool check = kDebugLocking) SHARED_TRYLOCK_FUNCTION(true); 350*795d594fSAndroid Build Coastguard Worker 351*795d594fSAndroid Build Coastguard Worker // Release a share of the access. 352*795d594fSAndroid Build Coastguard Worker void SharedUnlock(Thread* self) RELEASE_SHARED() ALWAYS_INLINE; ReaderUnlock(Thread * self)353*795d594fSAndroid Build Coastguard Worker void ReaderUnlock(Thread* self) RELEASE_SHARED() { SharedUnlock(self); } 354*795d594fSAndroid Build Coastguard Worker 355*795d594fSAndroid Build Coastguard Worker // Is the current thread the exclusive holder of the ReaderWriterMutex. 356*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE bool IsExclusiveHeld(const Thread* self) const; 357*795d594fSAndroid Build Coastguard Worker 358*795d594fSAndroid Build Coastguard Worker // Assert the current thread has exclusive access to the ReaderWriterMutex. 359*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE void AssertExclusiveHeld(const Thread* self) const ASSERT_CAPABILITY(this); 360*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE void AssertWriterHeld(const Thread* self) const ASSERT_CAPABILITY(this); 361*795d594fSAndroid Build Coastguard Worker 362*795d594fSAndroid Build Coastguard Worker // Assert the current thread doesn't have exclusive access to the ReaderWriterMutex. AssertNotExclusiveHeld(const Thread * self)363*795d594fSAndroid Build Coastguard Worker void AssertNotExclusiveHeld(const Thread* self) ASSERT_CAPABILITY(!this) { 364*795d594fSAndroid Build Coastguard Worker if (kDebugLocking && (gAborting == 0)) { 365*795d594fSAndroid Build Coastguard Worker CHECK(!IsExclusiveHeld(self)) << *this; 366*795d594fSAndroid Build Coastguard Worker } 367*795d594fSAndroid Build Coastguard Worker } AssertNotWriterHeld(const Thread * self)368*795d594fSAndroid Build Coastguard Worker void AssertNotWriterHeld(const Thread* self) ASSERT_CAPABILITY(!this) { 369*795d594fSAndroid Build Coastguard Worker AssertNotExclusiveHeld(self); 370*795d594fSAndroid Build Coastguard Worker } 371*795d594fSAndroid Build Coastguard Worker 372*795d594fSAndroid Build Coastguard Worker // Is the current thread a shared holder of the ReaderWriterMutex. 373*795d594fSAndroid Build Coastguard Worker bool IsSharedHeld(const Thread* self) const; 374*795d594fSAndroid Build Coastguard Worker 375*795d594fSAndroid Build Coastguard Worker // Assert the current thread has shared access to the ReaderWriterMutex. AssertSharedHeld(const Thread * self)376*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE void AssertSharedHeld(const Thread* self) ASSERT_SHARED_CAPABILITY(this) { 377*795d594fSAndroid Build Coastguard Worker if (kDebugLocking && (gAborting == 0)) { 378*795d594fSAndroid Build Coastguard Worker // TODO: we can only assert this well when self != null. 379*795d594fSAndroid Build Coastguard Worker CHECK(IsSharedHeld(self) || self == nullptr) << *this; 380*795d594fSAndroid Build Coastguard Worker } 381*795d594fSAndroid Build Coastguard Worker } AssertReaderHeld(const Thread * self)382*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE void AssertReaderHeld(const Thread* self) ASSERT_SHARED_CAPABILITY(this) { 383*795d594fSAndroid Build Coastguard Worker AssertSharedHeld(self); 384*795d594fSAndroid Build Coastguard Worker } 385*795d594fSAndroid Build Coastguard Worker 386*795d594fSAndroid Build Coastguard Worker // Assert the current thread doesn't hold this ReaderWriterMutex either in shared or exclusive 387*795d594fSAndroid Build Coastguard Worker // mode. AssertNotHeld(const Thread * self)388*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE void AssertNotHeld(const Thread* self) ASSERT_CAPABILITY(!this) { 389*795d594fSAndroid Build Coastguard Worker if (kDebugLocking && (gAborting == 0)) { 390*795d594fSAndroid Build Coastguard Worker CHECK(!IsExclusiveHeld(self)) << *this; 391*795d594fSAndroid Build Coastguard Worker CHECK(!IsSharedHeld(self)) << *this; 392*795d594fSAndroid Build Coastguard Worker } 393*795d594fSAndroid Build Coastguard Worker } 394*795d594fSAndroid Build Coastguard Worker 395*795d594fSAndroid Build Coastguard Worker // Id associated with exclusive owner. No memory ordering semantics if called from a thread other 396*795d594fSAndroid Build Coastguard Worker // than the owner. Returns 0 if the lock is not held. Returns either 0 or -1 if it is held by 397*795d594fSAndroid Build Coastguard Worker // one or more readers. Not reliable unless the mutex is held. 398*795d594fSAndroid Build Coastguard Worker pid_t GetExclusiveOwnerTid() const; 399*795d594fSAndroid Build Coastguard Worker 400*795d594fSAndroid Build Coastguard Worker void Dump(std::ostream& os) const override; 401*795d594fSAndroid Build Coastguard Worker 402*795d594fSAndroid Build Coastguard Worker // For negative capabilities in clang annotations. 403*795d594fSAndroid Build Coastguard Worker const ReaderWriterMutex& operator!() const { return *this; } 404*795d594fSAndroid Build Coastguard Worker 405*795d594fSAndroid Build Coastguard Worker void WakeupToRespondToEmptyCheckpoint() override; 406*795d594fSAndroid Build Coastguard Worker 407*795d594fSAndroid Build Coastguard Worker private: 408*795d594fSAndroid Build Coastguard Worker #if ART_USE_FUTEXES 409*795d594fSAndroid Build Coastguard Worker // Out-of-inline path for handling contention for a SharedLock. 410*795d594fSAndroid Build Coastguard Worker void HandleSharedLockContention(Thread* self, int32_t cur_state); 411*795d594fSAndroid Build Coastguard Worker 412*795d594fSAndroid Build Coastguard Worker // -1 implies held exclusive, >= 0: shared held by state_ many owners. 413*795d594fSAndroid Build Coastguard Worker AtomicInteger state_; 414*795d594fSAndroid Build Coastguard Worker // Exclusive owner. Modification guarded by this mutex. 415*795d594fSAndroid Build Coastguard Worker Atomic<pid_t> exclusive_owner_; 416*795d594fSAndroid Build Coastguard Worker // Number of contenders waiting for either a reader share or exclusive access. We only maintain 417*795d594fSAndroid Build Coastguard Worker // the sum, since we would otherwise need to read both in all unlock operations. 418*795d594fSAndroid Build Coastguard Worker // We keep this separate from the state, since futexes are limited to 32 bits, and obvious 419*795d594fSAndroid Build Coastguard Worker // approaches to combining with state_ risk overflow. 420*795d594fSAndroid Build Coastguard Worker AtomicInteger num_contenders_; 421*795d594fSAndroid Build Coastguard Worker #else 422*795d594fSAndroid Build Coastguard Worker pthread_rwlock_t rwlock_; 423*795d594fSAndroid Build Coastguard Worker Atomic<pid_t> exclusive_owner_; // Writes guarded by rwlock_. Asynchronous reads are OK. 424*795d594fSAndroid Build Coastguard Worker #endif 425*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(ReaderWriterMutex); 426*795d594fSAndroid Build Coastguard Worker }; 427*795d594fSAndroid Build Coastguard Worker 428*795d594fSAndroid Build Coastguard Worker // MutatorMutex is a special kind of ReaderWriterMutex created specifically for the 429*795d594fSAndroid Build Coastguard Worker // Locks::mutator_lock_ mutex. The behaviour is identical to the ReaderWriterMutex except that 430*795d594fSAndroid Build Coastguard Worker // thread state changes also play a part in lock ownership. The mutator_lock_ will not be truly 431*795d594fSAndroid Build Coastguard Worker // held by any mutator threads. However, a thread in the kRunnable state is considered to have 432*795d594fSAndroid Build Coastguard Worker // shared ownership of the mutator lock and therefore transitions in and out of the kRunnable 433*795d594fSAndroid Build Coastguard Worker // state have associated implications on lock ownership. Extra methods to handle the state 434*795d594fSAndroid Build Coastguard Worker // transitions have been added to the interface but are only accessible to the methods dealing 435*795d594fSAndroid Build Coastguard Worker // with state transitions. The thread state and flags attributes are used to ensure thread state 436*795d594fSAndroid Build Coastguard Worker // transitions are consistent with the permitted behaviour of the mutex. 437*795d594fSAndroid Build Coastguard Worker // 438*795d594fSAndroid Build Coastguard Worker // *) The most important consequence of this behaviour is that all threads must be in one of the 439*795d594fSAndroid Build Coastguard Worker // suspended states before exclusive ownership of the mutator mutex is sought. 440*795d594fSAndroid Build Coastguard Worker // 441*795d594fSAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& os, const MutatorMutex& mu); 442*795d594fSAndroid Build Coastguard Worker class SHARED_LOCKABLE MutatorMutex : public ReaderWriterMutex { 443*795d594fSAndroid Build Coastguard Worker public: 444*795d594fSAndroid Build Coastguard Worker explicit MutatorMutex(const char* name, LockLevel level = kDefaultMutexLevel) ReaderWriterMutex(name,level)445*795d594fSAndroid Build Coastguard Worker : ReaderWriterMutex(name, level) {} ~MutatorMutex()446*795d594fSAndroid Build Coastguard Worker ~MutatorMutex() {} 447*795d594fSAndroid Build Coastguard Worker IsMutatorMutex()448*795d594fSAndroid Build Coastguard Worker virtual bool IsMutatorMutex() const { return true; } 449*795d594fSAndroid Build Coastguard Worker 450*795d594fSAndroid Build Coastguard Worker // For negative capabilities in clang annotations. 451*795d594fSAndroid Build Coastguard Worker const MutatorMutex& operator!() const { return *this; } 452*795d594fSAndroid Build Coastguard Worker 453*795d594fSAndroid Build Coastguard Worker private: 454*795d594fSAndroid Build Coastguard Worker friend class Thread; 455*795d594fSAndroid Build Coastguard Worker void TransitionFromRunnableToSuspended(Thread* self) UNLOCK_FUNCTION() ALWAYS_INLINE; 456*795d594fSAndroid Build Coastguard Worker void TransitionFromSuspendedToRunnable(Thread* self) SHARED_LOCK_FUNCTION() ALWAYS_INLINE; 457*795d594fSAndroid Build Coastguard Worker 458*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(MutatorMutex); 459*795d594fSAndroid Build Coastguard Worker }; 460*795d594fSAndroid Build Coastguard Worker 461*795d594fSAndroid Build Coastguard Worker // ConditionVariables allow threads to queue and sleep. Threads may then be resumed individually 462*795d594fSAndroid Build Coastguard Worker // (Signal) or all at once (Broadcast). 463*795d594fSAndroid Build Coastguard Worker class EXPORT ConditionVariable { 464*795d594fSAndroid Build Coastguard Worker public: 465*795d594fSAndroid Build Coastguard Worker ConditionVariable(const char* name, Mutex& mutex); 466*795d594fSAndroid Build Coastguard Worker ~ConditionVariable(); 467*795d594fSAndroid Build Coastguard Worker 468*795d594fSAndroid Build Coastguard Worker // Requires the mutex to be held. 469*795d594fSAndroid Build Coastguard Worker void Broadcast(Thread* self); 470*795d594fSAndroid Build Coastguard Worker // Requires the mutex to be held. 471*795d594fSAndroid Build Coastguard Worker void Signal(Thread* self); 472*795d594fSAndroid Build Coastguard Worker // TODO: No thread safety analysis on Wait and TimedWait as they call mutex operations via their 473*795d594fSAndroid Build Coastguard Worker // pointer copy, thereby defeating annotalysis. 474*795d594fSAndroid Build Coastguard Worker void Wait(Thread* self) NO_THREAD_SAFETY_ANALYSIS; 475*795d594fSAndroid Build Coastguard Worker bool TimedWait(Thread* self, int64_t ms, int32_t ns) NO_THREAD_SAFETY_ANALYSIS; 476*795d594fSAndroid Build Coastguard Worker // Variant of Wait that should be used with caution. Doesn't validate that no mutexes are held 477*795d594fSAndroid Build Coastguard Worker // when waiting. 478*795d594fSAndroid Build Coastguard Worker // TODO: remove this. 479*795d594fSAndroid Build Coastguard Worker void WaitHoldingLocks(Thread* self) NO_THREAD_SAFETY_ANALYSIS; 480*795d594fSAndroid Build Coastguard Worker CheckSafeToWait(Thread * self)481*795d594fSAndroid Build Coastguard Worker void CheckSafeToWait(Thread* self) NO_THREAD_SAFETY_ANALYSIS { 482*795d594fSAndroid Build Coastguard Worker if (kDebugLocking) { 483*795d594fSAndroid Build Coastguard Worker guard_.CheckSafeToWait(self); 484*795d594fSAndroid Build Coastguard Worker } 485*795d594fSAndroid Build Coastguard Worker } 486*795d594fSAndroid Build Coastguard Worker 487*795d594fSAndroid Build Coastguard Worker private: 488*795d594fSAndroid Build Coastguard Worker const char* const name_; 489*795d594fSAndroid Build Coastguard Worker // The Mutex being used by waiters. It is an error to mix condition variables between different 490*795d594fSAndroid Build Coastguard Worker // Mutexes. 491*795d594fSAndroid Build Coastguard Worker Mutex& guard_; 492*795d594fSAndroid Build Coastguard Worker #if ART_USE_FUTEXES 493*795d594fSAndroid Build Coastguard Worker // A counter that is modified by signals and broadcasts. This ensures that when a waiter gives up 494*795d594fSAndroid Build Coastguard Worker // their Mutex and another thread takes it and signals, the waiting thread observes that sequence_ 495*795d594fSAndroid Build Coastguard Worker // changed and doesn't enter the wait. Modified while holding guard_, but is read by futex wait 496*795d594fSAndroid Build Coastguard Worker // without guard_ held. 497*795d594fSAndroid Build Coastguard Worker AtomicInteger sequence_; 498*795d594fSAndroid Build Coastguard Worker // Number of threads that have come into to wait, not the length of the waiters on the futex as 499*795d594fSAndroid Build Coastguard Worker // waiters may have been requeued onto guard_. Guarded by guard_. 500*795d594fSAndroid Build Coastguard Worker int32_t num_waiters_; 501*795d594fSAndroid Build Coastguard Worker 502*795d594fSAndroid Build Coastguard Worker void RequeueWaiters(int32_t count); 503*795d594fSAndroid Build Coastguard Worker #else 504*795d594fSAndroid Build Coastguard Worker pthread_cond_t cond_; 505*795d594fSAndroid Build Coastguard Worker #endif 506*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(ConditionVariable); 507*795d594fSAndroid Build Coastguard Worker }; 508*795d594fSAndroid Build Coastguard Worker 509*795d594fSAndroid Build Coastguard Worker // Scoped locker/unlocker for a regular Mutex that acquires mu upon construction and releases it 510*795d594fSAndroid Build Coastguard Worker // upon destruction. 511*795d594fSAndroid Build Coastguard Worker class SCOPED_CAPABILITY MutexLock { 512*795d594fSAndroid Build Coastguard Worker public: MutexLock(Thread * self,Mutex & mu)513*795d594fSAndroid Build Coastguard Worker MutexLock(Thread* self, Mutex& mu) ACQUIRE(mu) : self_(self), mu_(mu) { 514*795d594fSAndroid Build Coastguard Worker mu_.ExclusiveLock(self_); 515*795d594fSAndroid Build Coastguard Worker } 516*795d594fSAndroid Build Coastguard Worker RELEASE()517*795d594fSAndroid Build Coastguard Worker ~MutexLock() RELEASE() { 518*795d594fSAndroid Build Coastguard Worker mu_.ExclusiveUnlock(self_); 519*795d594fSAndroid Build Coastguard Worker } 520*795d594fSAndroid Build Coastguard Worker 521*795d594fSAndroid Build Coastguard Worker private: 522*795d594fSAndroid Build Coastguard Worker Thread* const self_; 523*795d594fSAndroid Build Coastguard Worker Mutex& mu_; 524*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(MutexLock); 525*795d594fSAndroid Build Coastguard Worker }; 526*795d594fSAndroid Build Coastguard Worker 527*795d594fSAndroid Build Coastguard Worker // Pretend to acquire a mutex for checking purposes, without actually doing so. Use with 528*795d594fSAndroid Build Coastguard Worker // extreme caution when it is known the condition that the mutex would guard against cannot arise. 529*795d594fSAndroid Build Coastguard Worker class SCOPED_CAPABILITY FakeMutexLock { 530*795d594fSAndroid Build Coastguard Worker public: FakeMutexLock(Mutex & mu)531*795d594fSAndroid Build Coastguard Worker explicit FakeMutexLock(Mutex& mu) ACQUIRE(mu) NO_THREAD_SAFETY_ANALYSIS {} 532*795d594fSAndroid Build Coastguard Worker RELEASE()533*795d594fSAndroid Build Coastguard Worker ~FakeMutexLock() RELEASE() NO_THREAD_SAFETY_ANALYSIS {} 534*795d594fSAndroid Build Coastguard Worker 535*795d594fSAndroid Build Coastguard Worker private: 536*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(FakeMutexLock); 537*795d594fSAndroid Build Coastguard Worker }; 538*795d594fSAndroid Build Coastguard Worker 539*795d594fSAndroid Build Coastguard Worker // Scoped locker/unlocker for a ReaderWriterMutex that acquires read access to mu upon 540*795d594fSAndroid Build Coastguard Worker // construction and releases it upon destruction. 541*795d594fSAndroid Build Coastguard Worker class SCOPED_CAPABILITY ReaderMutexLock { 542*795d594fSAndroid Build Coastguard Worker public: 543*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE ReaderMutexLock(Thread* self, ReaderWriterMutex& mu) ACQUIRE(mu); 544*795d594fSAndroid Build Coastguard Worker 545*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE ~ReaderMutexLock() RELEASE(); 546*795d594fSAndroid Build Coastguard Worker 547*795d594fSAndroid Build Coastguard Worker private: 548*795d594fSAndroid Build Coastguard Worker Thread* const self_; 549*795d594fSAndroid Build Coastguard Worker ReaderWriterMutex& mu_; 550*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(ReaderMutexLock); 551*795d594fSAndroid Build Coastguard Worker }; 552*795d594fSAndroid Build Coastguard Worker 553*795d594fSAndroid Build Coastguard Worker // Scoped locker/unlocker for a ReaderWriterMutex that acquires write access to mu upon 554*795d594fSAndroid Build Coastguard Worker // construction and releases it upon destruction. 555*795d594fSAndroid Build Coastguard Worker class SCOPED_CAPABILITY WriterMutexLock { 556*795d594fSAndroid Build Coastguard Worker public: WriterMutexLock(Thread * self,ReaderWriterMutex & mu)557*795d594fSAndroid Build Coastguard Worker WriterMutexLock(Thread* self, ReaderWriterMutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) : 558*795d594fSAndroid Build Coastguard Worker self_(self), mu_(mu) { 559*795d594fSAndroid Build Coastguard Worker mu_.ExclusiveLock(self_); 560*795d594fSAndroid Build Coastguard Worker } 561*795d594fSAndroid Build Coastguard Worker UNLOCK_FUNCTION()562*795d594fSAndroid Build Coastguard Worker ~WriterMutexLock() UNLOCK_FUNCTION() { 563*795d594fSAndroid Build Coastguard Worker mu_.ExclusiveUnlock(self_); 564*795d594fSAndroid Build Coastguard Worker } 565*795d594fSAndroid Build Coastguard Worker 566*795d594fSAndroid Build Coastguard Worker private: 567*795d594fSAndroid Build Coastguard Worker Thread* const self_; 568*795d594fSAndroid Build Coastguard Worker ReaderWriterMutex& mu_; 569*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(WriterMutexLock); 570*795d594fSAndroid Build Coastguard Worker }; 571*795d594fSAndroid Build Coastguard Worker 572*795d594fSAndroid Build Coastguard Worker } // namespace art 573*795d594fSAndroid Build Coastguard Worker 574*795d594fSAndroid Build Coastguard Worker #endif // ART_RUNTIME_BASE_MUTEX_H_ 575