// Copyright 2011 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package race_test import ( "sync" "testing" "time" ) func TestNoRaceCond(t *testing.T) { // tsan's test02 ch := make(chan bool, 1) var x int = 0 var mu sync.Mutex var cond *sync.Cond = sync.NewCond(&mu) var condition int = 0 var waker func() waker = func() { x = 1 mu.Lock() condition = 1 cond.Signal() mu.Unlock() } var waiter func() waiter = func() { go waker() cond.L.Lock() for condition != 1 { cond.Wait() } cond.L.Unlock() x = 2 ch <- true } go waiter() <-ch } func TestRaceCond(t *testing.T) { // tsan's test50 ch := make(chan bool, 2) var x int = 0 var mu sync.Mutex var condition int = 0 var cond *sync.Cond = sync.NewCond(&mu) var waker func() = func() { <-time.After(1e5) x = 1 mu.Lock() condition = 1 cond.Signal() mu.Unlock() <-time.After(1e5) mu.Lock() x = 3 mu.Unlock() ch <- true } var waiter func() = func() { mu.Lock() for condition != 1 { cond.Wait() } mu.Unlock() x = 2 ch <- true } x = 0 go waker() go waiter() <-ch <-ch } // We do not currently automatically // parse this test. It is intended that the creation // stack is observed manually not to contain // off-by-one errors func TestRaceAnnounceThreads(t *testing.T) { const N = 7 allDone := make(chan bool, N) var x int var f, g, h func() f = func() { x = 1 go g() go func() { x = 1 allDone <- true }() x = 2 allDone <- true } g = func() { for i := 0; i < 2; i++ { go func() { x = 1 allDone <- true }() allDone <- true } } h = func() { x = 1 x = 2 go f() allDone <- true } go h() for i := 0; i < N; i++ { <-allDone } } func TestNoRaceAfterFunc1(t *testing.T) { i := 2 c := make(chan bool) var f func() f = func() { i-- if i >= 0 { time.AfterFunc(0, f) } else { c <- true } } time.AfterFunc(0, f) <-c } func TestNoRaceAfterFunc2(t *testing.T) { var x int timer := time.AfterFunc(10, func() { x = 1 }) defer timer.Stop() _ = x } func TestNoRaceAfterFunc3(t *testing.T) { c := make(chan bool, 1) x := 0 time.AfterFunc(1e7, func() { x = 1 c <- true }) <-c } func TestRaceAfterFunc3(t *testing.T) { c := make(chan bool, 2) x := 0 time.AfterFunc(1e7, func() { x = 1 c <- true }) time.AfterFunc(2e7, func() { x = 2 c <- true }) <-c <-c } // This test's output is intended to be // observed manually. One should check // that goroutine creation stack is // comprehensible. func TestRaceGoroutineCreationStack(t *testing.T) { var x int var ch = make(chan bool, 1) f1 := func() { x = 1 ch <- true } f2 := func() { go f1() } f3 := func() { go f2() } f4 := func() { go f3() } go f4() x = 2 <-ch } // A nil pointer in a mutex method call should not // corrupt the race detector state. // Used to hang indefinitely. func TestNoRaceNilMutexCrash(t *testing.T) { var mutex sync.Mutex panics := 0 defer func() { if x := recover(); x != nil { mutex.Lock() panics++ mutex.Unlock() } else { panic("no panic") } }() var othermutex *sync.RWMutex othermutex.RLock() }