summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Boehm <hboehm@google.com>2020-07-13 10:49:13 -0700
committerHans Boehm <hboehm@google.com>2020-07-14 17:58:03 -0700
commita3b75aea04f875da146c3ef71912e95f5ee903ac (patch)
tree88d328e3b2eb653b7417d1d640f0596f1a8cf16e
parent337cf0aa8a455479ca0bcb53a484fd9046c06a91 (diff)
downloadart-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.cc3
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();
}
}