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 "mutex.h" 18 19 #include <errno.h> 20 #include <sys/time.h> 21 22 #include "android-base/stringprintf.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 using android::base::StringPrintf; 36 37 static Atomic<Locks::ClientCallback*> safe_to_call_abort_callback(nullptr); 38 39 Mutex* Locks::abort_lock_ = nullptr; 40 Mutex* Locks::alloc_tracker_lock_ = nullptr; 41 Mutex* Locks::allocated_monitor_ids_lock_ = nullptr; 42 Mutex* Locks::allocated_thread_ids_lock_ = nullptr; 43 ReaderWriterMutex* Locks::breakpoint_lock_ = nullptr; 44 ReaderWriterMutex* Locks::classlinker_classes_lock_ = nullptr; 45 Mutex* Locks::deoptimization_lock_ = nullptr; 46 ReaderWriterMutex* Locks::heap_bitmap_lock_ = nullptr; 47 Mutex* Locks::instrument_entrypoints_lock_ = nullptr; 48 Mutex* Locks::intern_table_lock_ = nullptr; 49 Mutex* Locks::jni_function_table_lock_ = nullptr; 50 Mutex* Locks::jni_libraries_lock_ = nullptr; 51 Mutex* Locks::logging_lock_ = nullptr; 52 Mutex* Locks::modify_ldt_lock_ = nullptr; 53 MutatorMutex* Locks::mutator_lock_ = nullptr; 54 Mutex* Locks::profiler_lock_ = nullptr; 55 ReaderWriterMutex* Locks::verifier_deps_lock_ = nullptr; 56 ReaderWriterMutex* Locks::oat_file_manager_lock_ = nullptr; 57 Mutex* Locks::host_dlopen_handles_lock_ = nullptr; 58 Mutex* Locks::reference_processor_lock_ = nullptr; 59 Mutex* Locks::reference_queue_cleared_references_lock_ = nullptr; 60 Mutex* Locks::reference_queue_finalizer_references_lock_ = nullptr; 61 Mutex* Locks::reference_queue_phantom_references_lock_ = nullptr; 62 Mutex* Locks::reference_queue_soft_references_lock_ = nullptr; 63 Mutex* Locks::reference_queue_weak_references_lock_ = nullptr; 64 Mutex* Locks::runtime_shutdown_lock_ = nullptr; 65 Mutex* Locks::cha_lock_ = nullptr; 66 Mutex* Locks::subtype_check_lock_ = nullptr; 67 Mutex* Locks::thread_list_lock_ = nullptr; 68 ConditionVariable* Locks::thread_exit_cond_ = nullptr; 69 Mutex* Locks::thread_suspend_count_lock_ = nullptr; 70 Mutex* Locks::trace_lock_ = nullptr; 71 Mutex* Locks::unexpected_signal_lock_ = nullptr; 72 Mutex* Locks::user_code_suspension_lock_ = nullptr; 73 Uninterruptible Roles::uninterruptible_; 74 ReaderWriterMutex* Locks::jni_globals_lock_ = nullptr; 75 Mutex* Locks::jni_weak_globals_lock_ = nullptr; 76 ReaderWriterMutex* Locks::dex_lock_ = nullptr; 77 Mutex* Locks::native_debug_interface_lock_ = nullptr; 78 std::vector<BaseMutex*> Locks::expected_mutexes_on_weak_ref_access_; 79 Atomic<const BaseMutex*> Locks::expected_mutexes_on_weak_ref_access_guard_; 80 81 struct AllMutexData { 82 // A guard for all_mutexes_ that's not a mutex (Mutexes must CAS to acquire and busy wait). 83 Atomic<const BaseMutex*> all_mutexes_guard; 84 // All created mutexes guarded by all_mutexes_guard_. 85 std::set<BaseMutex*>* all_mutexes; 86 AllMutexData() : all_mutexes(nullptr) {} 87 }; 88 static struct AllMutexData gAllMutexData[kAllMutexDataSize]; 89 90 #if ART_USE_FUTEXES 91 static bool ComputeRelativeTimeSpec(timespec* result_ts, const timespec& lhs, const timespec& rhs) { 92 const int32_t one_sec = 1000 * 1000 * 1000; // one second in nanoseconds. 93 result_ts->tv_sec = lhs.tv_sec - rhs.tv_sec; 94 result_ts->tv_nsec = lhs.tv_nsec - rhs.tv_nsec; 95 if (result_ts->tv_nsec < 0) { 96 result_ts->tv_sec--; 97 result_ts->tv_nsec += one_sec; 98 } else if (result_ts->tv_nsec > one_sec) { 99 result_ts->tv_sec++; 100 result_ts->tv_nsec -= one_sec; 101 } 102 return result_ts->tv_sec < 0; 103 } 104 #endif 105 106 // Wait for an amount of time that roughly increases in the argument i. 107 // Spin for small arguments and yield/sleep for longer ones. 108 static void BackOff(uint32_t i) { 109 static constexpr uint32_t kSpinMax = 10; 110 static constexpr uint32_t kYieldMax = 20; 111 if (i <= kSpinMax) { 112 // TODO: Esp. in very latency-sensitive cases, consider replacing this with an explicit 113 // test-and-test-and-set loop in the caller. Possibly skip entirely on a uniprocessor. 114 volatile uint32_t x = 0; 115 const uint32_t spin_count = 10 * i; 116 for (uint32_t spin = 0; spin < spin_count; ++spin) { 117 ++x; // Volatile; hence should not be optimized away. 118 } 119 // TODO: Consider adding x86 PAUSE and/or ARM YIELD here. 120 } else if (i <= kYieldMax) { 121 sched_yield(); 122 } else { 123 NanoSleep(1000ull * (i - kYieldMax)); 124 } 125 } 126 127 class ScopedAllMutexesLock FINAL { 128 public: 129 explicit ScopedAllMutexesLock(const BaseMutex* mutex) : mutex_(mutex) { 130 for (uint32_t i = 0; 131 !gAllMutexData->all_mutexes_guard.CompareAndSetWeakAcquire(0, mutex); 132 ++i) { 133 BackOff(i); 134 } 135 } 136 137 ~ScopedAllMutexesLock() { 138 DCHECK_EQ(gAllMutexData->all_mutexes_guard.LoadRelaxed(), mutex_); 139 gAllMutexData->all_mutexes_guard.StoreRelease(0); 140 } 141 142 private: 143 const BaseMutex* const mutex_; 144 }; 145 146 class Locks::ScopedExpectedMutexesOnWeakRefAccessLock FINAL { 147 public: 148 explicit ScopedExpectedMutexesOnWeakRefAccessLock(const BaseMutex* mutex) : mutex_(mutex) { 149 for (uint32_t i = 0; 150 !Locks::expected_mutexes_on_weak_ref_access_guard_.CompareAndSetWeakAcquire(0, mutex); 151 ++i) { 152 BackOff(i); 153 } 154 } 155 156 ~ScopedExpectedMutexesOnWeakRefAccessLock() { 157 DCHECK_EQ(Locks::expected_mutexes_on_weak_ref_access_guard_.LoadRelaxed(), mutex_); 158 Locks::expected_mutexes_on_weak_ref_access_guard_.StoreRelease(0); 159 } 160 161 private: 162 const BaseMutex* const mutex_; 163 }; 164 165 // Scoped class that generates events at the beginning and end of lock contention. 166 class ScopedContentionRecorder FINAL : public ValueObject { 167 public: 168 ScopedContentionRecorder(BaseMutex* mutex, uint64_t blocked_tid, uint64_t owner_tid) 169 : mutex_(kLogLockContentions ? mutex : nullptr), 170 blocked_tid_(kLogLockContentions ? blocked_tid : 0), 171 owner_tid_(kLogLockContentions ? owner_tid : 0), 172 start_nano_time_(kLogLockContentions ? NanoTime() : 0) { 173 if (ATRACE_ENABLED()) { 174 std::string msg = StringPrintf("Lock contention on %s (owner tid: %" PRIu64 ")", 175 mutex->GetName(), owner_tid); 176 ATRACE_BEGIN(msg.c_str()); 177 } 178 } 179 180 ~ScopedContentionRecorder() { 181 ATRACE_END(); 182 if (kLogLockContentions) { 183 uint64_t end_nano_time = NanoTime(); 184 mutex_->RecordContention(blocked_tid_, owner_tid_, end_nano_time - start_nano_time_); 185 } 186 } 187 188 private: 189 BaseMutex* const mutex_; 190 const uint64_t blocked_tid_; 191 const uint64_t owner_tid_; 192 const uint64_t start_nano_time_; 193 }; 194 195 BaseMutex::BaseMutex(const char* name, LockLevel level) 196 : level_(level), 197 name_(name), 198 should_respond_to_empty_checkpoint_request_(false) { 199 if (kLogLockContentions) { 200 ScopedAllMutexesLock mu(this); 201 std::set<BaseMutex*>** all_mutexes_ptr = &gAllMutexData->all_mutexes; 202 if (*all_mutexes_ptr == nullptr) { 203 // We leak the global set of all mutexes to avoid ordering issues in global variable 204 // construction/destruction. 205 *all_mutexes_ptr = new std::set<BaseMutex*>(); 206 } 207 (*all_mutexes_ptr)->insert(this); 208 } 209 } 210 211 BaseMutex::~BaseMutex() { 212 if (kLogLockContentions) { 213 ScopedAllMutexesLock mu(this); 214 gAllMutexData->all_mutexes->erase(this); 215 } 216 } 217 218 void BaseMutex::DumpAll(std::ostream& os) { 219 if (kLogLockContentions) { 220 os << "Mutex logging:\n"; 221 ScopedAllMutexesLock mu(reinterpret_cast<const BaseMutex*>(-1)); 222 std::set<BaseMutex*>* all_mutexes = gAllMutexData->all_mutexes; 223 if (all_mutexes == nullptr) { 224 // No mutexes have been created yet during at startup. 225 return; 226 } 227 typedef std::set<BaseMutex*>::const_iterator It; 228 os << "(Contended)\n"; 229 for (It it = all_mutexes->begin(); it != all_mutexes->end(); ++it) { 230 BaseMutex* mutex = *it; 231 if (mutex->HasEverContended()) { 232 mutex->Dump(os); 233 os << "\n"; 234 } 235 } 236 os << "(Never contented)\n"; 237 for (It it = all_mutexes->begin(); it != all_mutexes->end(); ++it) { 238 BaseMutex* mutex = *it; 239 if (!mutex->HasEverContended()) { 240 mutex->Dump(os); 241 os << "\n"; 242 } 243 } 244 } 245 } 246 247 void BaseMutex::CheckSafeToWait(Thread* self) { 248 if (self == nullptr) { 249 CheckUnattachedThread(level_); 250 return; 251 } 252 if (kDebugLocking) { 253 CHECK(self->GetHeldMutex(level_) == this || level_ == kMonitorLock) 254 << "Waiting on unacquired mutex: " << name_; 255 bool bad_mutexes_held = false; 256 for (int i = kLockLevelCount - 1; i >= 0; --i) { 257 if (i != level_) { 258 BaseMutex* held_mutex = self->GetHeldMutex(static_cast<LockLevel>(i)); 259 // We allow the thread to wait even if the user_code_suspension_lock_ is held so long as we 260 // are some thread's resume_cond_ (level_ == kThreadSuspendCountLock). This just means that 261 // gc or some other internal process is suspending the thread while it is trying to suspend 262 // some other thread. So long as the current thread is not being suspended by a 263 // SuspendReason::kForUserCode (which needs the user_code_suspension_lock_ to clear) this is 264 // fine. 265 if (held_mutex == Locks::user_code_suspension_lock_ && level_ == kThreadSuspendCountLock) { 266 // No thread safety analysis is fine since we have both the user_code_suspension_lock_ 267 // from the line above and the ThreadSuspendCountLock since it is our level_. We use this 268 // lambda to avoid having to annotate the whole function as NO_THREAD_SAFETY_ANALYSIS. 269 auto is_suspending_for_user_code = [self]() NO_THREAD_SAFETY_ANALYSIS { 270 return self->GetUserCodeSuspendCount() != 0; 271 }; 272 if (is_suspending_for_user_code()) { 273 LOG(ERROR) << "Holding \"" << held_mutex->name_ << "\" " 274 << "(level " << LockLevel(i) << ") while performing wait on " 275 << "\"" << name_ << "\" (level " << level_ << ") " 276 << "with SuspendReason::kForUserCode pending suspensions"; 277 bad_mutexes_held = true; 278 } 279 } else if (held_mutex != nullptr) { 280 LOG(ERROR) << "Holding \"" << held_mutex->name_ << "\" " 281 << "(level " << LockLevel(i) << ") while performing wait on " 282 << "\"" << name_ << "\" (level " << level_ << ")"; 283 bad_mutexes_held = true; 284 } 285 } 286 } 287 if (gAborting == 0) { // Avoid recursive aborts. 288 CHECK(!bad_mutexes_held) << this; 289 } 290 } 291 } 292 293 void BaseMutex::ContentionLogData::AddToWaitTime(uint64_t value) { 294 if (kLogLockContentions) { 295 // Atomically add value to wait_time. 296 wait_time.FetchAndAddSequentiallyConsistent(value); 297 } 298 } 299 300 void BaseMutex::RecordContention(uint64_t blocked_tid, 301 uint64_t owner_tid, 302 uint64_t nano_time_blocked) { 303 if (kLogLockContentions) { 304 ContentionLogData* data = contention_log_data_; 305 ++(data->contention_count); 306 data->AddToWaitTime(nano_time_blocked); 307 ContentionLogEntry* log = data->contention_log; 308 // This code is intentionally racy as it is only used for diagnostics. 309 uint32_t slot = data->cur_content_log_entry.LoadRelaxed(); 310 if (log[slot].blocked_tid == blocked_tid && 311 log[slot].owner_tid == blocked_tid) { 312 ++log[slot].count; 313 } else { 314 uint32_t new_slot; 315 do { 316 slot = data->cur_content_log_entry.LoadRelaxed(); 317 new_slot = (slot + 1) % kContentionLogSize; 318 } while (!data->cur_content_log_entry.CompareAndSetWeakRelaxed(slot, new_slot)); 319 log[new_slot].blocked_tid = blocked_tid; 320 log[new_slot].owner_tid = owner_tid; 321 log[new_slot].count.StoreRelaxed(1); 322 } 323 } 324 } 325 326 void BaseMutex::DumpContention(std::ostream& os) const { 327 if (kLogLockContentions) { 328 const ContentionLogData* data = contention_log_data_; 329 const ContentionLogEntry* log = data->contention_log; 330 uint64_t wait_time = data->wait_time.LoadRelaxed(); 331 uint32_t contention_count = data->contention_count.LoadRelaxed(); 332 if (contention_count == 0) { 333 os << "never contended"; 334 } else { 335 os << "contended " << contention_count 336 << " total wait of contender " << PrettyDuration(wait_time) 337 << " average " << PrettyDuration(wait_time / contention_count); 338 SafeMap<uint64_t, size_t> most_common_blocker; 339 SafeMap<uint64_t, size_t> most_common_blocked; 340 for (size_t i = 0; i < kContentionLogSize; ++i) { 341 uint64_t blocked_tid = log[i].blocked_tid; 342 uint64_t owner_tid = log[i].owner_tid; 343 uint32_t count = log[i].count.LoadRelaxed(); 344 if (count > 0) { 345 auto it = most_common_blocked.find(blocked_tid); 346 if (it != most_common_blocked.end()) { 347 most_common_blocked.Overwrite(blocked_tid, it->second + count); 348 } else { 349 most_common_blocked.Put(blocked_tid, count); 350 } 351 it = most_common_blocker.find(owner_tid); 352 if (it != most_common_blocker.end()) { 353 most_common_blocker.Overwrite(owner_tid, it->second + count); 354 } else { 355 most_common_blocker.Put(owner_tid, count); 356 } 357 } 358 } 359 uint64_t max_tid = 0; 360 size_t max_tid_count = 0; 361 for (const auto& pair : most_common_blocked) { 362 if (pair.second > max_tid_count) { 363 max_tid = pair.first; 364 max_tid_count = pair.second; 365 } 366 } 367 if (max_tid != 0) { 368 os << " sample shows most blocked tid=" << max_tid; 369 } 370 max_tid = 0; 371 max_tid_count = 0; 372 for (const auto& pair : most_common_blocker) { 373 if (pair.second > max_tid_count) { 374 max_tid = pair.first; 375 max_tid_count = pair.second; 376 } 377 } 378 if (max_tid != 0) { 379 os << " sample shows tid=" << max_tid << " owning during this time"; 380 } 381 } 382 } 383 } 384 385 386 Mutex::Mutex(const char* name, LockLevel level, bool recursive) 387 : BaseMutex(name, level), exclusive_owner_(0), recursive_(recursive), recursion_count_(0) { 388 #if ART_USE_FUTEXES 389 DCHECK_EQ(0, state_.LoadRelaxed()); 390 DCHECK_EQ(0, num_contenders_.LoadRelaxed()); 391 #else 392 CHECK_MUTEX_CALL(pthread_mutex_init, (&mutex_, nullptr)); 393 #endif 394 } 395 396 // Helper to allow checking shutdown while locking for thread safety. 397 static bool IsSafeToCallAbortSafe() { 398 MutexLock mu(Thread::Current(), *Locks::runtime_shutdown_lock_); 399 return Locks::IsSafeToCallAbortRacy(); 400 } 401 402 Mutex::~Mutex() { 403 bool safe_to_call_abort = Locks::IsSafeToCallAbortRacy(); 404 #if ART_USE_FUTEXES 405 if (state_.LoadRelaxed() != 0) { 406 LOG(safe_to_call_abort ? FATAL : WARNING) 407 << "destroying mutex with owner: " << GetExclusiveOwnerTid(); 408 } else { 409 if (GetExclusiveOwnerTid() != 0) { 410 LOG(safe_to_call_abort ? FATAL : WARNING) 411 << "unexpectedly found an owner on unlocked mutex " << name_; 412 } 413 if (num_contenders_.LoadSequentiallyConsistent() != 0) { 414 LOG(safe_to_call_abort ? FATAL : WARNING) 415 << "unexpectedly found a contender on mutex " << name_; 416 } 417 } 418 #else 419 // We can't use CHECK_MUTEX_CALL here because on shutdown a suspended daemon thread 420 // may still be using locks. 421 int rc = pthread_mutex_destroy(&mutex_); 422 if (rc != 0) { 423 errno = rc; 424 PLOG(safe_to_call_abort ? FATAL : WARNING) 425 << "pthread_mutex_destroy failed for " << name_; 426 } 427 #endif 428 } 429 430 void Mutex::ExclusiveLock(Thread* self) { 431 DCHECK(self == nullptr || self == Thread::Current()); 432 if (kDebugLocking && !recursive_) { 433 AssertNotHeld(self); 434 } 435 if (!recursive_ || !IsExclusiveHeld(self)) { 436 #if ART_USE_FUTEXES 437 bool done = false; 438 do { 439 int32_t cur_state = state_.LoadRelaxed(); 440 if (LIKELY(cur_state == 0)) { 441 // Change state from 0 to 1 and impose load/store ordering appropriate for lock acquisition. 442 done = state_.CompareAndSetWeakAcquire(0 /* cur_state */, 1 /* new state */); 443 } else { 444 // Failed to acquire, hang up. 445 ScopedContentionRecorder scr(this, SafeGetTid(self), GetExclusiveOwnerTid()); 446 num_contenders_++; 447 if (UNLIKELY(should_respond_to_empty_checkpoint_request_)) { 448 self->CheckEmptyCheckpointFromMutex(); 449 } 450 if (futex(state_.Address(), FUTEX_WAIT, 1, nullptr, nullptr, 0) != 0) { 451 // EAGAIN and EINTR both indicate a spurious failure, try again from the beginning. 452 // We don't use TEMP_FAILURE_RETRY so we can intentionally retry to acquire the lock. 453 if ((errno != EAGAIN) && (errno != EINTR)) { 454 PLOG(FATAL) << "futex wait failed for " << name_; 455 } 456 } 457 num_contenders_--; 458 } 459 } while (!done); 460 DCHECK_EQ(state_.LoadRelaxed(), 1); 461 #else 462 CHECK_MUTEX_CALL(pthread_mutex_lock, (&mutex_)); 463 #endif 464 DCHECK_EQ(GetExclusiveOwnerTid(), 0); 465 exclusive_owner_.StoreRelaxed(SafeGetTid(self)); 466 RegisterAsLocked(self); 467 } 468 recursion_count_++; 469 if (kDebugLocking) { 470 CHECK(recursion_count_ == 1 || recursive_) << "Unexpected recursion count on mutex: " 471 << name_ << " " << recursion_count_; 472 AssertHeld(self); 473 } 474 } 475 476 bool Mutex::ExclusiveTryLock(Thread* self) { 477 DCHECK(self == nullptr || self == Thread::Current()); 478 if (kDebugLocking && !recursive_) { 479 AssertNotHeld(self); 480 } 481 if (!recursive_ || !IsExclusiveHeld(self)) { 482 #if ART_USE_FUTEXES 483 bool done = false; 484 do { 485 int32_t cur_state = state_.LoadRelaxed(); 486 if (cur_state == 0) { 487 // Change state from 0 to 1 and impose load/store ordering appropriate for lock acquisition. 488 done = state_.CompareAndSetWeakAcquire(0 /* cur_state */, 1 /* new state */); 489 } else { 490 return false; 491 } 492 } while (!done); 493 DCHECK_EQ(state_.LoadRelaxed(), 1); 494 #else 495 int result = pthread_mutex_trylock(&mutex_); 496 if (result == EBUSY) { 497 return false; 498 } 499 if (result != 0) { 500 errno = result; 501 PLOG(FATAL) << "pthread_mutex_trylock failed for " << name_; 502 } 503 #endif 504 DCHECK_EQ(GetExclusiveOwnerTid(), 0); 505 exclusive_owner_.StoreRelaxed(SafeGetTid(self)); 506 RegisterAsLocked(self); 507 } 508 recursion_count_++; 509 if (kDebugLocking) { 510 CHECK(recursion_count_ == 1 || recursive_) << "Unexpected recursion count on mutex: " 511 << name_ << " " << recursion_count_; 512 AssertHeld(self); 513 } 514 return true; 515 } 516 517 void Mutex::ExclusiveUnlock(Thread* self) { 518 if (kIsDebugBuild && self != nullptr && self != Thread::Current()) { 519 std::string name1 = "<null>"; 520 std::string name2 = "<null>"; 521 if (self != nullptr) { 522 self->GetThreadName(name1); 523 } 524 if (Thread::Current() != nullptr) { 525 Thread::Current()->GetThreadName(name2); 526 } 527 LOG(FATAL) << GetName() << " level=" << level_ << " self=" << name1 528 << " Thread::Current()=" << name2; 529 } 530 AssertHeld(self); 531 DCHECK_NE(GetExclusiveOwnerTid(), 0); 532 recursion_count_--; 533 if (!recursive_ || recursion_count_ == 0) { 534 if (kDebugLocking) { 535 CHECK(recursion_count_ == 0 || recursive_) << "Unexpected recursion count on mutex: " 536 << name_ << " " << recursion_count_; 537 } 538 RegisterAsUnlocked(self); 539 #if ART_USE_FUTEXES 540 bool done = false; 541 do { 542 int32_t cur_state = state_.LoadRelaxed(); 543 if (LIKELY(cur_state == 1)) { 544 // We're no longer the owner. 545 exclusive_owner_.StoreRelaxed(0); 546 // Change state to 0 and impose load/store ordering appropriate for lock release. 547 // Note, the relaxed loads below mustn't reorder before the CompareAndSet. 548 // TODO: the ordering here is non-trivial as state is split across 3 fields, fix by placing 549 // a status bit into the state on contention. 550 done = state_.CompareAndSetWeakSequentiallyConsistent(cur_state, 0 /* new state */); 551 if (LIKELY(done)) { // Spurious fail? 552 // Wake a contender. 553 if (UNLIKELY(num_contenders_.LoadRelaxed() > 0)) { 554 futex(state_.Address(), FUTEX_WAKE, 1, nullptr, nullptr, 0); 555 } 556 } 557 } else { 558 // Logging acquires the logging lock, avoid infinite recursion in that case. 559 if (this != Locks::logging_lock_) { 560 LOG(FATAL) << "Unexpected state_ in unlock " << cur_state << " for " << name_; 561 } else { 562 LogHelper::LogLineLowStack(__FILE__, 563 __LINE__, 564 ::android::base::FATAL_WITHOUT_ABORT, 565 StringPrintf("Unexpected state_ %d in unlock for %s", 566 cur_state, name_).c_str()); 567 _exit(1); 568 } 569 } 570 } while (!done); 571 #else 572 exclusive_owner_.StoreRelaxed(0); 573 CHECK_MUTEX_CALL(pthread_mutex_unlock, (&mutex_)); 574 #endif 575 } 576 } 577 578 void Mutex::Dump(std::ostream& os) const { 579 os << (recursive_ ? "recursive " : "non-recursive ") 580 << name_ 581 << " level=" << static_cast<int>(level_) 582 << " rec=" << recursion_count_ 583 << " owner=" << GetExclusiveOwnerTid() << " "; 584 DumpContention(os); 585 } 586 587 std::ostream& operator<<(std::ostream& os, const Mutex& mu) { 588 mu.Dump(os); 589 return os; 590 } 591 592 void Mutex::WakeupToRespondToEmptyCheckpoint() { 593 #if ART_USE_FUTEXES 594 // Wake up all the waiters so they will respond to the emtpy checkpoint. 595 DCHECK(should_respond_to_empty_checkpoint_request_); 596 if (UNLIKELY(num_contenders_.LoadRelaxed() > 0)) { 597 futex(state_.Address(), FUTEX_WAKE, -1, nullptr, nullptr, 0); 598 } 599 #else 600 LOG(FATAL) << "Non futex case isn't supported."; 601 #endif 602 } 603 604 ReaderWriterMutex::ReaderWriterMutex(const char* name, LockLevel level) 605 : BaseMutex(name, level) 606 #if ART_USE_FUTEXES 607 , state_(0), num_pending_readers_(0), num_pending_writers_(0) 608 #endif 609 { 610 #if !ART_USE_FUTEXES 611 CHECK_MUTEX_CALL(pthread_rwlock_init, (&rwlock_, nullptr)); 612 #endif 613 exclusive_owner_.StoreRelaxed(0); 614 } 615 616 ReaderWriterMutex::~ReaderWriterMutex() { 617 #if ART_USE_FUTEXES 618 CHECK_EQ(state_.LoadRelaxed(), 0); 619 CHECK_EQ(GetExclusiveOwnerTid(), 0); 620 CHECK_EQ(num_pending_readers_.LoadRelaxed(), 0); 621 CHECK_EQ(num_pending_writers_.LoadRelaxed(), 0); 622 #else 623 // We can't use CHECK_MUTEX_CALL here because on shutdown a suspended daemon thread 624 // may still be using locks. 625 int rc = pthread_rwlock_destroy(&rwlock_); 626 if (rc != 0) { 627 errno = rc; 628 bool is_safe_to_call_abort = IsSafeToCallAbortSafe(); 629 PLOG(is_safe_to_call_abort ? FATAL : WARNING) << "pthread_rwlock_destroy failed for " << name_; 630 } 631 #endif 632 } 633 634 void ReaderWriterMutex::ExclusiveLock(Thread* self) { 635 DCHECK(self == nullptr || self == Thread::Current()); 636 AssertNotExclusiveHeld(self); 637 #if ART_USE_FUTEXES 638 bool done = false; 639 do { 640 int32_t cur_state = state_.LoadRelaxed(); 641 if (LIKELY(cur_state == 0)) { 642 // Change state from 0 to -1 and impose load/store ordering appropriate for lock acquisition. 643 done = state_.CompareAndSetWeakAcquire(0 /* cur_state*/, -1 /* new state */); 644 } else { 645 // Failed to acquire, hang up. 646 ScopedContentionRecorder scr(this, SafeGetTid(self), GetExclusiveOwnerTid()); 647 ++num_pending_writers_; 648 if (UNLIKELY(should_respond_to_empty_checkpoint_request_)) { 649 self->CheckEmptyCheckpointFromMutex(); 650 } 651 if (futex(state_.Address(), FUTEX_WAIT, cur_state, nullptr, nullptr, 0) != 0) { 652 // EAGAIN and EINTR both indicate a spurious failure, try again from the beginning. 653 // We don't use TEMP_FAILURE_RETRY so we can intentionally retry to acquire the lock. 654 if ((errno != EAGAIN) && (errno != EINTR)) { 655 PLOG(FATAL) << "futex wait failed for " << name_; 656 } 657 } 658 --num_pending_writers_; 659 } 660 } while (!done); 661 DCHECK_EQ(state_.LoadRelaxed(), -1); 662 #else 663 CHECK_MUTEX_CALL(pthread_rwlock_wrlock, (&rwlock_)); 664 #endif 665 DCHECK_EQ(GetExclusiveOwnerTid(), 0); 666 exclusive_owner_.StoreRelaxed(SafeGetTid(self)); 667 RegisterAsLocked(self); 668 AssertExclusiveHeld(self); 669 } 670 671 void ReaderWriterMutex::ExclusiveUnlock(Thread* self) { 672 DCHECK(self == nullptr || self == Thread::Current()); 673 AssertExclusiveHeld(self); 674 RegisterAsUnlocked(self); 675 DCHECK_NE(GetExclusiveOwnerTid(), 0); 676 #if ART_USE_FUTEXES 677 bool done = false; 678 do { 679 int32_t cur_state = state_.LoadRelaxed(); 680 if (LIKELY(cur_state == -1)) { 681 // We're no longer the owner. 682 exclusive_owner_.StoreRelaxed(0); 683 // Change state from -1 to 0 and impose load/store ordering appropriate for lock release. 684 // Note, the relaxed loads below musn't reorder before the CompareAndSet. 685 // TODO: the ordering here is non-trivial as state is split across 3 fields, fix by placing 686 // a status bit into the state on contention. 687 done = state_.CompareAndSetWeakSequentiallyConsistent(-1 /* cur_state*/, 0 /* new state */); 688 if (LIKELY(done)) { // Weak CAS may fail spuriously. 689 // Wake any waiters. 690 if (UNLIKELY(num_pending_readers_.LoadRelaxed() > 0 || 691 num_pending_writers_.LoadRelaxed() > 0)) { 692 futex(state_.Address(), FUTEX_WAKE, -1, nullptr, nullptr, 0); 693 } 694 } 695 } else { 696 LOG(FATAL) << "Unexpected state_:" << cur_state << " for " << name_; 697 } 698 } while (!done); 699 #else 700 exclusive_owner_.StoreRelaxed(0); 701 CHECK_MUTEX_CALL(pthread_rwlock_unlock, (&rwlock_)); 702 #endif 703 } 704 705 #if HAVE_TIMED_RWLOCK 706 bool ReaderWriterMutex::ExclusiveLockWithTimeout(Thread* self, int64_t ms, int32_t ns) { 707 DCHECK(self == nullptr || self == Thread::Current()); 708 #if ART_USE_FUTEXES 709 bool done = false; 710 timespec end_abs_ts; 711 InitTimeSpec(true, CLOCK_MONOTONIC, ms, ns, &end_abs_ts); 712 do { 713 int32_t cur_state = state_.LoadRelaxed(); 714 if (cur_state == 0) { 715 // Change state from 0 to -1 and impose load/store ordering appropriate for lock acquisition. 716 done = state_.CompareAndSetWeakAcquire(0 /* cur_state */, -1 /* new state */); 717 } else { 718 // Failed to acquire, hang up. 719 timespec now_abs_ts; 720 InitTimeSpec(true, CLOCK_MONOTONIC, 0, 0, &now_abs_ts); 721 timespec rel_ts; 722 if (ComputeRelativeTimeSpec(&rel_ts, end_abs_ts, now_abs_ts)) { 723 return false; // Timed out. 724 } 725 ScopedContentionRecorder scr(this, SafeGetTid(self), GetExclusiveOwnerTid()); 726 ++num_pending_writers_; 727 if (UNLIKELY(should_respond_to_empty_checkpoint_request_)) { 728 self->CheckEmptyCheckpointFromMutex(); 729 } 730 if (futex(state_.Address(), FUTEX_WAIT, cur_state, &rel_ts, nullptr, 0) != 0) { 731 if (errno == ETIMEDOUT) { 732 --num_pending_writers_; 733 return false; // Timed out. 734 } else if ((errno != EAGAIN) && (errno != EINTR)) { 735 // EAGAIN and EINTR both indicate a spurious failure, 736 // recompute the relative time out from now and try again. 737 // We don't use TEMP_FAILURE_RETRY so we can recompute rel_ts; 738 PLOG(FATAL) << "timed futex wait failed for " << name_; 739 } 740 } 741 --num_pending_writers_; 742 } 743 } while (!done); 744 #else 745 timespec ts; 746 InitTimeSpec(true, CLOCK_REALTIME, ms, ns, &ts); 747 int result = pthread_rwlock_timedwrlock(&rwlock_, &ts); 748 if (result == ETIMEDOUT) { 749 return false; 750 } 751 if (result != 0) { 752 errno = result; 753 PLOG(FATAL) << "pthread_rwlock_timedwrlock failed for " << name_; 754 } 755 #endif 756 exclusive_owner_.StoreRelaxed(SafeGetTid(self)); 757 RegisterAsLocked(self); 758 AssertSharedHeld(self); 759 return true; 760 } 761 #endif 762 763 #if ART_USE_FUTEXES 764 void ReaderWriterMutex::HandleSharedLockContention(Thread* self, int32_t cur_state) { 765 // Owner holds it exclusively, hang up. 766 ScopedContentionRecorder scr(this, SafeGetTid(self), GetExclusiveOwnerTid()); 767 ++num_pending_readers_; 768 if (UNLIKELY(should_respond_to_empty_checkpoint_request_)) { 769 self->CheckEmptyCheckpointFromMutex(); 770 } 771 if (futex(state_.Address(), FUTEX_WAIT, cur_state, nullptr, nullptr, 0) != 0) { 772 if (errno != EAGAIN && errno != EINTR) { 773 PLOG(FATAL) << "futex wait failed for " << name_; 774 } 775 } 776 --num_pending_readers_; 777 } 778 #endif 779 780 bool ReaderWriterMutex::SharedTryLock(Thread* self) { 781 DCHECK(self == nullptr || self == Thread::Current()); 782 #if ART_USE_FUTEXES 783 bool done = false; 784 do { 785 int32_t cur_state = state_.LoadRelaxed(); 786 if (cur_state >= 0) { 787 // Add as an extra reader and impose load/store ordering appropriate for lock acquisition. 788 done = state_.CompareAndSetWeakAcquire(cur_state, cur_state + 1); 789 } else { 790 // Owner holds it exclusively. 791 return false; 792 } 793 } while (!done); 794 #else 795 int result = pthread_rwlock_tryrdlock(&rwlock_); 796 if (result == EBUSY) { 797 return false; 798 } 799 if (result != 0) { 800 errno = result; 801 PLOG(FATAL) << "pthread_mutex_trylock failed for " << name_; 802 } 803 #endif 804 RegisterAsLocked(self); 805 AssertSharedHeld(self); 806 return true; 807 } 808 809 bool ReaderWriterMutex::IsSharedHeld(const Thread* self) const { 810 DCHECK(self == nullptr || self == Thread::Current()); 811 bool result; 812 if (UNLIKELY(self == nullptr)) { // Handle unattached threads. 813 result = IsExclusiveHeld(self); // TODO: a better best effort here. 814 } else { 815 result = (self->GetHeldMutex(level_) == this); 816 } 817 return result; 818 } 819 820 void ReaderWriterMutex::Dump(std::ostream& os) const { 821 os << name_ 822 << " level=" << static_cast<int>(level_) 823 << " owner=" << GetExclusiveOwnerTid() 824 #if ART_USE_FUTEXES 825 << " state=" << state_.LoadSequentiallyConsistent() 826 << " num_pending_writers=" << num_pending_writers_.LoadSequentiallyConsistent() 827 << " num_pending_readers=" << num_pending_readers_.LoadSequentiallyConsistent() 828 #endif 829 << " "; 830 DumpContention(os); 831 } 832 833 std::ostream& operator<<(std::ostream& os, const ReaderWriterMutex& mu) { 834 mu.Dump(os); 835 return os; 836 } 837 838 std::ostream& operator<<(std::ostream& os, const MutatorMutex& mu) { 839 mu.Dump(os); 840 return os; 841 } 842 843 void ReaderWriterMutex::WakeupToRespondToEmptyCheckpoint() { 844 #if ART_USE_FUTEXES 845 // Wake up all the waiters so they will respond to the emtpy checkpoint. 846 DCHECK(should_respond_to_empty_checkpoint_request_); 847 if (UNLIKELY(num_pending_readers_.LoadRelaxed() > 0 || 848 num_pending_writers_.LoadRelaxed() > 0)) { 849 futex(state_.Address(), FUTEX_WAKE, -1, nullptr, nullptr, 0); 850 } 851 #else 852 LOG(FATAL) << "Non futex case isn't supported."; 853 #endif 854 } 855 856 ConditionVariable::ConditionVariable(const char* name, Mutex& guard) 857 : name_(name), guard_(guard) { 858 #if ART_USE_FUTEXES 859 DCHECK_EQ(0, sequence_.LoadRelaxed()); 860 num_waiters_ = 0; 861 #else 862 pthread_condattr_t cond_attrs; 863 CHECK_MUTEX_CALL(pthread_condattr_init, (&cond_attrs)); 864 #if !defined(__APPLE__) 865 // Apple doesn't have CLOCK_MONOTONIC or pthread_condattr_setclock. 866 CHECK_MUTEX_CALL(pthread_condattr_setclock, (&cond_attrs, CLOCK_MONOTONIC)); 867 #endif 868 CHECK_MUTEX_CALL(pthread_cond_init, (&cond_, &cond_attrs)); 869 #endif 870 } 871 872 ConditionVariable::~ConditionVariable() { 873 #if ART_USE_FUTEXES 874 if (num_waiters_!= 0) { 875 bool is_safe_to_call_abort = IsSafeToCallAbortSafe(); 876 LOG(is_safe_to_call_abort ? FATAL : WARNING) 877 << "ConditionVariable::~ConditionVariable for " << name_ 878 << " called with " << num_waiters_ << " waiters."; 879 } 880 #else 881 // We can't use CHECK_MUTEX_CALL here because on shutdown a suspended daemon thread 882 // may still be using condition variables. 883 int rc = pthread_cond_destroy(&cond_); 884 if (rc != 0) { 885 errno = rc; 886 bool is_safe_to_call_abort = IsSafeToCallAbortSafe(); 887 PLOG(is_safe_to_call_abort ? FATAL : WARNING) << "pthread_cond_destroy failed for " << name_; 888 } 889 #endif 890 } 891 892 void ConditionVariable::Broadcast(Thread* self) { 893 DCHECK(self == nullptr || self == Thread::Current()); 894 // TODO: enable below, there's a race in thread creation that causes false failures currently. 895 // guard_.AssertExclusiveHeld(self); 896 DCHECK_EQ(guard_.GetExclusiveOwnerTid(), SafeGetTid(self)); 897 #if ART_USE_FUTEXES 898 if (num_waiters_ > 0) { 899 sequence_++; // Indicate the broadcast occurred. 900 bool done = false; 901 do { 902 int32_t cur_sequence = sequence_.LoadRelaxed(); 903 // Requeue waiters onto mutex. The waiter holds the contender count on the mutex high ensuring 904 // mutex unlocks will awaken the requeued waiter thread. 905 done = futex(sequence_.Address(), FUTEX_CMP_REQUEUE, 0, 906 reinterpret_cast<const timespec*>(std::numeric_limits<int32_t>::max()), 907 guard_.state_.Address(), cur_sequence) != -1; 908 if (!done) { 909 if (errno != EAGAIN && errno != EINTR) { 910 PLOG(FATAL) << "futex cmp requeue failed for " << name_; 911 } 912 } 913 } while (!done); 914 } 915 #else 916 CHECK_MUTEX_CALL(pthread_cond_broadcast, (&cond_)); 917 #endif 918 } 919 920 void ConditionVariable::Signal(Thread* self) { 921 DCHECK(self == nullptr || self == Thread::Current()); 922 guard_.AssertExclusiveHeld(self); 923 #if ART_USE_FUTEXES 924 if (num_waiters_ > 0) { 925 sequence_++; // Indicate a signal occurred. 926 // Futex wake 1 waiter who will then come and in contend on mutex. It'd be nice to requeue them 927 // to avoid this, however, requeueing can only move all waiters. 928 int num_woken = futex(sequence_.Address(), FUTEX_WAKE, 1, nullptr, nullptr, 0); 929 // Check something was woken or else we changed sequence_ before they had chance to wait. 930 CHECK((num_woken == 0) || (num_woken == 1)); 931 } 932 #else 933 CHECK_MUTEX_CALL(pthread_cond_signal, (&cond_)); 934 #endif 935 } 936 937 void ConditionVariable::Wait(Thread* self) { 938 guard_.CheckSafeToWait(self); 939 WaitHoldingLocks(self); 940 } 941 942 void ConditionVariable::WaitHoldingLocks(Thread* self) { 943 DCHECK(self == nullptr || self == Thread::Current()); 944 guard_.AssertExclusiveHeld(self); 945 unsigned int old_recursion_count = guard_.recursion_count_; 946 #if ART_USE_FUTEXES 947 num_waiters_++; 948 // Ensure the Mutex is contended so that requeued threads are awoken. 949 guard_.num_contenders_++; 950 guard_.recursion_count_ = 1; 951 int32_t cur_sequence = sequence_.LoadRelaxed(); 952 guard_.ExclusiveUnlock(self); 953 if (futex(sequence_.Address(), FUTEX_WAIT, cur_sequence, nullptr, nullptr, 0) != 0) { 954 // Futex failed, check it is an expected error. 955 // EAGAIN == EWOULDBLK, so we let the caller try again. 956 // EINTR implies a signal was sent to this thread. 957 if ((errno != EINTR) && (errno != EAGAIN)) { 958 PLOG(FATAL) << "futex wait failed for " << name_; 959 } 960 } 961 if (self != nullptr) { 962 JNIEnvExt* const env = self->GetJniEnv(); 963 if (UNLIKELY(env != nullptr && env->IsRuntimeDeleted())) { 964 CHECK(self->IsDaemon()); 965 // If the runtime has been deleted, then we cannot proceed. Just sleep forever. This may 966 // occur for user daemon threads that get a spurious wakeup. This occurs for test 132 with 967 // --host and --gdb. 968 // After we wake up, the runtime may have been shutdown, which means that this condition may 969 // have been deleted. It is not safe to retry the wait. 970 SleepForever(); 971 } 972 } 973 guard_.ExclusiveLock(self); 974 CHECK_GE(num_waiters_, 0); 975 num_waiters_--; 976 // We awoke and so no longer require awakes from the guard_'s unlock. 977 CHECK_GE(guard_.num_contenders_.LoadRelaxed(), 0); 978 guard_.num_contenders_--; 979 #else 980 pid_t old_owner = guard_.GetExclusiveOwnerTid(); 981 guard_.exclusive_owner_.StoreRelaxed(0); 982 guard_.recursion_count_ = 0; 983 CHECK_MUTEX_CALL(pthread_cond_wait, (&cond_, &guard_.mutex_)); 984 guard_.exclusive_owner_.StoreRelaxed(old_owner); 985 #endif 986 guard_.recursion_count_ = old_recursion_count; 987 } 988 989 bool ConditionVariable::TimedWait(Thread* self, int64_t ms, int32_t ns) { 990 DCHECK(self == nullptr || self == Thread::Current()); 991 bool timed_out = false; 992 guard_.AssertExclusiveHeld(self); 993 guard_.CheckSafeToWait(self); 994 unsigned int old_recursion_count = guard_.recursion_count_; 995 #if ART_USE_FUTEXES 996 timespec rel_ts; 997 InitTimeSpec(false, CLOCK_REALTIME, ms, ns, &rel_ts); 998 num_waiters_++; 999 // Ensure the Mutex is contended so that requeued threads are awoken. 1000 guard_.num_contenders_++; 1001 guard_.recursion_count_ = 1; 1002 int32_t cur_sequence = sequence_.LoadRelaxed(); 1003 guard_.ExclusiveUnlock(self); 1004 if (futex(sequence_.Address(), FUTEX_WAIT, cur_sequence, &rel_ts, nullptr, 0) != 0) { 1005 if (errno == ETIMEDOUT) { 1006 // Timed out we're done. 1007 timed_out = true; 1008 } else if ((errno == EAGAIN) || (errno == EINTR)) { 1009 // A signal or ConditionVariable::Signal/Broadcast has come in. 1010 } else { 1011 PLOG(FATAL) << "timed futex wait failed for " << name_; 1012 } 1013 } 1014 guard_.ExclusiveLock(self); 1015 CHECK_GE(num_waiters_, 0); 1016 num_waiters_--; 1017 // We awoke and so no longer require awakes from the guard_'s unlock. 1018 CHECK_GE(guard_.num_contenders_.LoadRelaxed(), 0); 1019 guard_.num_contenders_--; 1020 #else 1021 #if !defined(__APPLE__) 1022 int clock = CLOCK_MONOTONIC; 1023 #else 1024 int clock = CLOCK_REALTIME; 1025 #endif 1026 pid_t old_owner = guard_.GetExclusiveOwnerTid(); 1027 guard_.exclusive_owner_.StoreRelaxed(0); 1028 guard_.recursion_count_ = 0; 1029 timespec ts; 1030 InitTimeSpec(true, clock, ms, ns, &ts); 1031 int rc = TEMP_FAILURE_RETRY(pthread_cond_timedwait(&cond_, &guard_.mutex_, &ts)); 1032 if (rc == ETIMEDOUT) { 1033 timed_out = true; 1034 } else if (rc != 0) { 1035 errno = rc; 1036 PLOG(FATAL) << "TimedWait failed for " << name_; 1037 } 1038 guard_.exclusive_owner_.StoreRelaxed(old_owner); 1039 #endif 1040 guard_.recursion_count_ = old_recursion_count; 1041 return timed_out; 1042 } 1043 1044 void Locks::Init() { 1045 if (logging_lock_ != nullptr) { 1046 // Already initialized. 1047 if (kRuntimeISA == InstructionSet::kX86 || kRuntimeISA == InstructionSet::kX86_64) { 1048 DCHECK(modify_ldt_lock_ != nullptr); 1049 } else { 1050 DCHECK(modify_ldt_lock_ == nullptr); 1051 } 1052 DCHECK(abort_lock_ != nullptr); 1053 DCHECK(alloc_tracker_lock_ != nullptr); 1054 DCHECK(allocated_monitor_ids_lock_ != nullptr); 1055 DCHECK(allocated_thread_ids_lock_ != nullptr); 1056 DCHECK(breakpoint_lock_ != nullptr); 1057 DCHECK(classlinker_classes_lock_ != nullptr); 1058 DCHECK(deoptimization_lock_ != nullptr); 1059 DCHECK(heap_bitmap_lock_ != nullptr); 1060 DCHECK(oat_file_manager_lock_ != nullptr); 1061 DCHECK(verifier_deps_lock_ != nullptr); 1062 DCHECK(host_dlopen_handles_lock_ != nullptr); 1063 DCHECK(intern_table_lock_ != nullptr); 1064 DCHECK(jni_function_table_lock_ != nullptr); 1065 DCHECK(jni_libraries_lock_ != nullptr); 1066 DCHECK(logging_lock_ != nullptr); 1067 DCHECK(mutator_lock_ != nullptr); 1068 DCHECK(profiler_lock_ != nullptr); 1069 DCHECK(cha_lock_ != nullptr); 1070 DCHECK(subtype_check_lock_ != nullptr); 1071 DCHECK(thread_list_lock_ != nullptr); 1072 DCHECK(thread_suspend_count_lock_ != nullptr); 1073 DCHECK(trace_lock_ != nullptr); 1074 DCHECK(unexpected_signal_lock_ != nullptr); 1075 DCHECK(user_code_suspension_lock_ != nullptr); 1076 DCHECK(dex_lock_ != nullptr); 1077 DCHECK(native_debug_interface_lock_ != nullptr); 1078 } else { 1079 // Create global locks in level order from highest lock level to lowest. 1080 LockLevel current_lock_level = kInstrumentEntrypointsLock; 1081 DCHECK(instrument_entrypoints_lock_ == nullptr); 1082 instrument_entrypoints_lock_ = new Mutex("instrument entrypoint lock", current_lock_level); 1083 1084 #define UPDATE_CURRENT_LOCK_LEVEL(new_level) \ 1085 if ((new_level) >= current_lock_level) { \ 1086 /* Do not use CHECKs or FATAL here, abort_lock_ is not setup yet. */ \ 1087 fprintf(stderr, "New local level %d is not less than current level %d\n", \ 1088 new_level, current_lock_level); \ 1089 exit(1); \ 1090 } \ 1091 current_lock_level = new_level; 1092 1093 UPDATE_CURRENT_LOCK_LEVEL(kUserCodeSuspensionLock); 1094 DCHECK(user_code_suspension_lock_ == nullptr); 1095 user_code_suspension_lock_ = new Mutex("user code suspension lock", current_lock_level); 1096 1097 UPDATE_CURRENT_LOCK_LEVEL(kMutatorLock); 1098 DCHECK(mutator_lock_ == nullptr); 1099 mutator_lock_ = new MutatorMutex("mutator lock", current_lock_level); 1100 1101 UPDATE_CURRENT_LOCK_LEVEL(kHeapBitmapLock); 1102 DCHECK(heap_bitmap_lock_ == nullptr); 1103 heap_bitmap_lock_ = new ReaderWriterMutex("heap bitmap lock", current_lock_level); 1104 1105 UPDATE_CURRENT_LOCK_LEVEL(kTraceLock); 1106 DCHECK(trace_lock_ == nullptr); 1107 trace_lock_ = new Mutex("trace lock", current_lock_level); 1108 1109 UPDATE_CURRENT_LOCK_LEVEL(kRuntimeShutdownLock); 1110 DCHECK(runtime_shutdown_lock_ == nullptr); 1111 runtime_shutdown_lock_ = new Mutex("runtime shutdown lock", current_lock_level); 1112 1113 UPDATE_CURRENT_LOCK_LEVEL(kProfilerLock); 1114 DCHECK(profiler_lock_ == nullptr); 1115 profiler_lock_ = new Mutex("profiler lock", current_lock_level); 1116 1117 UPDATE_CURRENT_LOCK_LEVEL(kDeoptimizationLock); 1118 DCHECK(deoptimization_lock_ == nullptr); 1119 deoptimization_lock_ = new Mutex("Deoptimization lock", current_lock_level); 1120 1121 UPDATE_CURRENT_LOCK_LEVEL(kAllocTrackerLock); 1122 DCHECK(alloc_tracker_lock_ == nullptr); 1123 alloc_tracker_lock_ = new Mutex("AllocTracker lock", current_lock_level); 1124 1125 UPDATE_CURRENT_LOCK_LEVEL(kThreadListLock); 1126 DCHECK(thread_list_lock_ == nullptr); 1127 thread_list_lock_ = new Mutex("thread list lock", current_lock_level); 1128 1129 UPDATE_CURRENT_LOCK_LEVEL(kJniLoadLibraryLock); 1130 DCHECK(jni_libraries_lock_ == nullptr); 1131 jni_libraries_lock_ = new Mutex("JNI shared libraries map lock", current_lock_level); 1132 1133 UPDATE_CURRENT_LOCK_LEVEL(kBreakpointLock); 1134 DCHECK(breakpoint_lock_ == nullptr); 1135 breakpoint_lock_ = new ReaderWriterMutex("breakpoint lock", current_lock_level); 1136 1137 UPDATE_CURRENT_LOCK_LEVEL(kSubtypeCheckLock); 1138 DCHECK(subtype_check_lock_ == nullptr); 1139 subtype_check_lock_ = new Mutex("SubtypeCheck lock", current_lock_level); 1140 1141 UPDATE_CURRENT_LOCK_LEVEL(kCHALock); 1142 DCHECK(cha_lock_ == nullptr); 1143 cha_lock_ = new Mutex("CHA lock", current_lock_level); 1144 1145 UPDATE_CURRENT_LOCK_LEVEL(kClassLinkerClassesLock); 1146 DCHECK(classlinker_classes_lock_ == nullptr); 1147 classlinker_classes_lock_ = new ReaderWriterMutex("ClassLinker classes lock", 1148 current_lock_level); 1149 1150 UPDATE_CURRENT_LOCK_LEVEL(kMonitorPoolLock); 1151 DCHECK(allocated_monitor_ids_lock_ == nullptr); 1152 allocated_monitor_ids_lock_ = new Mutex("allocated monitor ids lock", current_lock_level); 1153 1154 UPDATE_CURRENT_LOCK_LEVEL(kAllocatedThreadIdsLock); 1155 DCHECK(allocated_thread_ids_lock_ == nullptr); 1156 allocated_thread_ids_lock_ = new Mutex("allocated thread ids lock", current_lock_level); 1157 1158 if (kRuntimeISA == InstructionSet::kX86 || kRuntimeISA == InstructionSet::kX86_64) { 1159 UPDATE_CURRENT_LOCK_LEVEL(kModifyLdtLock); 1160 DCHECK(modify_ldt_lock_ == nullptr); 1161 modify_ldt_lock_ = new Mutex("modify_ldt lock", current_lock_level); 1162 } 1163 1164 UPDATE_CURRENT_LOCK_LEVEL(kDexLock); 1165 DCHECK(dex_lock_ == nullptr); 1166 dex_lock_ = new ReaderWriterMutex("ClassLinker dex lock", current_lock_level); 1167 1168 UPDATE_CURRENT_LOCK_LEVEL(kOatFileManagerLock); 1169 DCHECK(oat_file_manager_lock_ == nullptr); 1170 oat_file_manager_lock_ = new ReaderWriterMutex("OatFile manager lock", current_lock_level); 1171 1172 UPDATE_CURRENT_LOCK_LEVEL(kVerifierDepsLock); 1173 DCHECK(verifier_deps_lock_ == nullptr); 1174 verifier_deps_lock_ = new ReaderWriterMutex("verifier deps lock", current_lock_level); 1175 1176 UPDATE_CURRENT_LOCK_LEVEL(kHostDlOpenHandlesLock); 1177 DCHECK(host_dlopen_handles_lock_ == nullptr); 1178 host_dlopen_handles_lock_ = new Mutex("host dlopen handles lock", current_lock_level); 1179 1180 UPDATE_CURRENT_LOCK_LEVEL(kInternTableLock); 1181 DCHECK(intern_table_lock_ == nullptr); 1182 intern_table_lock_ = new Mutex("InternTable lock", current_lock_level); 1183 1184 UPDATE_CURRENT_LOCK_LEVEL(kReferenceProcessorLock); 1185 DCHECK(reference_processor_lock_ == nullptr); 1186 reference_processor_lock_ = new Mutex("ReferenceProcessor lock", current_lock_level); 1187 1188 UPDATE_CURRENT_LOCK_LEVEL(kReferenceQueueClearedReferencesLock); 1189 DCHECK(reference_queue_cleared_references_lock_ == nullptr); 1190 reference_queue_cleared_references_lock_ = new Mutex("ReferenceQueue cleared references lock", current_lock_level); 1191 1192 UPDATE_CURRENT_LOCK_LEVEL(kReferenceQueueWeakReferencesLock); 1193 DCHECK(reference_queue_weak_references_lock_ == nullptr); 1194 reference_queue_weak_references_lock_ = new Mutex("ReferenceQueue cleared references lock", current_lock_level); 1195 1196 UPDATE_CURRENT_LOCK_LEVEL(kReferenceQueueFinalizerReferencesLock); 1197 DCHECK(reference_queue_finalizer_references_lock_ == nullptr); 1198 reference_queue_finalizer_references_lock_ = new Mutex("ReferenceQueue finalizer references lock", current_lock_level); 1199 1200 UPDATE_CURRENT_LOCK_LEVEL(kReferenceQueuePhantomReferencesLock); 1201 DCHECK(reference_queue_phantom_references_lock_ == nullptr); 1202 reference_queue_phantom_references_lock_ = new Mutex("ReferenceQueue phantom references lock", current_lock_level); 1203 1204 UPDATE_CURRENT_LOCK_LEVEL(kReferenceQueueSoftReferencesLock); 1205 DCHECK(reference_queue_soft_references_lock_ == nullptr); 1206 reference_queue_soft_references_lock_ = new Mutex("ReferenceQueue soft references lock", current_lock_level); 1207 1208 UPDATE_CURRENT_LOCK_LEVEL(kJniGlobalsLock); 1209 DCHECK(jni_globals_lock_ == nullptr); 1210 jni_globals_lock_ = 1211 new ReaderWriterMutex("JNI global reference table lock", current_lock_level); 1212 1213 UPDATE_CURRENT_LOCK_LEVEL(kJniWeakGlobalsLock); 1214 DCHECK(jni_weak_globals_lock_ == nullptr); 1215 jni_weak_globals_lock_ = new Mutex("JNI weak global reference table lock", current_lock_level); 1216 1217 UPDATE_CURRENT_LOCK_LEVEL(kJniFunctionTableLock); 1218 DCHECK(jni_function_table_lock_ == nullptr); 1219 jni_function_table_lock_ = new Mutex("JNI function table lock", current_lock_level); 1220 1221 UPDATE_CURRENT_LOCK_LEVEL(kNativeDebugInterfaceLock); 1222 DCHECK(native_debug_interface_lock_ == nullptr); 1223 native_debug_interface_lock_ = new Mutex("Native debug interface lock", current_lock_level); 1224 1225 UPDATE_CURRENT_LOCK_LEVEL(kAbortLock); 1226 DCHECK(abort_lock_ == nullptr); 1227 abort_lock_ = new Mutex("abort lock", current_lock_level, true); 1228 1229 UPDATE_CURRENT_LOCK_LEVEL(kThreadSuspendCountLock); 1230 DCHECK(thread_suspend_count_lock_ == nullptr); 1231 thread_suspend_count_lock_ = new Mutex("thread suspend count lock", current_lock_level); 1232 1233 UPDATE_CURRENT_LOCK_LEVEL(kUnexpectedSignalLock); 1234 DCHECK(unexpected_signal_lock_ == nullptr); 1235 unexpected_signal_lock_ = new Mutex("unexpected signal lock", current_lock_level, true); 1236 1237 UPDATE_CURRENT_LOCK_LEVEL(kLoggingLock); 1238 DCHECK(logging_lock_ == nullptr); 1239 logging_lock_ = new Mutex("logging lock", current_lock_level, true); 1240 1241 #undef UPDATE_CURRENT_LOCK_LEVEL 1242 1243 // List of mutexes that we may hold when accessing a weak ref. 1244 AddToExpectedMutexesOnWeakRefAccess(dex_lock_, /*need_lock*/ false); 1245 AddToExpectedMutexesOnWeakRefAccess(classlinker_classes_lock_, /*need_lock*/ false); 1246 AddToExpectedMutexesOnWeakRefAccess(jni_libraries_lock_, /*need_lock*/ false); 1247 1248 InitConditions(); 1249 } 1250 } 1251 1252 void Locks::InitConditions() { 1253 thread_exit_cond_ = new ConditionVariable("thread exit condition variable", *thread_list_lock_); 1254 } 1255 1256 void Locks::SetClientCallback(ClientCallback* safe_to_call_abort_cb) { 1257 safe_to_call_abort_callback.StoreRelease(safe_to_call_abort_cb); 1258 } 1259 1260 // Helper to allow checking shutdown while ignoring locking requirements. 1261 bool Locks::IsSafeToCallAbortRacy() { 1262 Locks::ClientCallback* safe_to_call_abort_cb = safe_to_call_abort_callback.LoadAcquire(); 1263 return safe_to_call_abort_cb != nullptr && safe_to_call_abort_cb(); 1264 } 1265 1266 void Locks::AddToExpectedMutexesOnWeakRefAccess(BaseMutex* mutex, bool need_lock) { 1267 if (need_lock) { 1268 ScopedExpectedMutexesOnWeakRefAccessLock mu(mutex); 1269 mutex->SetShouldRespondToEmptyCheckpointRequest(true); 1270 expected_mutexes_on_weak_ref_access_.push_back(mutex); 1271 } else { 1272 mutex->SetShouldRespondToEmptyCheckpointRequest(true); 1273 expected_mutexes_on_weak_ref_access_.push_back(mutex); 1274 } 1275 } 1276 1277 void Locks::RemoveFromExpectedMutexesOnWeakRefAccess(BaseMutex* mutex, bool need_lock) { 1278 if (need_lock) { 1279 ScopedExpectedMutexesOnWeakRefAccessLock mu(mutex); 1280 mutex->SetShouldRespondToEmptyCheckpointRequest(false); 1281 std::vector<BaseMutex*>& list = expected_mutexes_on_weak_ref_access_; 1282 auto it = std::find(list.begin(), list.end(), mutex); 1283 DCHECK(it != list.end()); 1284 list.erase(it); 1285 } else { 1286 mutex->SetShouldRespondToEmptyCheckpointRequest(false); 1287 std::vector<BaseMutex*>& list = expected_mutexes_on_weak_ref_access_; 1288 auto it = std::find(list.begin(), list.end(), mutex); 1289 DCHECK(it != list.end()); 1290 list.erase(it); 1291 } 1292 } 1293 1294 bool Locks::IsExpectedOnWeakRefAccess(BaseMutex* mutex) { 1295 ScopedExpectedMutexesOnWeakRefAccessLock mu(mutex); 1296 std::vector<BaseMutex*>& list = expected_mutexes_on_weak_ref_access_; 1297 return std::find(list.begin(), list.end(), mutex) != list.end(); 1298 } 1299 1300 } // namespace art 1301