Fix possible deadlock in AddAccessFlags and ClearAccessFlags
Reload the value each loop iteration or else it will spin forever
if the CAS fails due to another thread adding a different flag.
Test: mm
Change-Id: Idc320921597acc20d56301899b398756563029f2
diff --git a/runtime/art_method.h b/runtime/art_method.h
index b38508b..11dcc35 100644
--- a/runtime/art_method.h
+++ b/runtime/art_method.h
@@ -95,18 +95,20 @@
// This setter guarantees atomicity.
void AddAccessFlags(uint32_t flag) {
- uint32_t old_access_flags = access_flags_.load(std::memory_order_relaxed);
+ uint32_t old_access_flags;
uint32_t new_access_flags;
do {
+ old_access_flags = access_flags_.load(std::memory_order_relaxed);
new_access_flags = old_access_flags | flag;
} while (!access_flags_.compare_exchange_weak(old_access_flags, new_access_flags));
}
// This setter guarantees atomicity.
void ClearAccessFlags(uint32_t flag) {
- uint32_t old_access_flags = access_flags_.load(std::memory_order_relaxed);
+ uint32_t old_access_flags;
uint32_t new_access_flags;
do {
+ old_access_flags = access_flags_.load(std::memory_order_relaxed);
new_access_flags = old_access_flags & ~flag;
} while (!access_flags_.compare_exchange_weak(old_access_flags, new_access_flags));
}