diff options
author | Hans Boehm <hboehm@google.com> | 2020-07-13 10:49:13 -0700 |
---|---|---|
committer | Hans Boehm <hboehm@google.com> | 2020-07-14 17:58:03 -0700 |
commit | a3b75aea04f875da146c3ef71912e95f5ee903ac (patch) | |
tree | 88d328e3b2eb653b7417d1d640f0596f1a8cf16e | |
parent | 337cf0aa8a455479ca0bcb53a484fd9046c06a91 (diff) | |
download | art-a3b75aea04f875da146c3ef71912e95f5ee903ac.tar.gz |
Invoke futex wait with correct valueandroid-cts-11.0_r2
If we were woken up early, Mutex::ExclusiveLock() would mistakenly
retry the wait with the original state_and_contenders value,
in spite of the fact that the contenders part might have changed.
This could turn a mutex wait loop into a spin loop, causing
a battery issue, and an occasional livelock issue. Fix that
oversight.
Bug: 161005897
Test: Treehugger
Change-Id: Ie98ad188d0edbd9d9359954efa08d03e833f167b
Merged-In: Ie98ad188d0edbd9d9359954efa08d03e833f167b
(cherry picked from commit d4e6a992ad3b08585cbe50b7b55d23833ad32727)
-rw-r--r-- | runtime/base/mutex.cc | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/runtime/base/mutex.cc b/runtime/base/mutex.cc index 0d1b162be7..0b8c781858 100644 --- a/runtime/base/mutex.cc +++ b/runtime/base/mutex.cc @@ -457,7 +457,8 @@ void Mutex::ExclusiveLock(Thread* self) { SleepIfRuntimeDeleted(self); // Retry until not held. In heavy contention situations we otherwise get redundant // futex wakeups as a result of repeatedly decrementing and incrementing contenders. - } while ((state_and_contenders_.load(std::memory_order_relaxed) & kHeldMask) != 0); + cur_state = state_and_contenders_.load(std::memory_order_relaxed); + } while ((cur_state & kHeldMask) != 0); decrement_contenders(); } } |