( apologies for the previous mangled message, re-posting from a saner UI ) On Sat, Jan 21, 2023 at 7:47 PM burak serdar <bser...@computer.org> wrote:
> > > On Sat, Jan 21, 2023 at 10:36 AM Peter Rabbitson <ribasu...@gmail.com> > wrote: > >> Greetings, >> >> I am trying to understand the exact mechanics of memory write ordering >> from within the same goroutine. I wrote a self-contained runnable example >> with the question inlined here: https://go.dev/play/p/ZXMg_Qq3ygF and am >> copying its header here: >> >> // Below is a complete example, with the question starting on line 38: >> // how do I ensure that a *separate Linux OS process* observing `IPCfile` >> // (either via pread() or mmap()) can *NEVER* observe W2 before W1. >> // The only permissible states are: >> // 1. no changes visible >> // 2. only W1 is visible >> // 3. both W1 and W2 are visible >> > > This is based on my interpretation of the go memory model: > > Atomic memory operations are sequentially consistent, so here: > > (*mmapBufAtomic.Load())[fSize-1] = 255 // W1 > (*mmapBufAtomic.Load())[0] = 42 // W2 > > The first atomic load happens before the second load. That also implies > the first write (W1) happens before the second (W2). However, there is no > guarantee that W2 will be observed by another goroutine. > This is perfectly acceptable ( see point 2. above ). Also note that there is no other goroutine that is looking at this: the observers are separate ( possibly not even go-based ) OS processes. I am strictly trying to get to a point where the writer process exemplified in the playground will issue the CPU write instructions in the order I expect. > I think what is really needed here is an atomic store byte operation. If > this is the only goroutine writing to this buffer, you can emulate that by > atomic.LoadUint32, set the highest/lowest byte, then atomic.StoreUint32 > This would not be viable: the W1 write is a single byte for the sake of brevity. In practice it will be a multi-GiB write, with a multi-KiB write following it, followed by a single-UInt write. All part of a lock-free "ratcheted" transactional implementation, allowing for incomplete writes, but no dirty reads - the "root pointer" is the last thing being updated, so an observer process sees "old state" or "new state" and nothing inbetween. This is why my quest to understand the precise behavior and guarantees of the resulting compiled program. -- 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. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAMrvTSLmXZjPBLoc-o8bbenY4Zo-jBdL2zYnKCN5SPceHkccEA%40mail.gmail.com.