There are two different viewpoints you can take. Either the Go Memory
Model must stand alone, and any concurrency claims made by the language
and standard library must be based on the limited set of operations
defined in the GMM, or the GMM provides the definitions and provides a
substantial, but not complete, list of operations satisfying that
definition, and a standard library package (or language feature) may
claim to satisfy the GMM definitions by some unspecified internal means.
If you accept the second, than I believe the documentation of the
sync/atomic package is enough to allow atomic operations to be used to
establish a happens-before relationship.
* burak serdar <
bse...@computer.org> [191111 21:03]:
> You cannot define a "happens-before" relationship using only atomics
^ Accepting the atomic documentation, I disagree with this.
> with the current memory model. The happens-before relationship, the
^ Either way, I completely disagree
with this.
> way it is written, relies on one goroutine blocking until the other
> comes to a point where "things happen" before the block is released.
> There is no blocking with atomics, hence there is no point in time
^ I (sort of) agree with this, ^ but not this.
Sort of, because any blocking that occurs takes place at the hardware
level (CPU and memory controller working out any cache and memory bus
contention).
> where one goroutine can be sure of things happened in the other
> goroutine.
>
> The only guarantee with atomics is that when one goroutine reads a
> value, it will read the last written value. There are no guarantees on
> other values. According to the mm, things that happened before that
> final write may not be observable to other goroutines.
The memory model is not defined in terms of blocking; in fact the only
mention of blocking is in the explanatory, non-normative text for
sync.Once. Blocking is a consequence of some operations in order to
obey the memory model; it is not the cause.
The memory model is defined in terms of happens-before relationships,
and says that certain operations create such a relationship.
My claim is that the GMM gives exactly three mutually exclusive choices:
Also, if e1 does not happen before e2 and does not happen after e2,
then we say that e1 and e2 happen concurrently.
There is no fourth choice, so if e1 and e2 do not happen concurrently,
then they have one of the happens-before relationships.
Most of the synchronization operations (e.g. channel reads and writes)
define that a happens-before relationship exists in a specific
direction.
The atomic package is different in that it specifies that two atomic
operations to the same memory location do not happen concurrently. By
logical inference, rather than explicit statement, there must be a
happens-before relationship, but the direction of that relationship is
not specified. You must use "pure logic" (in the mathematical sense),
if possible, to determine the direction.
I would be perfectly happy to have the memory model specify:
If an atomic read r [in one goroutine] can be proven to have observed
a specific atomic write w [from another goroutine], than the w
happens-before the r.
I like this even better:
Two atomic operations to the same variable v do not happen
concurrently, and thus a happens-before relationship exists between
them in an unspecified direction. Sometimes logic may be used to
prove the direction of the relationship.
If you adhere to the first viewpoint at the top of this message, than I
would say something like the above would be a mandatory addition to the
GMM document. However, I am perfectly happy with the viewpoint that the
GMM provides the definitions, and the list of operations satisfying
those definitions can be specified in the Language Specification and the
standard library documentation.
...Marvin