Invoke futex wait with correct value
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)
diff --git a/runtime/base/mutex.cc b/runtime/base/mutex.cc
index 0d1b162..0b8c781 100644
--- a/runtime/base/mutex.cc
+++ b/runtime/base/mutex.cc
@@ -457,7 +457,8 @@
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();
}
}