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