xref: /aosp_15_r20/art/runtime/base/locks.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2011 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #include "locks.h"
18*795d594fSAndroid Build Coastguard Worker 
19*795d594fSAndroid Build Coastguard Worker #include <errno.h>
20*795d594fSAndroid Build Coastguard Worker #include <sys/time.h>
21*795d594fSAndroid Build Coastguard Worker 
22*795d594fSAndroid Build Coastguard Worker #include "android-base/logging.h"
23*795d594fSAndroid Build Coastguard Worker 
24*795d594fSAndroid Build Coastguard Worker #include "base/atomic.h"
25*795d594fSAndroid Build Coastguard Worker #include "base/logging.h"
26*795d594fSAndroid Build Coastguard Worker #include "base/systrace.h"
27*795d594fSAndroid Build Coastguard Worker #include "base/time_utils.h"
28*795d594fSAndroid Build Coastguard Worker #include "base/value_object.h"
29*795d594fSAndroid Build Coastguard Worker #include "mutex-inl.h"
30*795d594fSAndroid Build Coastguard Worker #include "scoped_thread_state_change-inl.h"
31*795d594fSAndroid Build Coastguard Worker #include "thread-inl.h"
32*795d594fSAndroid Build Coastguard Worker 
33*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
34*795d594fSAndroid Build Coastguard Worker 
35*795d594fSAndroid Build Coastguard Worker static Atomic<Locks::ClientCallback*> safe_to_call_abort_callback(nullptr);
36*795d594fSAndroid Build Coastguard Worker 
37*795d594fSAndroid Build Coastguard Worker Mutex* Locks::abort_lock_ = nullptr;
38*795d594fSAndroid Build Coastguard Worker Mutex* Locks::alloc_tracker_lock_ = nullptr;
39*795d594fSAndroid Build Coastguard Worker Mutex* Locks::allocated_monitor_ids_lock_ = nullptr;
40*795d594fSAndroid Build Coastguard Worker Mutex* Locks::allocated_thread_ids_lock_ = nullptr;
41*795d594fSAndroid Build Coastguard Worker ReaderWriterMutex* Locks::breakpoint_lock_ = nullptr;
42*795d594fSAndroid Build Coastguard Worker ReaderWriterMutex* Locks::classlinker_classes_lock_ = nullptr;
43*795d594fSAndroid Build Coastguard Worker Mutex* Locks::custom_tls_lock_ = nullptr;
44*795d594fSAndroid Build Coastguard Worker Mutex* Locks::deoptimization_lock_ = nullptr;
45*795d594fSAndroid Build Coastguard Worker ReaderWriterMutex* Locks::heap_bitmap_lock_ = nullptr;
46*795d594fSAndroid Build Coastguard Worker Mutex* Locks::instrument_entrypoints_lock_ = nullptr;
47*795d594fSAndroid Build Coastguard Worker Mutex* Locks::intern_table_lock_ = nullptr;
48*795d594fSAndroid Build Coastguard Worker Mutex* Locks::jni_function_table_lock_ = nullptr;
49*795d594fSAndroid Build Coastguard Worker Mutex* Locks::jni_libraries_lock_ = nullptr;
50*795d594fSAndroid Build Coastguard Worker Mutex* Locks::logging_lock_ = nullptr;
51*795d594fSAndroid Build Coastguard Worker Mutex* Locks::modify_ldt_lock_ = nullptr;
52*795d594fSAndroid Build Coastguard Worker MutatorMutex* Locks::mutator_lock_ = nullptr;
53*795d594fSAndroid Build Coastguard Worker Mutex* Locks::profiler_lock_ = nullptr;
54*795d594fSAndroid Build Coastguard Worker ReaderWriterMutex* Locks::verifier_deps_lock_ = nullptr;
55*795d594fSAndroid Build Coastguard Worker ReaderWriterMutex* Locks::oat_file_manager_lock_ = nullptr;
56*795d594fSAndroid Build Coastguard Worker Mutex* Locks::host_dlopen_handles_lock_ = nullptr;
57*795d594fSAndroid Build Coastguard Worker Mutex* Locks::reference_processor_lock_ = nullptr;
58*795d594fSAndroid Build Coastguard Worker Mutex* Locks::reference_queue_cleared_references_lock_ = nullptr;
59*795d594fSAndroid Build Coastguard Worker Mutex* Locks::reference_queue_finalizer_references_lock_ = nullptr;
60*795d594fSAndroid Build Coastguard Worker Mutex* Locks::reference_queue_phantom_references_lock_ = nullptr;
61*795d594fSAndroid Build Coastguard Worker Mutex* Locks::reference_queue_soft_references_lock_ = nullptr;
62*795d594fSAndroid Build Coastguard Worker Mutex* Locks::reference_queue_weak_references_lock_ = nullptr;
63*795d594fSAndroid Build Coastguard Worker Mutex* Locks::runtime_shutdown_lock_ = nullptr;
64*795d594fSAndroid Build Coastguard Worker Mutex* Locks::runtime_thread_pool_lock_ = nullptr;
65*795d594fSAndroid Build Coastguard Worker Mutex* Locks::cha_lock_ = nullptr;
66*795d594fSAndroid Build Coastguard Worker Mutex* Locks::jit_lock_ = nullptr;
67*795d594fSAndroid Build Coastguard Worker ReaderWriterMutex* Locks::jit_mutator_lock_ = nullptr;
68*795d594fSAndroid Build Coastguard Worker Mutex* Locks::subtype_check_lock_ = nullptr;
69*795d594fSAndroid Build Coastguard Worker Mutex* Locks::thread_list_lock_ = nullptr;
70*795d594fSAndroid Build Coastguard Worker ConditionVariable* Locks::thread_exit_cond_ = nullptr;
71*795d594fSAndroid Build Coastguard Worker Mutex* Locks::thread_suspend_count_lock_ = nullptr;
72*795d594fSAndroid Build Coastguard Worker Mutex* Locks::trace_lock_ = nullptr;
73*795d594fSAndroid Build Coastguard Worker Mutex* Locks::unexpected_signal_lock_ = nullptr;
74*795d594fSAndroid Build Coastguard Worker Mutex* Locks::user_code_suspension_lock_ = nullptr;
75*795d594fSAndroid Build Coastguard Worker Uninterruptible Roles::uninterruptible_;
76*795d594fSAndroid Build Coastguard Worker ReaderWriterMutex* Locks::jni_globals_lock_ = nullptr;
77*795d594fSAndroid Build Coastguard Worker Mutex* Locks::jni_weak_globals_lock_ = nullptr;
78*795d594fSAndroid Build Coastguard Worker Mutex* Locks::dex_cache_lock_ = nullptr;
79*795d594fSAndroid Build Coastguard Worker ReaderWriterMutex* Locks::dex_lock_ = nullptr;
80*795d594fSAndroid Build Coastguard Worker Mutex* Locks::native_debug_interface_lock_ = nullptr;
81*795d594fSAndroid Build Coastguard Worker ReaderWriterMutex* Locks::jni_id_lock_ = nullptr;
82*795d594fSAndroid Build Coastguard Worker std::vector<BaseMutex*> Locks::expected_mutexes_on_weak_ref_access_;
83*795d594fSAndroid Build Coastguard Worker Atomic<const BaseMutex*> Locks::expected_mutexes_on_weak_ref_access_guard_;
84*795d594fSAndroid Build Coastguard Worker 
85*795d594fSAndroid Build Coastguard Worker // Wait for an amount of time that roughly increases in the argument i.
86*795d594fSAndroid Build Coastguard Worker // Spin for small arguments and yield/sleep for longer ones.
BackOff(uint32_t i)87*795d594fSAndroid Build Coastguard Worker static void BackOff(uint32_t i) {
88*795d594fSAndroid Build Coastguard Worker   static constexpr uint32_t kSpinMax = 10;
89*795d594fSAndroid Build Coastguard Worker   static constexpr uint32_t kYieldMax = 20;
90*795d594fSAndroid Build Coastguard Worker   if (i <= kSpinMax) {
91*795d594fSAndroid Build Coastguard Worker     // TODO: Esp. in very latency-sensitive cases, consider replacing this with an explicit
92*795d594fSAndroid Build Coastguard Worker     // test-and-test-and-set loop in the caller.  Possibly skip entirely on a uniprocessor.
93*795d594fSAndroid Build Coastguard Worker     volatile uint32_t x = 0;
94*795d594fSAndroid Build Coastguard Worker     const uint32_t spin_count = 10 * i;
95*795d594fSAndroid Build Coastguard Worker     for (uint32_t spin = 0; spin < spin_count; ++spin) {
96*795d594fSAndroid Build Coastguard Worker       x = x + 1;  // Volatile; hence should not be optimized away.
97*795d594fSAndroid Build Coastguard Worker     }
98*795d594fSAndroid Build Coastguard Worker     // TODO: Consider adding x86 PAUSE and/or ARM YIELD here.
99*795d594fSAndroid Build Coastguard Worker   } else if (i <= kYieldMax) {
100*795d594fSAndroid Build Coastguard Worker     sched_yield();
101*795d594fSAndroid Build Coastguard Worker   } else {
102*795d594fSAndroid Build Coastguard Worker     NanoSleep(1000ull * (i - kYieldMax));
103*795d594fSAndroid Build Coastguard Worker   }
104*795d594fSAndroid Build Coastguard Worker }
105*795d594fSAndroid Build Coastguard Worker 
106*795d594fSAndroid Build Coastguard Worker class Locks::ScopedExpectedMutexesOnWeakRefAccessLock final {
107*795d594fSAndroid Build Coastguard Worker  public:
ScopedExpectedMutexesOnWeakRefAccessLock(const BaseMutex * mutex)108*795d594fSAndroid Build Coastguard Worker   explicit ScopedExpectedMutexesOnWeakRefAccessLock(const BaseMutex* mutex) : mutex_(mutex) {
109*795d594fSAndroid Build Coastguard Worker     for (uint32_t i = 0;
110*795d594fSAndroid Build Coastguard Worker          !Locks::expected_mutexes_on_weak_ref_access_guard_.CompareAndSetWeakAcquire(nullptr,
111*795d594fSAndroid Build Coastguard Worker                                                                                      mutex);
112*795d594fSAndroid Build Coastguard Worker          ++i) {
113*795d594fSAndroid Build Coastguard Worker       BackOff(i);
114*795d594fSAndroid Build Coastguard Worker     }
115*795d594fSAndroid Build Coastguard Worker   }
116*795d594fSAndroid Build Coastguard Worker 
~ScopedExpectedMutexesOnWeakRefAccessLock()117*795d594fSAndroid Build Coastguard Worker   ~ScopedExpectedMutexesOnWeakRefAccessLock() {
118*795d594fSAndroid Build Coastguard Worker     DCHECK_EQ(Locks::expected_mutexes_on_weak_ref_access_guard_.load(std::memory_order_relaxed),
119*795d594fSAndroid Build Coastguard Worker               mutex_);
120*795d594fSAndroid Build Coastguard Worker     Locks::expected_mutexes_on_weak_ref_access_guard_.store(nullptr, std::memory_order_release);
121*795d594fSAndroid Build Coastguard Worker   }
122*795d594fSAndroid Build Coastguard Worker 
123*795d594fSAndroid Build Coastguard Worker  private:
124*795d594fSAndroid Build Coastguard Worker   const BaseMutex* const mutex_;
125*795d594fSAndroid Build Coastguard Worker };
126*795d594fSAndroid Build Coastguard Worker 
Init()127*795d594fSAndroid Build Coastguard Worker void Locks::Init() {
128*795d594fSAndroid Build Coastguard Worker   if (logging_lock_ != nullptr) {
129*795d594fSAndroid Build Coastguard Worker     // Already initialized.
130*795d594fSAndroid Build Coastguard Worker     if (kRuntimeISA == InstructionSet::kX86 || kRuntimeISA == InstructionSet::kX86_64) {
131*795d594fSAndroid Build Coastguard Worker       DCHECK(modify_ldt_lock_ != nullptr);
132*795d594fSAndroid Build Coastguard Worker     } else {
133*795d594fSAndroid Build Coastguard Worker       DCHECK(modify_ldt_lock_ == nullptr);
134*795d594fSAndroid Build Coastguard Worker     }
135*795d594fSAndroid Build Coastguard Worker     DCHECK(abort_lock_ != nullptr);
136*795d594fSAndroid Build Coastguard Worker     DCHECK(alloc_tracker_lock_ != nullptr);
137*795d594fSAndroid Build Coastguard Worker     DCHECK(allocated_monitor_ids_lock_ != nullptr);
138*795d594fSAndroid Build Coastguard Worker     DCHECK(allocated_thread_ids_lock_ != nullptr);
139*795d594fSAndroid Build Coastguard Worker     DCHECK(breakpoint_lock_ != nullptr);
140*795d594fSAndroid Build Coastguard Worker     DCHECK(classlinker_classes_lock_ != nullptr);
141*795d594fSAndroid Build Coastguard Worker     DCHECK(custom_tls_lock_ != nullptr);
142*795d594fSAndroid Build Coastguard Worker     DCHECK(deoptimization_lock_ != nullptr);
143*795d594fSAndroid Build Coastguard Worker     DCHECK(heap_bitmap_lock_ != nullptr);
144*795d594fSAndroid Build Coastguard Worker     DCHECK(oat_file_manager_lock_ != nullptr);
145*795d594fSAndroid Build Coastguard Worker     DCHECK(verifier_deps_lock_ != nullptr);
146*795d594fSAndroid Build Coastguard Worker     DCHECK(host_dlopen_handles_lock_ != nullptr);
147*795d594fSAndroid Build Coastguard Worker     DCHECK(intern_table_lock_ != nullptr);
148*795d594fSAndroid Build Coastguard Worker     DCHECK(jni_function_table_lock_ != nullptr);
149*795d594fSAndroid Build Coastguard Worker     DCHECK(jni_libraries_lock_ != nullptr);
150*795d594fSAndroid Build Coastguard Worker     DCHECK(logging_lock_ != nullptr);
151*795d594fSAndroid Build Coastguard Worker     DCHECK(mutator_lock_ != nullptr);
152*795d594fSAndroid Build Coastguard Worker     DCHECK(profiler_lock_ != nullptr);
153*795d594fSAndroid Build Coastguard Worker     DCHECK(cha_lock_ != nullptr);
154*795d594fSAndroid Build Coastguard Worker     DCHECK(jit_lock_ != nullptr);
155*795d594fSAndroid Build Coastguard Worker     DCHECK(jit_mutator_lock_ != nullptr);
156*795d594fSAndroid Build Coastguard Worker     DCHECK(subtype_check_lock_ != nullptr);
157*795d594fSAndroid Build Coastguard Worker     DCHECK(thread_list_lock_ != nullptr);
158*795d594fSAndroid Build Coastguard Worker     DCHECK(thread_suspend_count_lock_ != nullptr);
159*795d594fSAndroid Build Coastguard Worker     DCHECK(trace_lock_ != nullptr);
160*795d594fSAndroid Build Coastguard Worker     DCHECK(unexpected_signal_lock_ != nullptr);
161*795d594fSAndroid Build Coastguard Worker     DCHECK(user_code_suspension_lock_ != nullptr);
162*795d594fSAndroid Build Coastguard Worker     DCHECK(dex_lock_ != nullptr);
163*795d594fSAndroid Build Coastguard Worker     DCHECK(native_debug_interface_lock_ != nullptr);
164*795d594fSAndroid Build Coastguard Worker     DCHECK(jni_id_lock_ != nullptr);
165*795d594fSAndroid Build Coastguard Worker     DCHECK(runtime_thread_pool_lock_ != nullptr);
166*795d594fSAndroid Build Coastguard Worker   } else {
167*795d594fSAndroid Build Coastguard Worker     // Create global locks in level order from highest lock level to lowest.
168*795d594fSAndroid Build Coastguard Worker     LockLevel current_lock_level = kUserCodeSuspensionLock;
169*795d594fSAndroid Build Coastguard Worker     DCHECK(user_code_suspension_lock_ == nullptr);
170*795d594fSAndroid Build Coastguard Worker     user_code_suspension_lock_ = new Mutex("user code suspension lock", current_lock_level);
171*795d594fSAndroid Build Coastguard Worker 
172*795d594fSAndroid Build Coastguard Worker     #define UPDATE_CURRENT_LOCK_LEVEL(new_level) \
173*795d594fSAndroid Build Coastguard Worker       if ((new_level) >= current_lock_level) { \
174*795d594fSAndroid Build Coastguard Worker         /* Do not use CHECKs or FATAL here, abort_lock_ is not setup yet. */ \
175*795d594fSAndroid Build Coastguard Worker         fprintf(stderr, "New local level %d is not less than current level %d\n", \
176*795d594fSAndroid Build Coastguard Worker                 new_level, current_lock_level); \
177*795d594fSAndroid Build Coastguard Worker         exit(1); \
178*795d594fSAndroid Build Coastguard Worker       } \
179*795d594fSAndroid Build Coastguard Worker       current_lock_level = new_level;
180*795d594fSAndroid Build Coastguard Worker 
181*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kInstrumentEntrypointsLock);
182*795d594fSAndroid Build Coastguard Worker     DCHECK(instrument_entrypoints_lock_ == nullptr);
183*795d594fSAndroid Build Coastguard Worker     instrument_entrypoints_lock_ = new Mutex("instrument entrypoint lock", current_lock_level);
184*795d594fSAndroid Build Coastguard Worker 
185*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kMutatorLock);
186*795d594fSAndroid Build Coastguard Worker     DCHECK(mutator_lock_ == nullptr);
187*795d594fSAndroid Build Coastguard Worker     mutator_lock_ = new MutatorMutex("mutator lock", current_lock_level);
188*795d594fSAndroid Build Coastguard Worker 
189*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kHeapBitmapLock);
190*795d594fSAndroid Build Coastguard Worker     DCHECK(heap_bitmap_lock_ == nullptr);
191*795d594fSAndroid Build Coastguard Worker     heap_bitmap_lock_ = new ReaderWriterMutex("heap bitmap lock", current_lock_level);
192*795d594fSAndroid Build Coastguard Worker 
193*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kTraceLock);
194*795d594fSAndroid Build Coastguard Worker     DCHECK(trace_lock_ == nullptr);
195*795d594fSAndroid Build Coastguard Worker     trace_lock_ = new Mutex("trace lock", current_lock_level);
196*795d594fSAndroid Build Coastguard Worker 
197*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kRuntimeShutdownLock);
198*795d594fSAndroid Build Coastguard Worker     DCHECK(runtime_shutdown_lock_ == nullptr);
199*795d594fSAndroid Build Coastguard Worker     runtime_shutdown_lock_ = new Mutex("runtime shutdown lock", current_lock_level);
200*795d594fSAndroid Build Coastguard Worker 
201*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kRuntimeThreadPoolLock);
202*795d594fSAndroid Build Coastguard Worker     DCHECK(runtime_thread_pool_lock_ == nullptr);
203*795d594fSAndroid Build Coastguard Worker     runtime_thread_pool_lock_ = new Mutex("runtime thread pool lock", current_lock_level);
204*795d594fSAndroid Build Coastguard Worker 
205*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kProfilerLock);
206*795d594fSAndroid Build Coastguard Worker     DCHECK(profiler_lock_ == nullptr);
207*795d594fSAndroid Build Coastguard Worker     profiler_lock_ = new Mutex("profiler lock", current_lock_level);
208*795d594fSAndroid Build Coastguard Worker 
209*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kDeoptimizationLock);
210*795d594fSAndroid Build Coastguard Worker     DCHECK(deoptimization_lock_ == nullptr);
211*795d594fSAndroid Build Coastguard Worker     deoptimization_lock_ = new Mutex("Deoptimization lock", current_lock_level);
212*795d594fSAndroid Build Coastguard Worker 
213*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kAllocTrackerLock);
214*795d594fSAndroid Build Coastguard Worker     DCHECK(alloc_tracker_lock_ == nullptr);
215*795d594fSAndroid Build Coastguard Worker     alloc_tracker_lock_ = new Mutex("AllocTracker lock", current_lock_level);
216*795d594fSAndroid Build Coastguard Worker 
217*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kThreadListLock);
218*795d594fSAndroid Build Coastguard Worker     DCHECK(thread_list_lock_ == nullptr);
219*795d594fSAndroid Build Coastguard Worker     thread_list_lock_ = new Mutex("thread list lock", current_lock_level);
220*795d594fSAndroid Build Coastguard Worker 
221*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kBreakpointLock);
222*795d594fSAndroid Build Coastguard Worker     DCHECK(breakpoint_lock_ == nullptr);
223*795d594fSAndroid Build Coastguard Worker     breakpoint_lock_ = new ReaderWriterMutex("breakpoint lock", current_lock_level);
224*795d594fSAndroid Build Coastguard Worker 
225*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kSubtypeCheckLock);
226*795d594fSAndroid Build Coastguard Worker     DCHECK(subtype_check_lock_ == nullptr);
227*795d594fSAndroid Build Coastguard Worker     subtype_check_lock_ = new Mutex("SubtypeCheck lock", current_lock_level);
228*795d594fSAndroid Build Coastguard Worker 
229*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kClassLinkerClassesLock);
230*795d594fSAndroid Build Coastguard Worker     DCHECK(classlinker_classes_lock_ == nullptr);
231*795d594fSAndroid Build Coastguard Worker     classlinker_classes_lock_ = new ReaderWriterMutex("ClassLinker classes lock",
232*795d594fSAndroid Build Coastguard Worker                                                       current_lock_level);
233*795d594fSAndroid Build Coastguard Worker 
234*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kMonitorPoolLock);
235*795d594fSAndroid Build Coastguard Worker     DCHECK(allocated_monitor_ids_lock_ == nullptr);
236*795d594fSAndroid Build Coastguard Worker     allocated_monitor_ids_lock_ =  new Mutex("allocated monitor ids lock", current_lock_level);
237*795d594fSAndroid Build Coastguard Worker 
238*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kAllocatedThreadIdsLock);
239*795d594fSAndroid Build Coastguard Worker     DCHECK(allocated_thread_ids_lock_ == nullptr);
240*795d594fSAndroid Build Coastguard Worker     allocated_thread_ids_lock_ =  new Mutex("allocated thread ids lock", current_lock_level);
241*795d594fSAndroid Build Coastguard Worker 
242*795d594fSAndroid Build Coastguard Worker     if (kRuntimeISA == InstructionSet::kX86 || kRuntimeISA == InstructionSet::kX86_64) {
243*795d594fSAndroid Build Coastguard Worker       UPDATE_CURRENT_LOCK_LEVEL(kModifyLdtLock);
244*795d594fSAndroid Build Coastguard Worker       DCHECK(modify_ldt_lock_ == nullptr);
245*795d594fSAndroid Build Coastguard Worker       modify_ldt_lock_ = new Mutex("modify_ldt lock", current_lock_level);
246*795d594fSAndroid Build Coastguard Worker     }
247*795d594fSAndroid Build Coastguard Worker 
248*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kDexLock);
249*795d594fSAndroid Build Coastguard Worker     DCHECK(dex_lock_ == nullptr);
250*795d594fSAndroid Build Coastguard Worker     dex_lock_ = new ReaderWriterMutex("ClassLinker dex lock", current_lock_level);
251*795d594fSAndroid Build Coastguard Worker 
252*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kDexCacheLock);
253*795d594fSAndroid Build Coastguard Worker     DCHECK(dex_cache_lock_ == nullptr);
254*795d594fSAndroid Build Coastguard Worker     dex_cache_lock_ = new Mutex("DexCache lock", current_lock_level);
255*795d594fSAndroid Build Coastguard Worker 
256*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kJniLoadLibraryLock);
257*795d594fSAndroid Build Coastguard Worker     DCHECK(jni_libraries_lock_ == nullptr);
258*795d594fSAndroid Build Coastguard Worker     jni_libraries_lock_ = new Mutex("JNI shared libraries map lock", current_lock_level);
259*795d594fSAndroid Build Coastguard Worker 
260*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kOatFileManagerLock);
261*795d594fSAndroid Build Coastguard Worker     DCHECK(oat_file_manager_lock_ == nullptr);
262*795d594fSAndroid Build Coastguard Worker     oat_file_manager_lock_ = new ReaderWriterMutex("OatFile manager lock", current_lock_level);
263*795d594fSAndroid Build Coastguard Worker 
264*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kVerifierDepsLock);
265*795d594fSAndroid Build Coastguard Worker     DCHECK(verifier_deps_lock_ == nullptr);
266*795d594fSAndroid Build Coastguard Worker     verifier_deps_lock_ = new ReaderWriterMutex("verifier deps lock", current_lock_level);
267*795d594fSAndroid Build Coastguard Worker 
268*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kHostDlOpenHandlesLock);
269*795d594fSAndroid Build Coastguard Worker     DCHECK(host_dlopen_handles_lock_ == nullptr);
270*795d594fSAndroid Build Coastguard Worker     host_dlopen_handles_lock_ = new Mutex("host dlopen handles lock", current_lock_level);
271*795d594fSAndroid Build Coastguard Worker 
272*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kInternTableLock);
273*795d594fSAndroid Build Coastguard Worker     DCHECK(intern_table_lock_ == nullptr);
274*795d594fSAndroid Build Coastguard Worker     intern_table_lock_ = new Mutex("InternTable lock", current_lock_level);
275*795d594fSAndroid Build Coastguard Worker 
276*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kReferenceProcessorLock);
277*795d594fSAndroid Build Coastguard Worker     DCHECK(reference_processor_lock_ == nullptr);
278*795d594fSAndroid Build Coastguard Worker     reference_processor_lock_ = new Mutex("ReferenceProcessor lock", current_lock_level);
279*795d594fSAndroid Build Coastguard Worker 
280*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kReferenceQueueClearedReferencesLock);
281*795d594fSAndroid Build Coastguard Worker     DCHECK(reference_queue_cleared_references_lock_ == nullptr);
282*795d594fSAndroid Build Coastguard Worker     reference_queue_cleared_references_lock_ = new Mutex("ReferenceQueue cleared references lock", current_lock_level);
283*795d594fSAndroid Build Coastguard Worker 
284*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kReferenceQueueWeakReferencesLock);
285*795d594fSAndroid Build Coastguard Worker     DCHECK(reference_queue_weak_references_lock_ == nullptr);
286*795d594fSAndroid Build Coastguard Worker     reference_queue_weak_references_lock_ = new Mutex("ReferenceQueue cleared references lock", current_lock_level);
287*795d594fSAndroid Build Coastguard Worker 
288*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kReferenceQueueFinalizerReferencesLock);
289*795d594fSAndroid Build Coastguard Worker     DCHECK(reference_queue_finalizer_references_lock_ == nullptr);
290*795d594fSAndroid Build Coastguard Worker     reference_queue_finalizer_references_lock_ = new Mutex("ReferenceQueue finalizer references lock", current_lock_level);
291*795d594fSAndroid Build Coastguard Worker 
292*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kReferenceQueuePhantomReferencesLock);
293*795d594fSAndroid Build Coastguard Worker     DCHECK(reference_queue_phantom_references_lock_ == nullptr);
294*795d594fSAndroid Build Coastguard Worker     reference_queue_phantom_references_lock_ = new Mutex("ReferenceQueue phantom references lock", current_lock_level);
295*795d594fSAndroid Build Coastguard Worker 
296*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kReferenceQueueSoftReferencesLock);
297*795d594fSAndroid Build Coastguard Worker     DCHECK(reference_queue_soft_references_lock_ == nullptr);
298*795d594fSAndroid Build Coastguard Worker     reference_queue_soft_references_lock_ = new Mutex("ReferenceQueue soft references lock", current_lock_level);
299*795d594fSAndroid Build Coastguard Worker 
300*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kJniGlobalsLock);
301*795d594fSAndroid Build Coastguard Worker     DCHECK(jni_globals_lock_ == nullptr);
302*795d594fSAndroid Build Coastguard Worker     jni_globals_lock_ =
303*795d594fSAndroid Build Coastguard Worker         new ReaderWriterMutex("JNI global reference table lock", current_lock_level);
304*795d594fSAndroid Build Coastguard Worker 
305*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kJniWeakGlobalsLock);
306*795d594fSAndroid Build Coastguard Worker     DCHECK(jni_weak_globals_lock_ == nullptr);
307*795d594fSAndroid Build Coastguard Worker     jni_weak_globals_lock_ = new Mutex("JNI weak global reference table lock", current_lock_level);
308*795d594fSAndroid Build Coastguard Worker 
309*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kJniFunctionTableLock);
310*795d594fSAndroid Build Coastguard Worker     DCHECK(jni_function_table_lock_ == nullptr);
311*795d594fSAndroid Build Coastguard Worker     jni_function_table_lock_ = new Mutex("JNI function table lock", current_lock_level);
312*795d594fSAndroid Build Coastguard Worker 
313*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kCustomTlsLock);
314*795d594fSAndroid Build Coastguard Worker     DCHECK(custom_tls_lock_ == nullptr);
315*795d594fSAndroid Build Coastguard Worker     custom_tls_lock_ = new Mutex("Thread::custom_tls_ lock", current_lock_level);
316*795d594fSAndroid Build Coastguard Worker 
317*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kJitCodeCacheLock);
318*795d594fSAndroid Build Coastguard Worker     DCHECK(jit_lock_ == nullptr);
319*795d594fSAndroid Build Coastguard Worker     jit_lock_ = new Mutex("Jit code cache", current_lock_level);
320*795d594fSAndroid Build Coastguard Worker 
321*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kJitCodeCacheMutatorAndCHALock);
322*795d594fSAndroid Build Coastguard Worker     DCHECK(jit_mutator_lock_ == nullptr);
323*795d594fSAndroid Build Coastguard Worker     jit_mutator_lock_ = new ReaderWriterMutex("Jit code cache for mutator", current_lock_level);
324*795d594fSAndroid Build Coastguard Worker 
325*795d594fSAndroid Build Coastguard Worker     DCHECK(cha_lock_ == nullptr);
326*795d594fSAndroid Build Coastguard Worker     cha_lock_ = new Mutex("CHA lock", current_lock_level);
327*795d594fSAndroid Build Coastguard Worker 
328*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kNativeDebugInterfaceLock);
329*795d594fSAndroid Build Coastguard Worker     DCHECK(native_debug_interface_lock_ == nullptr);
330*795d594fSAndroid Build Coastguard Worker     native_debug_interface_lock_ = new Mutex("Native debug interface lock", current_lock_level);
331*795d594fSAndroid Build Coastguard Worker 
332*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kJniIdLock);
333*795d594fSAndroid Build Coastguard Worker     DCHECK(jni_id_lock_ == nullptr);
334*795d594fSAndroid Build Coastguard Worker     jni_id_lock_ = new ReaderWriterMutex("JNI id map lock", current_lock_level);
335*795d594fSAndroid Build Coastguard Worker 
336*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kAbortLock);
337*795d594fSAndroid Build Coastguard Worker     DCHECK(abort_lock_ == nullptr);
338*795d594fSAndroid Build Coastguard Worker     abort_lock_ = new Mutex("abort lock", current_lock_level, true);
339*795d594fSAndroid Build Coastguard Worker 
340*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kThreadSuspendCountLock);
341*795d594fSAndroid Build Coastguard Worker     DCHECK(thread_suspend_count_lock_ == nullptr);
342*795d594fSAndroid Build Coastguard Worker     thread_suspend_count_lock_ = new Mutex("thread suspend count lock", current_lock_level);
343*795d594fSAndroid Build Coastguard Worker 
344*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kUnexpectedSignalLock);
345*795d594fSAndroid Build Coastguard Worker     DCHECK(unexpected_signal_lock_ == nullptr);
346*795d594fSAndroid Build Coastguard Worker     unexpected_signal_lock_ = new Mutex("unexpected signal lock", current_lock_level, true);
347*795d594fSAndroid Build Coastguard Worker 
348*795d594fSAndroid Build Coastguard Worker     UPDATE_CURRENT_LOCK_LEVEL(kLoggingLock);
349*795d594fSAndroid Build Coastguard Worker     DCHECK(logging_lock_ == nullptr);
350*795d594fSAndroid Build Coastguard Worker     logging_lock_ = new Mutex("logging lock", current_lock_level, true);
351*795d594fSAndroid Build Coastguard Worker 
352*795d594fSAndroid Build Coastguard Worker     #undef UPDATE_CURRENT_LOCK_LEVEL
353*795d594fSAndroid Build Coastguard Worker 
354*795d594fSAndroid Build Coastguard Worker     // List of mutexes that we may hold when accessing a weak ref.
355*795d594fSAndroid Build Coastguard Worker     AddToExpectedMutexesOnWeakRefAccess(dex_lock_, /*need_lock=*/ false);
356*795d594fSAndroid Build Coastguard Worker     AddToExpectedMutexesOnWeakRefAccess(classlinker_classes_lock_, /*need_lock=*/ false);
357*795d594fSAndroid Build Coastguard Worker     AddToExpectedMutexesOnWeakRefAccess(jni_libraries_lock_, /*need_lock=*/ false);
358*795d594fSAndroid Build Coastguard Worker 
359*795d594fSAndroid Build Coastguard Worker     InitConditions();
360*795d594fSAndroid Build Coastguard Worker   }
361*795d594fSAndroid Build Coastguard Worker }
362*795d594fSAndroid Build Coastguard Worker 
InitConditions()363*795d594fSAndroid Build Coastguard Worker void Locks::InitConditions() {
364*795d594fSAndroid Build Coastguard Worker   thread_exit_cond_ = new ConditionVariable("thread exit condition variable", *thread_list_lock_);
365*795d594fSAndroid Build Coastguard Worker }
366*795d594fSAndroid Build Coastguard Worker 
SetClientCallback(ClientCallback * safe_to_call_abort_cb)367*795d594fSAndroid Build Coastguard Worker void Locks::SetClientCallback(ClientCallback* safe_to_call_abort_cb) {
368*795d594fSAndroid Build Coastguard Worker   safe_to_call_abort_callback.store(safe_to_call_abort_cb, std::memory_order_release);
369*795d594fSAndroid Build Coastguard Worker }
370*795d594fSAndroid Build Coastguard Worker 
371*795d594fSAndroid Build Coastguard Worker // Helper to allow checking shutdown while ignoring locking requirements.
IsSafeToCallAbortRacy()372*795d594fSAndroid Build Coastguard Worker bool Locks::IsSafeToCallAbortRacy() {
373*795d594fSAndroid Build Coastguard Worker   Locks::ClientCallback* safe_to_call_abort_cb =
374*795d594fSAndroid Build Coastguard Worker       safe_to_call_abort_callback.load(std::memory_order_acquire);
375*795d594fSAndroid Build Coastguard Worker   return safe_to_call_abort_cb != nullptr && safe_to_call_abort_cb();
376*795d594fSAndroid Build Coastguard Worker }
377*795d594fSAndroid Build Coastguard Worker 
AddToExpectedMutexesOnWeakRefAccess(BaseMutex * mutex,bool need_lock)378*795d594fSAndroid Build Coastguard Worker void Locks::AddToExpectedMutexesOnWeakRefAccess(BaseMutex* mutex, bool need_lock) {
379*795d594fSAndroid Build Coastguard Worker   if (need_lock) {
380*795d594fSAndroid Build Coastguard Worker     ScopedExpectedMutexesOnWeakRefAccessLock mu(mutex);
381*795d594fSAndroid Build Coastguard Worker     mutex->SetShouldRespondToEmptyCheckpointRequest(true);
382*795d594fSAndroid Build Coastguard Worker     expected_mutexes_on_weak_ref_access_.push_back(mutex);
383*795d594fSAndroid Build Coastguard Worker   } else {
384*795d594fSAndroid Build Coastguard Worker     mutex->SetShouldRespondToEmptyCheckpointRequest(true);
385*795d594fSAndroid Build Coastguard Worker     expected_mutexes_on_weak_ref_access_.push_back(mutex);
386*795d594fSAndroid Build Coastguard Worker   }
387*795d594fSAndroid Build Coastguard Worker }
388*795d594fSAndroid Build Coastguard Worker 
RemoveFromExpectedMutexesOnWeakRefAccess(BaseMutex * mutex,bool need_lock)389*795d594fSAndroid Build Coastguard Worker void Locks::RemoveFromExpectedMutexesOnWeakRefAccess(BaseMutex* mutex, bool need_lock) {
390*795d594fSAndroid Build Coastguard Worker   if (need_lock) {
391*795d594fSAndroid Build Coastguard Worker     ScopedExpectedMutexesOnWeakRefAccessLock mu(mutex);
392*795d594fSAndroid Build Coastguard Worker     mutex->SetShouldRespondToEmptyCheckpointRequest(false);
393*795d594fSAndroid Build Coastguard Worker     std::vector<BaseMutex*>& list = expected_mutexes_on_weak_ref_access_;
394*795d594fSAndroid Build Coastguard Worker     auto it = std::find(list.begin(), list.end(), mutex);
395*795d594fSAndroid Build Coastguard Worker     DCHECK(it != list.end());
396*795d594fSAndroid Build Coastguard Worker     list.erase(it);
397*795d594fSAndroid Build Coastguard Worker   } else {
398*795d594fSAndroid Build Coastguard Worker     mutex->SetShouldRespondToEmptyCheckpointRequest(false);
399*795d594fSAndroid Build Coastguard Worker     std::vector<BaseMutex*>& list = expected_mutexes_on_weak_ref_access_;
400*795d594fSAndroid Build Coastguard Worker     auto it = std::find(list.begin(), list.end(), mutex);
401*795d594fSAndroid Build Coastguard Worker     DCHECK(it != list.end());
402*795d594fSAndroid Build Coastguard Worker     list.erase(it);
403*795d594fSAndroid Build Coastguard Worker   }
404*795d594fSAndroid Build Coastguard Worker }
405*795d594fSAndroid Build Coastguard Worker 
IsExpectedOnWeakRefAccess(BaseMutex * mutex)406*795d594fSAndroid Build Coastguard Worker bool Locks::IsExpectedOnWeakRefAccess(BaseMutex* mutex) {
407*795d594fSAndroid Build Coastguard Worker   ScopedExpectedMutexesOnWeakRefAccessLock mu(mutex);
408*795d594fSAndroid Build Coastguard Worker   std::vector<BaseMutex*>& list = expected_mutexes_on_weak_ref_access_;
409*795d594fSAndroid Build Coastguard Worker   return std::find(list.begin(), list.end(), mutex) != list.end();
410*795d594fSAndroid Build Coastguard Worker }
411*795d594fSAndroid Build Coastguard Worker 
412*795d594fSAndroid Build Coastguard Worker }  // namespace art
413