FWIW, I agree with Caleb's reading here. It makes sense to talk about inlining and registerization when talking about how the Go memory model should be implemented - but I agree, with Caleb, that the memory model specifies the code to be correct. So if inlining and registers lead to the code being incorrect, I would, personally, read that as a bug in the compiler.
If you agree that atomic.StoreUint32(&v, 1) constitutes a write to &v *in a single goroutine*, i.e. if you agree that this var x uint32 atomic.StoreUint32(&x, 42) fmt.Println(x) has to always print 42, that already constitutes a sufficient argument that the code above is correct. Because the memory model specifies that a) the sequence o.m.Lock < o.done == 0 < atomic.StoreUint32 < o.m.Unlock (in each goroutine) and b) g1(o.m.Unlock) < g2(o.m.Lock) (if g1 wins the mutex). This already implies that g1(o.m.Lock) < g1(o.done == 0) < g1(atomic.StoreUint32) < g1(o.m.Unlock) < g2(o.m.Lock) < g2(o.done == 0) < … In the end, the Go memory model describes the order in terms of reads and writes and as long as we agree that a) o.done == 0 constitutes a read of &o.done and b) atomic.StoreUint32(&o.done, 1) constitutes a write to &o.done, the memory model orders them as expected. AIUI Dave's argument is, that o.done == 0 does not have to constitute a read of &o.done (as the compiler might not actually access that address again, because it thinks the value is already in a register), but I don't think this is a valid reasoning: The *code* clearly specifies this to be semantically a read from that address. The memory model specifies in what circumstances the compiler might optimize the actual semantics to differ from the ones in the code. For example, by keeping the value in a register and not load it again. And in this case, it clearly specifies that the compiler is not allowed to make that optimization. On Fri, Dec 29, 2017 at 11:08 AM, Henrik Johansson <dahankz...@gmail.com> wrote: > Surely single goroutine scenarios are trivial? Anything else would be a > compiler bug. In multiple goroutine scenarios a lock must be held or some > of the atomic functions are needed. Any other use that "works" are by > accident say on x86 or some other stricter arch. I am no expert in this but > surely hope this is true because much of my code depends on it... > > On Fri, Dec 29, 2017, 09:57 Caleb Spare <cesp...@gmail.com> wrote: > >> > I believe that program will always print 2, however when you bring >> multiple Goroutines into the mix, I’m less sure. >> >> I'm using examples without goroutines because the crux of our >> discussion, as I understand it, is whether a plain read ('if o.done == >> 0') will read the result of an atomic write >> ('atomic.StoreUint32(&o.done, 1)') given that there is a >> happens-before relationship between them. >> >> The simplest kind of happens-before relationship is that between >> sequential lines of straight-line code in a single goroutine. If you >> agree that the mutexes imply a happens-before relationship between the >> atomic write and the plain read, then we can simplify the discussion >> by only considering sequential code in a single goroutine. >> >> Regarding the sequential, single-goroutine example code: for my first >> example with atomic.StoreUint32 >> (https://play.golang.org/p/fdf8VeJ98Jv), you wrote >> >> > I agree it should print 2, but my reading of the memory model and >> > https://github.com/golang/go/issues/5045 doesn't give me any concrete >> > guarantee that it must. This is why i'm not sure about the >> > interactions between atomic and non atomic loads. >> >> but for the second example with a non-atomic store function >> (https://play.golang.org/p/gk3c6X_JdmQ), you wrote >> >> > I believe that program will always print 2 >> >> What's the distinction you see between them? >> >> -- >> You received this message because you are subscribed to the Google Groups >> "golang-nuts" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to golang-nuts+unsubscr...@googlegroups.com. >> For more options, visit https://groups.google.com/d/optout. >> > -- > You received this message because you are subscribed to the Google Groups > "golang-nuts" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to golang-nuts+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.