cppreference's page on compare_exchange gives the following example code (paraphrased snippet):
while(!head.compare_exchange_weak(new_node->next,
new_node,
std::memory_order_release,
std::memory_order_relaxed))
; // empty body
Suppose you run this once on thread A, and once on thread B. Nothing else is touching head
or its associated data. Thread B's invocation happens to start after thread A's has happened (in real time), but A's changes have not yet propagated to the cache of the CPU running Thread B.
What forces A's changes to get to B? That is to say, why is the execution where B's weak compare exchange simply fails indefinitely and the CPU cache remains stale not allowed? Or is it allowed?
It seems like the CPU running B is not being forced to go out and sync in the changes made by A, because the failure memory ordering is relaxed. So why does the hardware ever do so? Is this an implicit guarantee of the C++ spec, or of the hardware, or is bounded-staleness-of-memory a standard documented guarantee?
Good question! This is actually specifically addressed by clause 25 in §1.10 of the C++11 standard:
An implementation should ensure that the last value (in modification order) assigned by an atomic or synchronization operation will become visible to all other threads in a finite period of time.
So the answer is yes, the value is guaranteed to eventually propagate to the other thread, even with relaxed memory ordering.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With