Add missing storeload memory fences

There is no synchronize with relationship between the monitor micro-
lock and the onDeck microlock, so it is possible for an onDeck.load to
move above a contendersList.store, or a contendersList.load to move
above an ondeck.store.

To fix this issue a full memory fence (mm_mfence on x86) is needed
after the last store in the contendersList and onDeck critical regions.

Change-Id: I5beb7dfe0d21010c5bf00cd65d59b9c7af58e919


[ROCm/clr commit: f10435a1ef]
This commit is contained in:
Laurent Morichetti
2020-08-23 19:52:50 -07:00
committed by Saleel Kudchadker
parent ebeb05289c
commit 19f64478f1
2 changed files with 9 additions and 0 deletions
+4
View File
@@ -205,6 +205,10 @@ void Monitor::finishUnlock() {
return;
}
// A StoreLoad barrier is required to make sure the onDeck_ store is published before
// the contendersList_ micro-lock check.
std::atomic_thread_fence(std::memory_order_seq_cst);
// We do not have an on-deck thread (semaphore == NULL). Return if
// the contention list is empty or if the lock got acquired again.
head = contendersList_;
+5
View File
@@ -228,6 +228,11 @@ inline void Monitor::unlock() {
while (!contendersList_.compare_exchange_weak(ptr, ptr & ~kLockBit, std::memory_order_acq_rel,
std::memory_order_acquire))
;
// A StoreLoad barrier is required to make sure future loads do not happen before the
// contendersList_ store is published.
std::atomic_thread_fence(std::memory_order_seq_cst);
//
// We succeeded the CAS from locked to unlocked.
// This is the end of the critical region.