Hi Gophers,
I have a question about a more subtle part of the language, the memory model regarding atomic operations.
The memory model doc on
go.dev states:
>If the effect of an atomic operation A is observed by atomic operation B, then A is synchronized before B.[...]
I.e. "observing side-effects" by another atomic operation establishes a synchronizes-before and therefore a happen-before relationship between the write and the observation of that side-effect.
My question is basically: Do only atomic Loads count as auch an "observation" or does CompareAndSwap also count here? Is there a happens-before between a Store and a later CompareAndSwap (independent of whether the CAS returns false or true?).
I asked myself this because the documentation also makes a comparison to C++ and Java:
>The preceding definition has the same semantics as C++’s sequentially consistent atomics and Java’s volatile variables.
However, there is a small difference between the C++ CAS (compare_exchange) and Go's.
In C++, if the swap fails (because the value of the atomic is not the provided expected old value), it will change the old value (which it receives as a reference) to the new value of the atomic. This makes it clear that it counts as a read in any case. In Go (and other languages, e.g. Java), CompareAndSwap does not do this. Thus, one could get the idea that maybe CompareAndSwap doesn't count as a "read" as far as memory model and compiler reorderings and so on are concerned, because it does not read the current value of the atomic on a "program level", returning nothing to the "user", it only reads (compares to) it internally in its inner workings.
My question is thus: Does atomic.CompareAndSwap count as a read in this context and is there a happens-before relationship between a previous store and a later compare-and-swap (both if the CAS fails or succeeds?)
Thank you all for reading this wall of text.
-Antonio