xref: /aosp_15_r20/art/runtime/base/mutex.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
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