diff options
Diffstat (limited to 'runtime/monitor.cc')
-rw-r--r-- | runtime/monitor.cc | 52 |
1 files changed, 35 insertions, 17 deletions
diff --git a/runtime/monitor.cc b/runtime/monitor.cc index 0f567053e5..3771877c9d 100644 --- a/runtime/monitor.cc +++ b/runtime/monitor.cc @@ -314,21 +314,34 @@ std::string Monitor::PrettyContentionInfo(const std::string& owner_name, return oss.str(); } +bool Monitor::TryLockLocked(Thread* self) { + if (owner_ == nullptr) { // Unowned. + owner_ = self; + CHECK_EQ(lock_count_, 0); + // When debugging, save the current monitor holder for future + // acquisition failures to use in sampled logging. + if (lock_profiling_threshold_ != 0) { + locking_method_ = self->GetCurrentMethod(&locking_dex_pc_); + } + } else if (owner_ == self) { // Recursive. + lock_count_++; + } else { + return false; + } + AtraceMonitorLock(self, GetObject(), false /* is_wait */); + return true; +} + +bool Monitor::TryLock(Thread* self) { + MutexLock mu(self, monitor_lock_); + return TryLockLocked(self); +} + void Monitor::Lock(Thread* self) { MutexLock mu(self, monitor_lock_); while (true) { - if (owner_ == nullptr) { // Unowned. - owner_ = self; - CHECK_EQ(lock_count_, 0); - // When debugging, save the current monitor holder for future - // acquisition failures to use in sampled logging. - if (lock_profiling_threshold_ != 0) { - locking_method_ = self->GetCurrentMethod(&locking_dex_pc_); - } - break; - } else if (owner_ == self) { // Recursive. - lock_count_++; - break; + if (TryLockLocked(self)) { + return; } // Contended. const bool log_contention = (lock_profiling_threshold_ != 0); @@ -430,8 +443,6 @@ void Monitor::Lock(Thread* self) { monitor_lock_.Lock(self); // Reacquire locks in order. --num_waiters_; } - - AtraceMonitorLock(self, GetObject(), false /* is_wait */); } static void ThrowIllegalMonitorStateExceptionF(const char* fmt, ...) @@ -852,7 +863,7 @@ static mirror::Object* FakeUnlock(mirror::Object* obj) return obj; } -mirror::Object* Monitor::MonitorEnter(Thread* self, mirror::Object* obj) { +mirror::Object* Monitor::MonitorEnter(Thread* self, mirror::Object* obj, bool trylock) { DCHECK(self != nullptr); DCHECK(obj != nullptr); self->AssertThreadSuspensionIsAllowable(); @@ -898,6 +909,9 @@ mirror::Object* Monitor::MonitorEnter(Thread* self, mirror::Object* obj) { InflateThinLocked(self, h_obj, lock_word, 0); } } else { + if (trylock) { + return nullptr; + } // Contention. contention_count++; Runtime* runtime = Runtime::Current(); @@ -916,8 +930,12 @@ mirror::Object* Monitor::MonitorEnter(Thread* self, mirror::Object* obj) { } case LockWord::kFatLocked: { Monitor* mon = lock_word.FatLockMonitor(); - mon->Lock(self); - return h_obj.Get(); // Success! + if (trylock) { + return mon->TryLock(self) ? h_obj.Get() : nullptr; + } else { + mon->Lock(self); + return h_obj.Get(); // Success! + } } case LockWord::kHashCode: // Inflate with the existing hashcode. |