1 /* 2 * Copyright (C) 2012 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_LOCKS_H_ 18 #define ART_RUNTIME_LOCKS_H_ 19 20 #include <ostream> 21 22 #include "base/macros.h" 23 24 namespace art { 25 26 class LOCKABLE Mutex; 27 class LOCKABLE ReaderWriterMutex; 28 29 // LockLevel is used to impose a lock hierarchy [1] where acquisition of a Mutex at a higher or 30 // equal level to a lock a thread holds is invalid. The lock hierarchy achieves a cycle free 31 // partial ordering and thereby cause deadlock situations to fail checks. 32 // 33 // [1] http://www.drdobbs.com/parallel/use-lock-hierarchies-to-avoid-deadlock/204801163 34 enum LockLevel { 35 kLoggingLock = 0, 36 kUnexpectedSignalLock, 37 kThreadSuspendCountLock, 38 kAbortLock, 39 kJdwpSocketLock, 40 kAllocSpaceLock, 41 kMarkSweepMarkStackLock, 42 kDefaultMutexLevel, 43 kMarkSweepLargeObjectLock, 44 kPinTableLock, 45 kLoadLibraryLock, 46 kJdwpObjectRegistryLock, 47 kClassLinkerClassesLock, 48 kBreakpointLock, 49 kThreadListLock, 50 kBreakpointInvokeLock, 51 kTraceLock, 52 kJdwpEventListLock, 53 kJdwpAttachLock, 54 kJdwpStartLock, 55 kRuntimeShutdownLock, 56 kHeapBitmapLock, 57 kMonitorLock, 58 kMutatorLock, 59 kZygoteCreationLock, 60 61 kLockLevelCount // Must come last. 62 }; 63 std::ostream& operator<<(std::ostream& os, const LockLevel& rhs); 64 65 // Global mutexes corresponding to the levels above. 66 class Locks { 67 public: 68 static void Init(); 69 70 // The mutator_lock_ is used to allow mutators to execute in a shared (reader) mode or to block 71 // mutators by having an exclusive (writer) owner. In normal execution each mutator thread holds 72 // a share on the mutator_lock_. The garbage collector may also execute with shared access but 73 // at times requires exclusive access to the heap (not to be confused with the heap meta-data 74 // guarded by the heap_lock_ below). When the garbage collector requires exclusive access it asks 75 // the mutators to suspend themselves which also involves usage of the thread_suspend_count_lock_ 76 // to cover weaknesses in using ReaderWriterMutexes with ConditionVariables. We use a condition 77 // variable to wait upon in the suspension logic as releasing and then re-acquiring a share on 78 // the mutator lock doesn't necessarily allow the exclusive user (e.g the garbage collector) 79 // chance to acquire the lock. 80 // 81 // Thread suspension: 82 // Shared users | Exclusive user 83 // (holding mutator lock and in kRunnable state) | .. running .. 84 // .. running .. | Request thread suspension by: 85 // .. running .. | - acquiring thread_suspend_count_lock_ 86 // .. running .. | - incrementing Thread::suspend_count_ on 87 // .. running .. | all mutator threads 88 // .. running .. | - releasing thread_suspend_count_lock_ 89 // .. running .. | Block trying to acquire exclusive mutator lock 90 // Poll Thread::suspend_count_ and enter full | .. blocked .. 91 // suspend code. | .. blocked .. 92 // Change state to kSuspended | .. blocked .. 93 // x: Release share on mutator_lock_ | Carry out exclusive access 94 // Acquire thread_suspend_count_lock_ | .. exclusive .. 95 // while Thread::suspend_count_ > 0 | .. exclusive .. 96 // - wait on Thread::resume_cond_ | .. exclusive .. 97 // (releases thread_suspend_count_lock_) | .. exclusive .. 98 // .. waiting .. | Release mutator_lock_ 99 // .. waiting .. | Request thread resumption by: 100 // .. waiting .. | - acquiring thread_suspend_count_lock_ 101 // .. waiting .. | - decrementing Thread::suspend_count_ on 102 // .. waiting .. | all mutator threads 103 // .. waiting .. | - notifying on Thread::resume_cond_ 104 // - re-acquire thread_suspend_count_lock_ | - releasing thread_suspend_count_lock_ 105 // Release thread_suspend_count_lock_ | .. running .. 106 // Acquire share on mutator_lock_ | .. running .. 107 // - This could block but the thread still | .. running .. 108 // has a state of kSuspended and so this | .. running .. 109 // isn't an issue. | .. running .. 110 // Acquire thread_suspend_count_lock_ | .. running .. 111 // - we poll here as we're transitioning into | .. running .. 112 // kRunnable and an individual thread suspend | .. running .. 113 // request (e.g for debugging) won't try | .. running .. 114 // to acquire the mutator lock (which would | .. running .. 115 // block as we hold the mutator lock). This | .. running .. 116 // poll ensures that if the suspender thought | .. running .. 117 // we were suspended by incrementing our | .. running .. 118 // Thread::suspend_count_ and then reading | .. running .. 119 // our state we go back to waiting on | .. running .. 120 // Thread::resume_cond_. | .. running .. 121 // can_go_runnable = Thread::suspend_count_ == 0 | .. running .. 122 // Release thread_suspend_count_lock_ | .. running .. 123 // if can_go_runnable | .. running .. 124 // Change state to kRunnable | .. running .. 125 // else | .. running .. 126 // Goto x | .. running .. 127 // .. running .. | .. running .. 128 static ReaderWriterMutex* mutator_lock_; 129 130 // Allow reader-writer mutual exclusion on the mark and live bitmaps of the heap. 131 static ReaderWriterMutex* heap_bitmap_lock_ ACQUIRED_AFTER(mutator_lock_); 132 133 // Guards shutdown of the runtime. 134 static Mutex* runtime_shutdown_lock_ ACQUIRED_AFTER(heap_bitmap_lock_); 135 136 // The thread_list_lock_ guards ThreadList::list_. It is also commonly held to stop threads 137 // attaching and detaching. 138 static Mutex* thread_list_lock_ ACQUIRED_AFTER(runtime_shutdown_lock_); 139 140 // Guards breakpoints and single-stepping. 141 static Mutex* breakpoint_lock_ ACQUIRED_AFTER(thread_list_lock_); 142 143 // Guards trace requests. 144 static Mutex* trace_lock_ ACQUIRED_AFTER(breakpoint_lock_); 145 146 // Guards lists of classes within the class linker. 147 static ReaderWriterMutex* classlinker_classes_lock_ ACQUIRED_AFTER(trace_lock_); 148 149 // When declaring any Mutex add DEFAULT_MUTEX_ACQUIRED_AFTER to use annotalysis to check the code 150 // doesn't try to hold a higher level Mutex. 151 #define DEFAULT_MUTEX_ACQUIRED_AFTER ACQUIRED_AFTER(classlinker_classes_lock_) 152 153 // Have an exclusive aborting thread. 154 static Mutex* abort_lock_ ACQUIRED_AFTER(classlinker_classes_lock_); 155 156 // Allow mutual exclusion when manipulating Thread::suspend_count_. 157 // TODO: Does the trade-off of a per-thread lock make sense? 158 static Mutex* thread_suspend_count_lock_ ACQUIRED_AFTER(abort_lock_); 159 160 // One unexpected signal at a time lock. 161 static Mutex* unexpected_signal_lock_ ACQUIRED_AFTER(thread_suspend_count_lock_); 162 163 // Have an exclusive logging thread. 164 static Mutex* logging_lock_ ACQUIRED_AFTER(unexpected_signal_lock_); 165 }; 166 167 } // namespace art 168 169 #endif // ART_RUNTIME_LOCKS_H_ 170