Well, what the Go memory model says is this:

"The memory operations in each goroutine must correspond to a correct
sequential execution of that goroutine, given the values read from and
written to memory. That execution must be consistent with the sequenced
before relation, defined as the partial order requirements set out by the
Go language specification for Go's control flow constructs as well as the
order of evaluation for expressions."

What that means is, you follow the semantics of the language to determine
what a sequential "everything in order" execution would do, and you keep
track of the reads and writes which that does. The compiler can meet
Requirement One provided the "values read from and written to memory" by
"that goroutine" are the same, and they must be consistent with the
"sequenced before" relation that is described in the following sections of
the memory model.

The sequenced before relation established by atomics is this:

"The APIs in the sync/atomic package are collectively “atomic operations”
that can be used to synchronize the execution of different goroutines. If
the effect of an atomic operation A is observed by atomic operation B, then
A is synchronized before B. All the atomic operations executed in a program
behave as though executed in some sequentially consistent order."

This only applies if *both *A and B are atomic operations.

On Thu, Sep 15, 2022 at 11:10 AM robert engels <reng...@ix.netcom.com>
wrote:

> Please see the “sequentially consistent” here
> https://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync
>
> This is what most references to “happens before” imply. (and their example
> is my exact example).
>
> On Sep 15, 2022, at 10:08 AM, robert engels <reng...@ix.netcom.com> wrote:
>
> This is not what “happens before” means - at least not in any other
> accepted concurrency designs.
>
> See my second example as to why.
>
> On Sep 15, 2022, at 10:02 AM, Thomas Bushnell BSG <tbushn...@google.com>
> wrote:
>
> Happens before works just fine with atomics. But in your example, x is not
> an atomic.
>
> Thomas
>
> On Thu, Sep 15, 2022 at 10:51 AM robert engels <reng...@ix.netcom.com>
> wrote:
>
>> Yea, the race detector is broken… it fails on the following code:
>>
>> package main
>>
>> import (
>>    "sync"
>>    "sync/atomic"
>> )
>>
>> func main() {
>>
>>    var x int32
>>    var y int32
>>
>>    w := sync.WaitGroup{}
>>    w.Add(2)
>>
>>    go func() {
>>       for {
>>          x = 1
>>          atomic.StoreInt32(&y, 1)
>>       }
>>       w.Done()
>>    }()
>>    go func() {
>>       for {
>>          if atomic.LoadInt32(&y) == 1 {
>>             if x != 1 {
>>                panic("should not happen")
>>             }
>>          }
>>       }
>>       w.Done()
>>    }()
>>    w.Wait()
>>
>> }
>>
>> The above code does not have a race, or Go doesn’t have “happens before”
>> semantics with its atomics.
>>
>>
>> On Sep 15, 2022, at 9:41 AM, Robert Engels <reng...@ix.netcom.com> wrote:
>>
>> To clarify, if the atomic read of Y sees the updated Y then a subsequent
>> non-atomic read of X must see the updated X. This is a happens before
>> relationship.
>>
>> The question was if the race detector understands this - I know - why not
>> try it out…
>>
>> On Sep 15, 2022, at 9:39 AM, Robert Engels <reng...@ix.netcom.com> wrote:
>>
>> 
>> I think it needs to see the updated X - which agrees with burak.
>>
>> Reading Z is race.
>>
>> On Sep 15, 2022, at 9:24 AM, burak serdar <bser...@computer.org> wrote:
>>
>> 
>>
>> On Thu, Sep 15, 2022 at 8:03 AM 'Thomas Bushnell BSG' via golang-nuts <
>> golang-nuts@googlegroups.com> wrote:
>>
>>> You cannot make that assumption. It's not about what the race detector
>>> can detect.
>>>
>>> Goroutine one:
>>>   Writes non-synchronized X
>>>   Writes atomic Y
>>>   Writes non-synchronized Z with the value of X+Y
>>>
>>> Goroutine two
>>>   Reads atomic Y and sees the new value
>>>
>>
>> The way I read the Go memory model, if Goroutine two sees the new value
>> of Y, non-synchronizes writes to X by Goroutine 2 happened before Y, and
>> thus, anything that happens after Y. This is based on:
>>
>> "If a synchronizing read-like memory operation r observes a synchronizing
>> write-like memory operation w (that is, if W(r) = w), then w is
>> synchronized before r."
>>
>> And:
>>
>> "The happens before relation is defined as the transitive closure of the
>> union of the sequenced before and synchronized before relations."
>>
>> Because:
>>   * The writes to non-synchronized X are sequenced before the atomic
>> write to Y
>>   * The atomic read Y happened after atomic write to Y if it sees the new
>> value
>>   * non-synchronized reads from X happen after that
>>
>> So that should not be a race.
>>
>> Am I reading this correctly?
>>
>>
>>
>>>
>>> Can goroutine two now read non-synchronized X and assume it sees the new
>>> value written by one? No, it cannot. There is no "happens before" relation
>>> connecting the two writes performed by goroutine one. Requirement one does
>>> not establish such a relationship. It only establishes that Z will be
>>> written with the correct sum of X and Y. There must be *some *sequential
>>> order within the context of goroutine one that sees the correct value; the
>>> compiler is free to swap the order of the writes X and Y.
>>>
>>> If X were an atomic, then Requirement two would come into play. But
>>> because X and Z are not atomic, they play no role in Requirement two. Note
>>> that the description of atomic in the model says that writes to *atomic
>>> *values have the property you want. And since there is no before
>>> relationship established by any of the following text, this synchronization
>>> cannot be relied on.
>>>
>>> Now you're asking whether the race detector ensures the synchronization
>>> property you're suggesting? The race detector doesn't ensure any
>>> synchronization properties; it detects bugs.
>>>
>>> I think it is capable of detecting this one.
>>>
>>> Thomas
>>>
>>>
>>>
>>>
>>> On Wed, Sep 14, 2022 at 11:01 PM robert engels <reng...@ix.netcom.com>
>>> wrote:
>>>
>>>> Hi,
>>>>
>>>> I am working on a new project, and the race detector is reporting a
>>>> race.
>>>>
>>>> Essentially, the code is
>>>>
>>>> var S []int
>>>>
>>>> several go routines write new S values using a mutex
>>>>
>>>> go routine Y reads S without grabbing a lock (it reads it initially
>>>> under lock)
>>>>
>>>> The semantics are such that Y can operate successfully with any valid
>>>> value of S (e.g. could be stale). (essentially S is used with copy on write
>>>> semantics)
>>>>
>>>> The race detector reports this as a race.
>>>>
>>>> I could change all reads of Y to use an atomic load, but I don’t think
>>>> it should be necessary.
>>>>
>>>> Is there any way to perform “lazy loads” in Go?
>>>>
>>>> And a follow-up:
>>>>
>>>> Is the race detector smart enough so that if a routines write to
>>>> several vars (v1…n)  and performs an atomic store to X, and another routine
>>>> atomically reads X it can also non atomically read v1…n and it will see the
>>>> stored values?
>>>>
>>>> This has been the long standing issue with the Go memory model and
>>>> “happens before”… but how does the race detector report this?
>>>>
>>>> (Some background, the library functions fine under heavy concurrent
>>>> stress tests - but the race detector says it is broken).
>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> 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/8EC74417-C4AD-4490-9231-6E869EE72D93%40ix.netcom.com
>>>> .
>>>>
>>>
>>> --
>>> 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/CA%2BYjuxtd%2BpaU_BNxXDrMAN9v71r-Qhm9LcXcN2fTtjD_6oWw-Q%40mail.gmail.com
>>> <https://groups.google.com/d/msgid/golang-nuts/CA%2BYjuxtd%2BpaU_BNxXDrMAN9v71r-Qhm9LcXcN2fTtjD_6oWw-Q%40mail.gmail.com?utm_medium=email&utm_source=footer>
>>> .
>>>
>>
>> --
>> 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/CAMV2Rqr4vggPOWjiQg6qN0tJjhhXncKHLMCDwkqZTHBJJ7%3Dmug%40mail.gmail.com
>> <https://groups.google.com/d/msgid/golang-nuts/CAMV2Rqr4vggPOWjiQg6qN0tJjhhXncKHLMCDwkqZTHBJJ7%3Dmug%40mail.gmail.com?utm_medium=email&utm_source=footer>
>> .
>>
>>
>> --
>> 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/93E2826E-1D85-48BE-BBD3-ED17F70C74F2%40ix.netcom.com
>> <https://groups.google.com/d/msgid/golang-nuts/93E2826E-1D85-48BE-BBD3-ED17F70C74F2%40ix.netcom.com?utm_medium=email&utm_source=footer>
>> .
>>
>>
>>
>
>

-- 
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/CA%2BYjuxseJ%2Be%3DeSAxdWr-vqiCzHqP%2BtR%2BtzgXk3ZiTC2%3DrPyufQ%40mail.gmail.com.

Reply via email to