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