ART: Change contention logging lock strategy
Compute possible contention (wrt/ sampling) first. Then keep the whole
logging section under the mutator lock *and* the thread-list lock so
as to avoid any thread races.
This change is in preparation for heavier logging under heavy lock
contention.
Enable contention logging in 004-ThreadStress.
Bug: 62353392
Test: m test-art-host
Change-Id: I7b9126bae273f0cddb681f5f013ce6d814c7b8c0
diff --git a/runtime/monitor.cc b/runtime/monitor.cc
index a617818..4d309bf 100644
--- a/runtime/monitor.cc
+++ b/runtime/monitor.cc
@@ -401,31 +401,28 @@
if (original_owner_thread_id != 0u) {
// Woken from contention.
if (log_contention) {
- uint32_t original_owner_tid = 0;
- std::string original_owner_name;
- {
+ uint64_t wait_ms = MilliTime() - wait_start_ms;
+ uint32_t sample_percent;
+ if (wait_ms >= lock_profiling_threshold_) {
+ sample_percent = 100;
+ } else {
+ 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);
+ // Acquire thread-list lock to find thread and keep it from dying until we're done.
MutexLock mu2(Thread::Current(), *Locks::thread_list_lock_);
+
// Re-find the owner in case the thread got killed.
Thread* original_owner = Runtime::Current()->GetThreadList()->FindThreadByThreadId(
original_owner_thread_id);
- // Do not do any work that requires the mutator lock.
- if (original_owner != nullptr) {
- original_owner_tid = original_owner->GetTid();
- original_owner->GetThreadName(original_owner_name);
- }
- }
- if (original_owner_tid != 0u) {
- uint64_t wait_ms = MilliTime() - wait_start_ms;
- uint32_t sample_percent;
- if (wait_ms >= lock_profiling_threshold_) {
- sample_percent = 100;
- } else {
- 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 (original_owner != nullptr) {
+ pid_t original_owner_tid = original_owner->GetTid();
+ std::string original_owner_name;
+ original_owner->GetThreadName(original_owner_name);
+
if (wait_ms > kLongWaitMs && owners_method != nullptr) {
uint32_t pc;
ArtMethod* m = self->GetCurrentMethod(&pc);