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%2BYjuxvuc%3DKAUKUSn7WOgF0vVofGnxut7jfLtJhUdkFd%2B65dYw%40mail.gmail.com.

Reply via email to