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