Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What guarantees that a weak relaxed uncontended CAS loop terminates?

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?

like image 918
Craig Gidney Avatar asked Mar 16 '15 18:03

Craig Gidney


1 Answers

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.

like image 187
Cameron Avatar answered Oct 29 '22 12:10

Cameron