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]
Этот коммит содержится в:
Laurent Morichetti
2020-08-23 19:52:50 -07:00
коммит произвёл Saleel Kudchadker
родитель ebeb05289c
Коммит 19f64478f1
2 изменённых файлов: 9 добавлений и 0 удалений
+4
Просмотреть файл
@@ -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
Просмотреть файл
@@ -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.