• Dmitriy Vyukov's avatar
    sync: fix race instrumentation of WaitGroup · 07cb48c3
    Dmitriy Vyukov authored
    Currently more than 1 gorutine can execute raceWrite() in Wait()
    in the following scenario:
    1. goroutine 1 executes first check of wg.counter, sees that it's == 0
    2. goroutine 2 executes first check of wg.counter, sees that it's == 0
    3. goroutine 2 locks the mutex, sees that he is the first waiter and executes raceWrite()
    4. goroutine 2 block on the semaphore
    5. goroutine 3 executes Done() and unblocks goroutine 2
    6. goroutine 1 lock the mutex, sees that he is the first waiter and executes raceWrite()
    
    It produces the following false report:
    WARNING: DATA RACE
    Write by goroutine 35:
      sync.raceWrite()
          src/pkg/sync/race.go:41 +0x33
      sync.(*WaitGroup).Wait()
          src/pkg/sync/waitgroup.go:103 +0xae
      command-line-arguments_test.TestNoRaceWaitGroupMultipleWait2()
          src/pkg/runtime/race/testdata/waitgroup_test.go:156 +0x19a
      testing.tRunner()
          src/pkg/testing/testing.go:361 +0x108
    
    Previous write by goroutine 36:
      sync.raceWrite()
          src/pkg/sync/race.go:41 +0x33
      sync.(*WaitGroup).Wait()
          src/pkg/sync/waitgroup.go:103 +0xae
      command-line-arguments_test.func·012()
          src/pkg/runtime/race/testdata/waitgroup_test.go:148 +0x4d
    
    R=golang-dev, r
    CC=golang-dev
    https://golang.org/cl/10424043
    07cb48c3
waitgroup.go 3.68 KB