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 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 kAllocSpaceLock, 80 kBumpPointerSpaceBlockLock, 81 kArenaPoolLock, 82 kDexFileMethodInlinerLock, 83 kDexFileToMethodInlinerMapLock, 84 kInternTableLock, 85 kOatFileSecondaryLookupLock, 86 kHostDlOpenHandlesLock, 87 kOatFileManagerLock, 88 kTracingUniqueMethodsLock, 89 kTracingStreamingLock, 90 kDeoptimizedMethodsLock, 91 kClassLoaderClassesLock, 92 kDefaultMutexLevel, 93 kMarkSweepLargeObjectLock, 94 kPinTableLock, 95 kJdwpObjectRegistryLock, 96 kModifyLdtLock, 97 kAllocatedThreadIdsLock, 98 kMonitorPoolLock, 99 kMethodVerifiersLock, 100 kClassLinkerClassesLock, // TODO rename. 101 kJitCodeCacheLock, 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 }; 123 std::ostream& operator<<(std::ostream& os, const LockLevel& rhs); 124 125 const 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. 130 const bool kLogLockContentions = false; 131 #else 132 // Keep this false as lock contention logging is supported only with 133 // futex. 134 const bool kLogLockContentions = false; 135 #endif 136 const size_t kContentionLogSize = 4; 137 const size_t kContentionLogDataSize = kLogLockContentions ? 1 : 0; 138 const size_t kAllMutexDataSize = kLogLockContentions ? 1 : 0; 139 140 // Base class for all Mutex implementations 141 class BaseMutex { 142 public: GetName()143 const char* GetName() const { 144 return name_; 145 } 146 IsMutex()147 virtual bool IsMutex() const { return false; } IsReaderWriterMutex()148 virtual bool IsReaderWriterMutex() const { return false; } IsMutatorMutex()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 { ContentionLogEntryContentionLogEntry174 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); ContentionLogDataContentionLogData189 ContentionLogData() : wait_time(0) {} 190 }; 191 ContentionLogData contention_log_data_[kContentionLogDataSize]; 192 193 public: HasEverContended()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. 214 std::ostream& operator<<(std::ostream& os, const Mutex& mu); 215 class LOCKABLE Mutex : public BaseMutex { 216 public: 217 explicit Mutex(const char* name, LockLevel level = kDefaultMutexLevel, bool recursive = false); 218 ~Mutex(); 219 IsMutex()220 virtual bool IsMutex() const { return true; } 221 222 // Block until mutex is free then acquire exclusive access. 223 void ExclusiveLock(Thread* self) ACQUIRE(); Lock(Thread * self)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); TryLock(Thread * self)228 bool TryLock(Thread* self) TRY_ACQUIRE(true) { return ExclusiveTryLock(self); } 229 230 // Release exclusive access. 231 void ExclusiveUnlock(Thread* self) RELEASE(); Unlock(Thread * self)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. AssertExclusiveHeld(const Thread * self)238 void AssertExclusiveHeld(const Thread* self) ASSERT_CAPABILITY(this) { 239 if (kDebugLocking && (gAborting == 0)) { 240 CHECK(IsExclusiveHeld(self)) << *this; 241 } 242 } AssertHeld(const Thread * self)243 void AssertHeld(const Thread* self) ASSERT_CAPABILITY(this) { AssertExclusiveHeld(self); } 244 245 // Assert that the Mutex is not held by the current thread. AssertNotHeldExclusive(const Thread * self)246 void AssertNotHeldExclusive(const Thread* self) ASSERT_CAPABILITY(!*this) { 247 if (kDebugLocking && (gAborting == 0)) { 248 CHECK(!IsExclusiveHeld(self)) << *this; 249 } 250 } AssertNotHeld(const Thread * self)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. GetDepth()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. 303 std::ostream& operator<<(std::ostream& os, const ReaderWriterMutex& mu); 304 class SHARED_LOCKABLE ReaderWriterMutex : public BaseMutex { 305 public: 306 explicit ReaderWriterMutex(const char* name, LockLevel level = kDefaultMutexLevel); 307 ~ReaderWriterMutex(); 308 IsReaderWriterMutex()309 virtual bool IsReaderWriterMutex() const { return true; } 310 311 // Block until ReaderWriterMutex is free then acquire exclusive access. 312 void ExclusiveLock(Thread* self) ACQUIRE(); WriterLock(Thread * self)313 void WriterLock(Thread* self) ACQUIRE() { ExclusiveLock(self); } 314 315 // Release exclusive access. 316 void ExclusiveUnlock(Thread* self) RELEASE(); WriterUnlock(Thread * self)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; ReaderLock(Thread * self)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; ReaderUnlock(Thread * self)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. AssertExclusiveHeld(const Thread * self)341 void AssertExclusiveHeld(const Thread* self) ASSERT_CAPABILITY(this) { 342 if (kDebugLocking && (gAborting == 0)) { 343 CHECK(IsExclusiveHeld(self)) << *this; 344 } 345 } AssertWriterHeld(const Thread * self)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. AssertNotExclusiveHeld(const Thread * self)349 void AssertNotExclusiveHeld(const Thread* self) ASSERT_CAPABILITY(!this) { 350 if (kDebugLocking && (gAborting == 0)) { 351 CHECK(!IsExclusiveHeld(self)) << *this; 352 } 353 } AssertNotWriterHeld(const Thread * self)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. AssertSharedHeld(const Thread * self)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 } AssertReaderHeld(const Thread * self)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. AssertNotHeld(const Thread * self)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 // 422 std::ostream& operator<<(std::ostream& os, const MutatorMutex& mu); 423 class SHARED_LOCKABLE MutatorMutex : public ReaderWriterMutex { 424 public: 425 explicit MutatorMutex(const char* name, LockLevel level = kDefaultMutexLevel) ReaderWriterMutex(name,level)426 : ReaderWriterMutex(name, level) {} ~MutatorMutex()427 ~MutatorMutex() {} 428 IsMutatorMutex()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). 444 class 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. 482 class SCOPED_CAPABILITY MutexLock { 483 public: MutexLock(Thread * self,Mutex & mu)484 MutexLock(Thread* self, Mutex& mu) ACQUIRE(mu) : self_(self), mu_(mu) { 485 mu_.ExclusiveLock(self_); 486 } 487 RELEASE()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. 502 class SCOPED_CAPABILITY ReaderMutexLock { 503 public: ReaderMutexLock(Thread * self,ReaderWriterMutex & mu)504 ReaderMutexLock(Thread* self, ReaderWriterMutex& mu) ACQUIRE(mu) : 505 self_(self), mu_(mu) { 506 mu_.SharedLock(self_); 507 } 508 RELEASE()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. 524 class SCOPED_CAPABILITY WriterMutexLock { 525 public: WriterMutexLock(Thread * self,ReaderWriterMutex & mu)526 WriterMutexLock(Thread* self, ReaderWriterMutex& mu) EXCLUSIVE_LOCK_FUNCTION(mu) : 527 self_(self), mu_(mu) { 528 mu_.ExclusiveLock(self_); 529 } 530 UNLOCK_FUNCTION()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. 545 class CAPABILITY("role") Role { 546 public: Acquire()547 void Acquire() ACQUIRE() {} Release()548 void Release() RELEASE() {} 549 const Role& operator!() const { return *this; } 550 }; 551 552 class Uninterruptible : public Role { 553 }; 554 555 // Global mutexes corresponding to the levels above. 556 class 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 dlopen_handles_ in DlOpenOatFile. 655 static Mutex* host_dlopen_handles_lock_ ACQUIRED_AFTER(oat_file_manager_lock_); 656 657 // Guards intern table. 658 static Mutex* intern_table_lock_ ACQUIRED_AFTER(host_dlopen_handles_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 699 class 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