• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   * Copyright (C) 2011 The Android Open Source Project
3   *
4   * Licensed under the Apache License, Version 2.0 (the "License");
5   * you may not use this file except in compliance with the License.
6   * You may obtain a copy of the License at
7   *
8   *      http://www.apache.org/licenses/LICENSE-2.0
9   *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  #ifndef ART_RUNTIME_BASE_MUTEX_H_
18  #define ART_RUNTIME_BASE_MUTEX_H_
19  
20  #include <pthread.h>
21  #include <stdint.h>
22  
23  #include <iosfwd>
24  #include <string>
25  
26  #include "atomic.h"
27  #include "base/logging.h"
28  #include "base/macros.h"
29  #include "globals.h"
30  
31  #if defined(__APPLE__)
32  #define ART_USE_FUTEXES 0
33  #else
34  #define ART_USE_FUTEXES 1
35  #endif
36  
37  // Currently Darwin doesn't support locks with timeouts.
38  #if !defined(__APPLE__)
39  #define HAVE_TIMED_RWLOCK 1
40  #else
41  #define HAVE_TIMED_RWLOCK 0
42  #endif
43  
44  namespace art {
45  
46  class SHARED_LOCKABLE ReaderWriterMutex;
47  class SHARED_LOCKABLE MutatorMutex;
48  class ScopedContentionRecorder;
49  class Thread;
50  
51  // LockLevel is used to impose a lock hierarchy [1] where acquisition of a Mutex at a higher or
52  // equal level to a lock a thread holds is invalid. The lock hierarchy achieves a cycle free
53  // partial ordering and thereby cause deadlock situations to fail checks.
54  //
55  // [1] http://www.drdobbs.com/parallel/use-lock-hierarchies-to-avoid-deadlock/204801163
56  enum LockLevel {
57    kLoggingLock = 0,
58    kSwapMutexesLock,
59    kUnexpectedSignalLock,
60    kThreadSuspendCountLock,
61    kAbortLock,
62    kJdwpAdbStateLock,
63    kJdwpSocketLock,
64    kRegionSpaceRegionLock,
65    kMarkSweepMarkStackLock,
66    kRosAllocGlobalLock,
67    kRosAllocBracketLock,
68    kRosAllocBulkFreeLock,
69    kTaggingLockLevel,
70    kTransactionLogLock,
71    kJniFunctionTableLock,
72    kJniWeakGlobalsLock,
73    kJniGlobalsLock,
74    kReferenceQueueSoftReferencesLock,
75    kReferenceQueuePhantomReferencesLock,
76    kReferenceQueueFinalizerReferencesLock,
77    kReferenceQueueWeakReferencesLock,
78    kReferenceQueueClearedReferencesLock,
79    kReferenceProcessorLock,
80    kJitDebugInterfaceLock,
81    kAllocSpaceLock,
82    kBumpPointerSpaceBlockLock,
83    kArenaPoolLock,
84    kInternTableLock,
85    kOatFileSecondaryLookupLock,
86    kHostDlOpenHandlesLock,
87    kVerifierDepsLock,
88    kOatFileManagerLock,
89    kTracingUniqueMethodsLock,
90    kTracingStreamingLock,
91    kDeoptimizedMethodsLock,
92    kClassLoaderClassesLock,
93    kDefaultMutexLevel,
94    kDexLock,
95    kMarkSweepLargeObjectLock,
96    kJdwpObjectRegistryLock,
97    kModifyLdtLock,
98    kAllocatedThreadIdsLock,
99    kMonitorPoolLock,
100    kClassLinkerClassesLock,  // TODO rename.
101    kJitCodeCacheLock,
102    kCHALock,
103    kBreakpointLock,
104    kMonitorLock,
105    kMonitorListLock,
106    kJniLoadLibraryLock,
107    kThreadListLock,
108    kAllocTrackerLock,
109    kDeoptimizationLock,
110    kProfilerLock,
111    kJdwpShutdownLock,
112    kJdwpEventListLock,
113    kJdwpAttachLock,
114    kJdwpStartLock,
115    kRuntimeShutdownLock,
116    kTraceLock,
117    kHeapBitmapLock,
118    kMutatorLock,
119    kUserCodeSuspensionLock,
120    kInstrumentEntrypointsLock,
121    kZygoteCreationLock,
122  
123    kLockLevelCount  // Must come last.
124  };
125  std::ostream& operator<<(std::ostream& os, const LockLevel& rhs);
126  
127  const bool kDebugLocking = kIsDebugBuild;
128  
129  // Record Log contention information, dumpable via SIGQUIT.
130  #ifdef ART_USE_FUTEXES
131  // To enable lock contention logging, set this to true.
132  const bool kLogLockContentions = false;
133  #else
134  // Keep this false as lock contention logging is supported only with
135  // futex.
136  const bool kLogLockContentions = false;
137  #endif
138  const size_t kContentionLogSize = 4;
139  const size_t kContentionLogDataSize = kLogLockContentions ? 1 : 0;
140  const size_t kAllMutexDataSize = kLogLockContentions ? 1 : 0;
141  
142  // Base class for all Mutex implementations
143  class BaseMutex {
144   public:
GetName()145    const char* GetName() const {
146      return name_;
147    }
148  
IsMutex()149    virtual bool IsMutex() const { return false; }
IsReaderWriterMutex()150    virtual bool IsReaderWriterMutex() const { return false; }
IsMutatorMutex()151    virtual bool IsMutatorMutex() const { return false; }
152  
153    virtual void Dump(std::ostream& os) const = 0;
154  
155    static void DumpAll(std::ostream& os);
156  
ShouldRespondToEmptyCheckpointRequest()157    bool ShouldRespondToEmptyCheckpointRequest() const {
158      return should_respond_to_empty_checkpoint_request_;
159    }
160  
SetShouldRespondToEmptyCheckpointRequest(bool value)161    void SetShouldRespondToEmptyCheckpointRequest(bool value) {
162      should_respond_to_empty_checkpoint_request_ = value;
163    }
164  
165    virtual void WakeupToRespondToEmptyCheckpoint() = 0;
166  
167   protected:
168    friend class ConditionVariable;
169  
170    BaseMutex(const char* name, LockLevel level);
171    virtual ~BaseMutex();
172    void RegisterAsLocked(Thread* self);
173    void RegisterAsUnlocked(Thread* self);
174    void CheckSafeToWait(Thread* self);
175  
176    friend class ScopedContentionRecorder;
177  
178    void RecordContention(uint64_t blocked_tid, uint64_t owner_tid, uint64_t nano_time_blocked);
179    void DumpContention(std::ostream& os) const;
180  
181    const LockLevel level_;  // Support for lock hierarchy.
182    const char* const name_;
183    bool should_respond_to_empty_checkpoint_request_;
184  
185    // A log entry that records contention but makes no guarantee that either tid will be held live.
186    struct ContentionLogEntry {
ContentionLogEntryContentionLogEntry187      ContentionLogEntry() : blocked_tid(0), owner_tid(0) {}
188      uint64_t blocked_tid;
189      uint64_t owner_tid;
190      AtomicInteger count;
191    };
192    struct ContentionLogData {
193      ContentionLogEntry contention_log[kContentionLogSize];
194      // The next entry in the contention log to be updated. Value ranges from 0 to
195      // kContentionLogSize - 1.
196      AtomicInteger cur_content_log_entry;
197      // Number of times the Mutex has been contended.
198      AtomicInteger contention_count;
199      // Sum of time waited by all contenders in ns.
200      Atomic<uint64_t> wait_time;
201      void AddToWaitTime(uint64_t value);
ContentionLogDataContentionLogData202      ContentionLogData() : wait_time(0) {}
203    };
204    ContentionLogData contention_log_data_[kContentionLogDataSize];
205  
206   public:
HasEverContended()207    bool HasEverContended() const {
208      if (kLogLockContentions) {
209        return contention_log_data_->contention_count.LoadSequentiallyConsistent() > 0;
210      }
211      return false;
212    }
213  };
214  
215  // A Mutex is used to achieve mutual exclusion between threads. A Mutex can be used to gain
216  // exclusive access to what it guards. A Mutex can be in one of two states:
217  // - Free - not owned by any thread,
218  // - Exclusive - owned by a single thread.
219  //
220  // The effect of locking and unlocking operations on the state is:
221  // State     | ExclusiveLock | ExclusiveUnlock
222  // -------------------------------------------
223  // Free      | Exclusive     | error
224  // Exclusive | Block*        | Free
225  // * Mutex is not reentrant and so an attempt to ExclusiveLock on the same thread will result in
226  //   an error. Being non-reentrant simplifies Waiting on ConditionVariables.
227  std::ostream& operator<<(std::ostream& os, const Mutex& mu);
228  class LOCKABLE Mutex : public BaseMutex {
229   public:
230    explicit Mutex(const char* name, LockLevel level = kDefaultMutexLevel, bool recursive = false);
231    ~Mutex();
232  
IsMutex()233    virtual bool IsMutex() const { return true; }
234  
235    // Block until mutex is free then acquire exclusive access.
236    void ExclusiveLock(Thread* self) ACQUIRE();
Lock(Thread * self)237    void Lock(Thread* self) ACQUIRE() {  ExclusiveLock(self); }
238  
239    // Returns true if acquires exclusive access, false otherwise.
240    bool ExclusiveTryLock(Thread* self) TRY_ACQUIRE(true);
TryLock(Thread * self)241    bool TryLock(Thread* self) TRY_ACQUIRE(true) { return ExclusiveTryLock(self); }
242  
243    // Release exclusive access.
244    void ExclusiveUnlock(Thread* self) RELEASE();
Unlock(Thread * self)245    void Unlock(Thread* self) RELEASE() {  ExclusiveUnlock(self); }
246  
247    // Is the current thread the exclusive holder of the Mutex.
248    ALWAYS_INLINE bool IsExclusiveHeld(const Thread* self) const;
249  
250    // Assert that the Mutex is exclusively held by the current thread.
251    ALWAYS_INLINE void AssertExclusiveHeld(const Thread* self) const ASSERT_CAPABILITY(this);
252    ALWAYS_INLINE void AssertHeld(const Thread* self) const ASSERT_CAPABILITY(this);
253  
254    // Assert that the Mutex is not held by the current thread.
AssertNotHeldExclusive(const Thread * self)255    void AssertNotHeldExclusive(const Thread* self) ASSERT_CAPABILITY(!*this) {
256      if (kDebugLocking && (gAborting == 0)) {
257        CHECK(!IsExclusiveHeld(self)) << *this;
258      }
259    }
AssertNotHeld(const Thread * self)260    void AssertNotHeld(const Thread* self) ASSERT_CAPABILITY(!*this) {
261      AssertNotHeldExclusive(self);
262    }
263  
264    // Id associated with exclusive owner. No memory ordering semantics if called from a thread other
265    // than the owner.
266    uint64_t GetExclusiveOwnerTid() const;
267  
268    // Returns how many times this Mutex has been locked, it is better to use AssertHeld/NotHeld.
GetDepth()269    unsigned int GetDepth() const {
270      return recursion_count_;
271    }
272  
273    virtual void Dump(std::ostream& os) const;
274  
275    // For negative capabilities in clang annotations.
276    const Mutex& operator!() const { return *this; }
277  
278    void WakeupToRespondToEmptyCheckpoint() OVERRIDE;
279  
280   private:
281  #if ART_USE_FUTEXES
282    // 0 is unheld, 1 is held.
283    AtomicInteger state_;
284    // Exclusive owner.
285    volatile uint64_t exclusive_owner_;
286    // Number of waiting contenders.
287    AtomicInteger num_contenders_;
288  #else
289    pthread_mutex_t mutex_;
290    volatile uint64_t exclusive_owner_;  // Guarded by mutex_.
291  #endif
292    const bool recursive_;  // Can the lock be recursively held?
293    unsigned int recursion_count_;
294    friend class ConditionVariable;
295    DISALLOW_COPY_AND_ASSIGN(Mutex);
296  };
297  
298  // A ReaderWriterMutex is used to achieve mutual exclusion between threads, similar to a Mutex.
299  // Unlike a Mutex a ReaderWriterMutex can be used to gain exclusive (writer) or shared (reader)
300  // access to what it guards. A flaw in relation to a Mutex is that it cannot be used with a
301  // condition variable. A ReaderWriterMutex can be in one of three states:
302  // - Free - not owned by any thread,
303  // - Exclusive - owned by a single thread,
304  // - Shared(n) - shared amongst n threads.
305  //
306  // The effect of locking and unlocking operations on the state is:
307  //
308  // State     | ExclusiveLock | ExclusiveUnlock | SharedLock       | SharedUnlock
309  // ----------------------------------------------------------------------------
310  // Free      | Exclusive     | error           | SharedLock(1)    | error
311  // Exclusive | Block         | Free            | Block            | error
312  // Shared(n) | Block         | error           | SharedLock(n+1)* | Shared(n-1) or Free
313  // * for large values of n the SharedLock may block.
314  std::ostream& operator<<(std::ostream& os, const ReaderWriterMutex& mu);
315  class SHARED_LOCKABLE ReaderWriterMutex : public BaseMutex {
316   public:
317    explicit ReaderWriterMutex(const char* name, LockLevel level = kDefaultMutexLevel);
318    ~ReaderWriterMutex();
319  
IsReaderWriterMutex()320    virtual bool IsReaderWriterMutex() const { return true; }
321  
322    // Block until ReaderWriterMutex is free then acquire exclusive access.
323    void ExclusiveLock(Thread* self) ACQUIRE();
WriterLock(Thread * self)324    void WriterLock(Thread* self) ACQUIRE() {  ExclusiveLock(self); }
325  
326    // Release exclusive access.
327    void ExclusiveUnlock(Thread* self) RELEASE();
WriterUnlock(Thread * self)328    void WriterUnlock(Thread* self) RELEASE() {  ExclusiveUnlock(self); }
329  
330    // Block until ReaderWriterMutex is free and acquire exclusive access. Returns true on success
331    // or false if timeout is reached.
332  #if HAVE_TIMED_RWLOCK
333    bool ExclusiveLockWithTimeout(Thread* self, int64_t ms, int32_t ns)
334        EXCLUSIVE_TRYLOCK_FUNCTION(true);
335  #endif
336  
337    // Block until ReaderWriterMutex is shared or free then acquire a share on the access.
338    void SharedLock(Thread* self) ACQUIRE_SHARED() ALWAYS_INLINE;
ReaderLock(Thread * self)339    void ReaderLock(Thread* self) ACQUIRE_SHARED() { SharedLock(self); }
340  
341    // Try to acquire share of ReaderWriterMutex.
342    bool SharedTryLock(Thread* self) SHARED_TRYLOCK_FUNCTION(true);
343  
344    // Release a share of the access.
345    void SharedUnlock(Thread* self) RELEASE_SHARED() ALWAYS_INLINE;
ReaderUnlock(Thread * self)346    void ReaderUnlock(Thread* self) RELEASE_SHARED() { SharedUnlock(self); }
347  
348    // Is the current thread the exclusive holder of the ReaderWriterMutex.
349    ALWAYS_INLINE bool IsExclusiveHeld(const Thread* self) const;
350  
351    // Assert the current thread has exclusive access to the ReaderWriterMutex.
352    ALWAYS_INLINE void AssertExclusiveHeld(const Thread* self) const ASSERT_CAPABILITY(this);
353    ALWAYS_INLINE void AssertWriterHeld(const Thread* self) const ASSERT_CAPABILITY(this);
354  
355    // Assert the current thread doesn't have exclusive access to the ReaderWriterMutex.
AssertNotExclusiveHeld(const Thread * self)356    void AssertNotExclusiveHeld(const Thread* self) ASSERT_CAPABILITY(!this) {
357      if (kDebugLocking && (gAborting == 0)) {
358        CHECK(!IsExclusiveHeld(self)) << *this;
359      }
360    }
AssertNotWriterHeld(const Thread * self)361    void AssertNotWriterHeld(const Thread* self) ASSERT_CAPABILITY(!this) {
362      AssertNotExclusiveHeld(self);
363    }
364  
365    // Is the current thread a shared holder of the ReaderWriterMutex.
366    bool IsSharedHeld(const Thread* self) const;
367  
368    // Assert the current thread has shared access to the ReaderWriterMutex.
AssertSharedHeld(const Thread * self)369    ALWAYS_INLINE void AssertSharedHeld(const Thread* self) ASSERT_SHARED_CAPABILITY(this) {
370      if (kDebugLocking && (gAborting == 0)) {
371        // TODO: we can only assert this well when self != null.
372        CHECK(IsSharedHeld(self) || self == nullptr) << *this;
373      }
374    }
AssertReaderHeld(const Thread * self)375    ALWAYS_INLINE void AssertReaderHeld(const Thread* self) ASSERT_SHARED_CAPABILITY(this) {
376      AssertSharedHeld(self);
377    }
378  
379    // Assert the current thread doesn't hold this ReaderWriterMutex either in shared or exclusive
380    // mode.
AssertNotHeld(const Thread * self)381    ALWAYS_INLINE void AssertNotHeld(const Thread* self) ASSERT_SHARED_CAPABILITY(!this) {
382      if (kDebugLocking && (gAborting == 0)) {
383        CHECK(!IsSharedHeld(self)) << *this;
384      }
385    }
386  
387    // Id associated with exclusive owner. No memory ordering semantics if called from a thread other
388    // than the owner.
389    uint64_t GetExclusiveOwnerTid() const;
390  
391    virtual void Dump(std::ostream& os) const;
392  
393    // For negative capabilities in clang annotations.
394    const ReaderWriterMutex& operator!() const { return *this; }
395  
396    void WakeupToRespondToEmptyCheckpoint() OVERRIDE;
397  
398   private:
399  #if ART_USE_FUTEXES
400    // Out-of-inline path for handling contention for a SharedLock.
401    void HandleSharedLockContention(Thread* self, int32_t cur_state);
402  
403    // -1 implies held exclusive, +ve shared held by state_ many owners.
404    AtomicInteger state_;
405    // Exclusive owner. Modification guarded by this mutex.
406    volatile uint64_t exclusive_owner_;
407    // Number of contenders waiting for a reader share.
408    AtomicInteger num_pending_readers_;
409    // Number of contenders waiting to be the writer.
410    AtomicInteger num_pending_writers_;
411  #else
412    pthread_rwlock_t rwlock_;
413    volatile uint64_t exclusive_owner_;  // Guarded by rwlock_.
414  #endif
415    DISALLOW_COPY_AND_ASSIGN(ReaderWriterMutex);
416  };
417  
418  // MutatorMutex is a special kind of ReaderWriterMutex created specifically for the
419  // Locks::mutator_lock_ mutex. The behaviour is identical to the ReaderWriterMutex except that
420  // thread state changes also play a part in lock ownership. The mutator_lock_ will not be truly
421  // held by any mutator threads. However, a thread in the kRunnable state is considered to have
422  // shared ownership of the mutator lock and therefore transitions in and out of the kRunnable
423  // state have associated implications on lock ownership. Extra methods to handle the state
424  // transitions have been added to the interface but are only accessible to the methods dealing
425  // with state transitions. The thread state and flags attributes are used to ensure thread state
426  // transitions are consistent with the permitted behaviour of the mutex.
427  //
428  // *) The most important consequence of this behaviour is that all threads must be in one of the
429  // suspended states before exclusive ownership of the mutator mutex is sought.
430  //
431  std::ostream& operator<<(std::ostream& os, const MutatorMutex& mu);
432  class SHARED_LOCKABLE MutatorMutex : public ReaderWriterMutex {
433   public:
434    explicit MutatorMutex(const char* name, LockLevel level = kDefaultMutexLevel)
ReaderWriterMutex(name,level)435      : ReaderWriterMutex(name, level) {}
~MutatorMutex()436    ~MutatorMutex() {}
437  
IsMutatorMutex()438    virtual bool IsMutatorMutex() const { return true; }
439  
440    // For negative capabilities in clang annotations.
441    const MutatorMutex& operator!() const { return *this; }
442  
443   private:
444    friend class Thread;
445    void TransitionFromRunnableToSuspended(Thread* self) UNLOCK_FUNCTION() ALWAYS_INLINE;
446    void TransitionFromSuspendedToRunnable(Thread* self) SHARED_LOCK_FUNCTION() ALWAYS_INLINE;
447  
448    DISALLOW_COPY_AND_ASSIGN(MutatorMutex);
449  };
450  
451  // ConditionVariables allow threads to queue and sleep. Threads may then be resumed individually
452  // (Signal) or all at once (Broadcast).
453  class ConditionVariable {
454   public:
455    ConditionVariable(const char* name, Mutex& mutex);
456    ~ConditionVariable();
457  
458    void Broadcast(Thread* self);
459    void Signal(Thread* self);
460    // TODO: No thread safety analysis on Wait and TimedWait as they call mutex operations via their
461    //       pointer copy, thereby defeating annotalysis.
462    void Wait(Thread* self) NO_THREAD_SAFETY_ANALYSIS;
463    bool TimedWait(Thread* self, int64_t ms, int32_t ns) NO_THREAD_SAFETY_ANALYSIS;
464    // Variant of Wait that should be used with caution. Doesn't validate that no mutexes are held
465    // when waiting.
466    // TODO: remove this.
467    void WaitHoldingLocks(Thread* self) NO_THREAD_SAFETY_ANALYSIS;
468  
469   private:
470    const char* const name_;
471    // The Mutex being used by waiters. It is an error to mix condition variables between different
472    // Mutexes.
473    Mutex& guard_;
474  #if ART_USE_FUTEXES
475    // A counter that is modified by signals and broadcasts. This ensures that when a waiter gives up
476    // their Mutex and another thread takes it and signals, the waiting thread observes that sequence_
477    // changed and doesn't enter the wait. Modified while holding guard_, but is read by futex wait
478    // without guard_ held.
479    AtomicInteger sequence_;
480    // Number of threads that have come into to wait, not the length of the waiters on the futex as
481    // waiters may have been requeued onto guard_. Guarded by guard_.
482    volatile int32_t num_waiters_;
483  #else
484    pthread_cond_t cond_;
485  #endif
486    DISALLOW_COPY_AND_ASSIGN(ConditionVariable);
487  };
488  
489  // Scoped locker/unlocker for a regular Mutex that acquires mu upon construction and releases it
490  // upon destruction.
491  class SCOPED_CAPABILITY MutexLock {
492   public:
MutexLock(Thread * self,Mutex & mu)493    MutexLock(Thread* self, Mutex& mu) ACQUIRE(mu) : self_(self), mu_(mu) {
494      mu_.ExclusiveLock(self_);
495    }
496  
RELEASE()497    ~MutexLock() RELEASE() {
498      mu_.ExclusiveUnlock(self_);
499    }
500  
501   private:
502    Thread* const self_;
503    Mutex& mu_;
504    DISALLOW_COPY_AND_ASSIGN(MutexLock);
505  };
506  // Catch bug where variable name is omitted. "MutexLock (lock);" instead of "MutexLock mu(lock)".
507  #define MutexLock(x) static_assert(0, "MutexLock declaration missing variable name")
508  
509  // Scoped locker/unlocker for a ReaderWriterMutex that acquires read access to mu upon
510  // construction and releases it upon destruction.
511  class SCOPED_CAPABILITY ReaderMutexLock {
512   public:
513    ALWAYS_INLINE ReaderMutexLock(Thread* self, ReaderWriterMutex& mu) ACQUIRE(mu);
514  
515    ALWAYS_INLINE ~ReaderMutexLock() RELEASE();
516  
517   private:
518    Thread* const self_;
519    ReaderWriterMutex& mu_;
520    DISALLOW_COPY_AND_ASSIGN(ReaderMutexLock);
521  };
522  
523  // Scoped locker/unlocker for a ReaderWriterMutex that acquires write access to mu upon
524  // construction and releases it upon destruction.
525  class SCOPED_CAPABILITY WriterMutexLock {
526   public:
WriterMutexLock(Thread * self,ReaderWriterMutex & mu)527    WriterMutexLock(Thread* self, ReaderWriterMutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) :
528        self_(self), mu_(mu) {
529      mu_.ExclusiveLock(self_);
530    }
531  
UNLOCK_FUNCTION()532    ~WriterMutexLock() UNLOCK_FUNCTION() {
533      mu_.ExclusiveUnlock(self_);
534    }
535  
536   private:
537    Thread* const self_;
538    ReaderWriterMutex& mu_;
539    DISALLOW_COPY_AND_ASSIGN(WriterMutexLock);
540  };
541  // Catch bug where variable name is omitted. "WriterMutexLock (lock);" instead of
542  // "WriterMutexLock mu(lock)".
543  #define WriterMutexLock(x) static_assert(0, "WriterMutexLock declaration missing variable name")
544  
545  // For StartNoThreadSuspension and EndNoThreadSuspension.
546  class CAPABILITY("role") Role {
547   public:
Acquire()548    void Acquire() ACQUIRE() {}
Release()549    void Release() RELEASE() {}
550    const Role& operator!() const { return *this; }
551  };
552  
553  class Uninterruptible : public Role {
554  };
555  
556  // Global mutexes corresponding to the levels above.
557  class Locks {
558   public:
559    static void Init();
560    static void InitConditions() NO_THREAD_SAFETY_ANALYSIS;  // Condition variables.
561  
562    // Destroying various lock types can emit errors that vary depending upon
563    // whether the client (art::Runtime) is currently active.  Allow the client
564    // to set a callback that is used to check when it is acceptable to call
565    // Abort.  The default behavior is that the client *is not* able to call
566    // Abort if no callback is established.
567    using ClientCallback = bool();
568    static void SetClientCallback(ClientCallback* is_safe_to_call_abort_cb) NO_THREAD_SAFETY_ANALYSIS;
569    // Checks for whether it is safe to call Abort() without using locks.
570    static bool IsSafeToCallAbortRacy() NO_THREAD_SAFETY_ANALYSIS;
571  
572    // Add a mutex to expected_mutexes_on_weak_ref_access_.
573    static void AddToExpectedMutexesOnWeakRefAccess(BaseMutex* mutex, bool need_lock = true);
574    // Remove a mutex from expected_mutexes_on_weak_ref_access_.
575    static void RemoveFromExpectedMutexesOnWeakRefAccess(BaseMutex* mutex, bool need_lock = true);
576    // Check if the given mutex is in expected_mutexes_on_weak_ref_access_.
577    static bool IsExpectedOnWeakRefAccess(BaseMutex* mutex);
578  
579    // Guards allocation entrypoint instrumenting.
580    static Mutex* instrument_entrypoints_lock_;
581  
582    // Guards code that deals with user-code suspension. This mutex must be held when suspending or
583    // resuming threads with SuspendReason::kForUserCode. It may be held by a suspended thread, but
584    // only if the suspension is not due to SuspendReason::kForUserCode.
585    static Mutex* user_code_suspension_lock_ ACQUIRED_AFTER(instrument_entrypoints_lock_);
586  
587    // A barrier is used to synchronize the GC/Debugger thread with mutator threads. When GC/Debugger
588    // thread wants to suspend all mutator threads, it needs to wait for all mutator threads to pass
589    // a barrier. Threads that are already suspended will get their barrier passed by the GC/Debugger
590    // thread; threads in the runnable state will pass the barrier when they transit to the suspended
591    // state. GC/Debugger thread will be woken up when all mutator threads are suspended.
592    //
593    // Thread suspension:
594    // mutator thread                                | GC/Debugger
595    //   .. running ..                               |   .. running ..
596    //   .. running ..                               | Request thread suspension by:
597    //   .. running ..                               |   - acquiring thread_suspend_count_lock_
598    //   .. running ..                               |   - incrementing Thread::suspend_count_ on
599    //   .. running ..                               |     all mutator threads
600    //   .. running ..                               |   - releasing thread_suspend_count_lock_
601    //   .. running ..                               | Block wait for all threads to pass a barrier
602    // Poll Thread::suspend_count_ and enter full    |   .. blocked ..
603    // suspend code.                                 |   .. blocked ..
604    // Change state to kSuspended (pass the barrier) | Wake up when all threads pass the barrier
605    // x: Acquire thread_suspend_count_lock_         |   .. running ..
606    // while Thread::suspend_count_ > 0              |   .. running ..
607    //   - wait on Thread::resume_cond_              |   .. running ..
608    //     (releases thread_suspend_count_lock_)     |   .. running ..
609    //   .. waiting ..                               | Request thread resumption by:
610    //   .. waiting ..                               |   - acquiring thread_suspend_count_lock_
611    //   .. waiting ..                               |   - decrementing Thread::suspend_count_ on
612    //   .. waiting ..                               |     all mutator threads
613    //   .. waiting ..                               |   - notifying on Thread::resume_cond_
614    //    - re-acquire thread_suspend_count_lock_    |   - releasing thread_suspend_count_lock_
615    // Release thread_suspend_count_lock_            |  .. running ..
616    // Change to kRunnable                           |  .. running ..
617    //  - this uses a CAS operation to ensure the    |  .. running ..
618    //    suspend request flag isn't raised as the   |  .. running ..
619    //    state is changed                           |  .. running ..
620    //  - if the CAS operation fails then goto x     |  .. running ..
621    //  .. running ..                                |  .. running ..
622    static MutatorMutex* mutator_lock_ ACQUIRED_AFTER(user_code_suspension_lock_);
623  
624    // Allow reader-writer mutual exclusion on the mark and live bitmaps of the heap.
625    static ReaderWriterMutex* heap_bitmap_lock_ ACQUIRED_AFTER(mutator_lock_);
626  
627    // Guards shutdown of the runtime.
628    static Mutex* runtime_shutdown_lock_ ACQUIRED_AFTER(heap_bitmap_lock_);
629  
630    // Guards background profiler global state.
631    static Mutex* profiler_lock_ ACQUIRED_AFTER(runtime_shutdown_lock_);
632  
633    // Guards trace (ie traceview) requests.
634    static Mutex* trace_lock_ ACQUIRED_AFTER(profiler_lock_);
635  
636    // Guards debugger recent allocation records.
637    static Mutex* alloc_tracker_lock_ ACQUIRED_AFTER(trace_lock_);
638  
639    // Guards updates to instrumentation to ensure mutual exclusion of
640    // events like deoptimization requests.
641    // TODO: improve name, perhaps instrumentation_update_lock_.
642    static Mutex* deoptimization_lock_ ACQUIRED_AFTER(alloc_tracker_lock_);
643  
644    // Guards Class Hierarchy Analysis (CHA).
645    static Mutex* cha_lock_ ACQUIRED_AFTER(deoptimization_lock_);
646  
647    // The thread_list_lock_ guards ThreadList::list_. It is also commonly held to stop threads
648    // attaching and detaching.
649    static Mutex* thread_list_lock_ ACQUIRED_AFTER(cha_lock_);
650  
651    // Signaled when threads terminate. Used to determine when all non-daemons have terminated.
652    static ConditionVariable* thread_exit_cond_ GUARDED_BY(Locks::thread_list_lock_);
653  
654    // Guards maintaining loading library data structures.
655    static Mutex* jni_libraries_lock_ ACQUIRED_AFTER(thread_list_lock_);
656  
657    // Guards breakpoints.
658    static ReaderWriterMutex* breakpoint_lock_ ACQUIRED_AFTER(jni_libraries_lock_);
659  
660    // Guards lists of classes within the class linker.
661    static ReaderWriterMutex* classlinker_classes_lock_ ACQUIRED_AFTER(breakpoint_lock_);
662  
663    // When declaring any Mutex add DEFAULT_MUTEX_ACQUIRED_AFTER to use annotalysis to check the code
664    // doesn't try to hold a higher level Mutex.
665    #define DEFAULT_MUTEX_ACQUIRED_AFTER ACQUIRED_AFTER(Locks::classlinker_classes_lock_)
666  
667    static Mutex* allocated_monitor_ids_lock_ ACQUIRED_AFTER(classlinker_classes_lock_);
668  
669    // Guard the allocation/deallocation of thread ids.
670    static Mutex* allocated_thread_ids_lock_ ACQUIRED_AFTER(allocated_monitor_ids_lock_);
671  
672    // Guards modification of the LDT on x86.
673    static Mutex* modify_ldt_lock_ ACQUIRED_AFTER(allocated_thread_ids_lock_);
674  
675    static ReaderWriterMutex* dex_lock_ ACQUIRED_AFTER(modify_ldt_lock_);
676  
677    // Guards opened oat files in OatFileManager.
678    static ReaderWriterMutex* oat_file_manager_lock_ ACQUIRED_AFTER(dex_lock_);
679  
680    // Guards extra string entries for VerifierDeps.
681    static ReaderWriterMutex* verifier_deps_lock_ ACQUIRED_AFTER(oat_file_manager_lock_);
682  
683    // Guards dlopen_handles_ in DlOpenOatFile.
684    static Mutex* host_dlopen_handles_lock_ ACQUIRED_AFTER(verifier_deps_lock_);
685  
686    // Guards intern table.
687    static Mutex* intern_table_lock_ ACQUIRED_AFTER(host_dlopen_handles_lock_);
688  
689    // Guards reference processor.
690    static Mutex* reference_processor_lock_ ACQUIRED_AFTER(intern_table_lock_);
691  
692    // Guards cleared references queue.
693    static Mutex* reference_queue_cleared_references_lock_ ACQUIRED_AFTER(reference_processor_lock_);
694  
695    // Guards weak references queue.
696    static Mutex* reference_queue_weak_references_lock_ ACQUIRED_AFTER(reference_queue_cleared_references_lock_);
697  
698    // Guards finalizer references queue.
699    static Mutex* reference_queue_finalizer_references_lock_ ACQUIRED_AFTER(reference_queue_weak_references_lock_);
700  
701    // Guards phantom references queue.
702    static Mutex* reference_queue_phantom_references_lock_ ACQUIRED_AFTER(reference_queue_finalizer_references_lock_);
703  
704    // Guards soft references queue.
705    static Mutex* reference_queue_soft_references_lock_ ACQUIRED_AFTER(reference_queue_phantom_references_lock_);
706  
707    // Guard accesses to the JNI Global Reference table.
708    static ReaderWriterMutex* jni_globals_lock_ ACQUIRED_AFTER(reference_queue_soft_references_lock_);
709  
710    // Guard accesses to the JNI Weak Global Reference table.
711    static Mutex* jni_weak_globals_lock_ ACQUIRED_AFTER(jni_globals_lock_);
712  
713    // Guard accesses to the JNI function table override.
714    static Mutex* jni_function_table_lock_ ACQUIRED_AFTER(jni_weak_globals_lock_);
715  
716    // Have an exclusive aborting thread.
717    static Mutex* abort_lock_ ACQUIRED_AFTER(jni_function_table_lock_);
718  
719    // Allow mutual exclusion when manipulating Thread::suspend_count_.
720    // TODO: Does the trade-off of a per-thread lock make sense?
721    static Mutex* thread_suspend_count_lock_ ACQUIRED_AFTER(abort_lock_);
722  
723    // One unexpected signal at a time lock.
724    static Mutex* unexpected_signal_lock_ ACQUIRED_AFTER(thread_suspend_count_lock_);
725  
726    // Have an exclusive logging thread.
727    static Mutex* logging_lock_ ACQUIRED_AFTER(unexpected_signal_lock_);
728  
729    // List of mutexes that we expect a thread may hold when accessing weak refs. This is used to
730    // avoid a deadlock in the empty checkpoint while weak ref access is disabled (b/34964016). If we
731    // encounter an unexpected mutex on accessing weak refs,
732    // Thread::CheckEmptyCheckpointFromWeakRefAccess will detect it.
733    static std::vector<BaseMutex*> expected_mutexes_on_weak_ref_access_;
734    static Atomic<const BaseMutex*> expected_mutexes_on_weak_ref_access_guard_;
735    class ScopedExpectedMutexesOnWeakRefAccessLock;
736  };
737  
738  class Roles {
739   public:
740    // Uninterruptible means that the thread may not become suspended.
741    static Uninterruptible uninterruptible_;
742  };
743  
744  }  // namespace art
745  
746  #endif  // ART_RUNTIME_BASE_MUTEX_H_
747