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