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]
Этот коммит содержится в:
коммит произвёл
Saleel Kudchadker
родитель
ebeb05289c
Коммит
19f64478f1
@@ -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_;
|
||||
|
||||
@@ -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.
|
||||
|
||||
Ссылка в новой задаче
Block a user