diff options
Diffstat (limited to 'runtime/monitor.cc')
| -rw-r--r-- | runtime/monitor.cc | 57 |
1 files changed, 35 insertions, 22 deletions
diff --git a/runtime/monitor.cc b/runtime/monitor.cc index 071b0e2c75..a32003e81b 100644 --- a/runtime/monitor.cc +++ b/runtime/monitor.cc @@ -303,6 +303,7 @@ std::string Monitor::PrettyContentionInfo(const std::string& owner_name, ArtMethod* owners_method, uint32_t owners_dex_pc, size_t num_waiters) { + Locks::mutator_lock_->AssertSharedHeld(Thread::Current()); const char* owners_filename; int32_t owners_line_number = 0; if (owners_method != nullptr) { @@ -355,36 +356,44 @@ void Monitor::Lock(Thread* self) { // Do this before releasing the lock so that we don't get deflated. size_t num_waiters = num_waiters_; ++num_waiters_; + + // If systrace logging is enabled, first look at the lock owner. Acquiring the monitor's + // lock and then re-acquiring the mutator lock can deadlock. + bool started_trace = false; + if (ATRACE_ENABLED()) { + if (owner_ != nullptr) { // Did the owner_ give the lock up? + std::ostringstream oss; + std::string name; + owner_->GetThreadName(name); + oss << PrettyContentionInfo(name, + owner_->GetTid(), + owners_method, + owners_dex_pc, + num_waiters); + // Add info for contending thread. + uint32_t pc; + ArtMethod* m = self->GetCurrentMethod(&pc); + const char* filename; + int32_t line_number; + TranslateLocation(m, pc, &filename, &line_number); + oss << " blocking from " + << ArtMethod::PrettyMethod(m) << "(" << (filename != nullptr ? filename : "null") + << ":" << line_number << ")"; + ATRACE_BEGIN(oss.str().c_str()); + started_trace = true; + } + } + monitor_lock_.Unlock(self); // Let go of locks in order. self->SetMonitorEnterObject(GetObject()); { + ScopedThreadSuspension tsc(self, kBlocked); // Change to blocked and give up mutator_lock_. uint32_t original_owner_thread_id = 0u; - ScopedThreadStateChange tsc(self, kBlocked); // Change to blocked and give up mutator_lock_. { // Reacquire monitor_lock_ without mutator_lock_ for Wait. MutexLock mu2(self, monitor_lock_); if (owner_ != nullptr) { // Did the owner_ give the lock up? original_owner_thread_id = owner_->GetThreadId(); - if (ATRACE_ENABLED()) { - std::ostringstream oss; - std::string name; - owner_->GetThreadName(name); - oss << PrettyContentionInfo(name, - owner_->GetTid(), - owners_method, - owners_dex_pc, - num_waiters); - // Add info for contending thread. - uint32_t pc; - ArtMethod* m = self->GetCurrentMethod(&pc); - const char* filename; - int32_t line_number; - TranslateLocation(m, pc, &filename, &line_number); - oss << " blocking from " - << ArtMethod::PrettyMethod(m) << "(" << (filename != nullptr ? filename : "null") - << ":" << line_number << ")"; - ATRACE_BEGIN(oss.str().c_str()); - } monitor_contenders_.Wait(self); // Still contended so wait. } } @@ -414,6 +423,8 @@ void Monitor::Lock(Thread* self) { sample_percent = 100 * wait_ms / lock_profiling_threshold_; } if (sample_percent != 0 && (static_cast<uint32_t>(rand() % 100) < sample_percent)) { + // Reacquire mutator_lock_ for logging. + ScopedObjectAccess soa(self); if (wait_ms > kLongWaitMs && owners_method != nullptr) { uint32_t pc; ArtMethod* m = self->GetCurrentMethod(&pc); @@ -441,9 +452,11 @@ void Monitor::Lock(Thread* self) { } } } - ATRACE_END(); } } + if (started_trace) { + ATRACE_END(); + } self->SetMonitorEnterObject(nullptr); monitor_lock_.Lock(self); // Reacquire locks in order. --num_waiters_; |