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 <mailto: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 
>>> <mailto: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 
>>> <mailto:golang-nuts%2bunsubscr...@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
>>>  
>>> <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 
>>> <mailto: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 
>>> <mailto: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 
> <mailto: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/621ABC85-EFBF-4B9D-B94B-F27D6BDA7E85%40ix.netcom.com.

Reply via email to