0
votes

The following is a quote from C++ Standard - Memory Order:

If an atomic store in thread A is tagged memory_order_release and an atomic load in thread B from the same variable is tagged memory_order_acquire, all memory writes (non-atomic and relaxed atomic) that happened-before the atomic store from the point of view of thread A, become visible side-effects in thread B. That is, once the atomic load is completed, thread B is guaranteed to see everything thread A wrote to memory.

The synchronization is established only between the threads releasing and acquiring the same atomic variable. Other threads can see different order of memory accesses than either or both of the synchronized threads.

Consider an atomic variable v and the following steps:

  1. Thread A stores in v using memory_order_release
  2. Thread B stores in v using memory_order_release
  3. Thread C loads from v using memory_order_acquire

Is the following statement true: "thread C is guaranteed to see everything thread A or B wrote to memory."

EDIT: I am moving my comment here to make the point more clear.

The C++ quote that I have up there does not say anything about B must read what is written by A. All it says is that A and B release/acquire on the same variable. That is exactly, what I am doing in those 3 steps: A and B release something, and C acquires something. Where does it say in the spec that acquire matches with the last release and not necessarily anything before that?

So far there is nothing to say that any of these operations happens-before any of the others, so no way to guarantee anything.Nate Eldredge
If all threads are just loading or storing to the same memory location, the memory order has no effect whatsoever. The only thing that matters is that they use atomic operations, and then C either sees the value A stored, the value B stored, or the value that was in there before A and B stored anything, just not anything else.G. Sliepen
What you can say in this situation is that if thread C's load gets a value that could only have been put there by A's store, then C sees everything that A wrote prior to the load. And the same for B's store. But if it does see the value which A stored, then unless there is more logic to the program, it has no way of knowing whether or not B did its store before that, so there cannot be any guarantee of C seeing what B previously wrote.Nate Eldredge
Note cppreference.com is not the C++ standard, but rather an independent community project that attempts to provide more accessible information about the language. In particular the text you cite does not appear in the standard itself. But the standard does say things like "For example, an atomic store-release synchronizes with a load-acquire that takes its value from the store".Nate Eldredge
Maybe what you are looking for is atomics.order p2 in n3337: "An atomic operation A that performs a release operation on an atomic object M synchronizes with an atomic operation B that performs an acquire operation on M and takes its value from any side effect in the release sequence headed by A." The only way you learn anything about synchronization is if the value returned by the load matches a value known to be stored by a particular store. The cppreference text takes that as a given.Nate Eldredge