github.com/likebike/go--@v0.0.0-20190911215757-0bd925d16e96/go/src/runtime/race/testdata/sync_test.go (about) 1 // Copyright 2011 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package race_test 6 7 import ( 8 "sync" 9 "testing" 10 "time" 11 ) 12 13 func TestNoRaceCond(t *testing.T) { 14 x := 0 15 _ = x 16 condition := 0 17 var mu sync.Mutex 18 cond := sync.NewCond(&mu) 19 go func() { 20 x = 1 21 mu.Lock() 22 condition = 1 23 cond.Signal() 24 mu.Unlock() 25 }() 26 mu.Lock() 27 for condition != 1 { 28 cond.Wait() 29 } 30 mu.Unlock() 31 x = 2 32 } 33 34 func TestRaceCond(t *testing.T) { 35 done := make(chan bool) 36 var mu sync.Mutex 37 cond := sync.NewCond(&mu) 38 x := 0 39 _ = x 40 condition := 0 41 go func() { 42 time.Sleep(10 * time.Millisecond) // Enter cond.Wait loop 43 x = 1 44 mu.Lock() 45 condition = 1 46 cond.Signal() 47 mu.Unlock() 48 time.Sleep(10 * time.Millisecond) // Exit cond.Wait loop 49 mu.Lock() 50 x = 3 51 mu.Unlock() 52 done <- true 53 }() 54 mu.Lock() 55 for condition != 1 { 56 cond.Wait() 57 } 58 mu.Unlock() 59 x = 2 60 <-done 61 } 62 63 // We do not currently automatically 64 // parse this test. It is intended that the creation 65 // stack is observed manually not to contain 66 // off-by-one errors 67 func TestRaceAnnounceThreads(t *testing.T) { 68 const N = 7 69 allDone := make(chan bool, N) 70 71 var x int 72 _ = x 73 74 var f, g, h func() 75 f = func() { 76 x = 1 77 go g() 78 go func() { 79 x = 1 80 allDone <- true 81 }() 82 x = 2 83 allDone <- true 84 } 85 86 g = func() { 87 for i := 0; i < 2; i++ { 88 go func() { 89 x = 1 90 allDone <- true 91 }() 92 allDone <- true 93 } 94 } 95 96 h = func() { 97 x = 1 98 x = 2 99 go f() 100 allDone <- true 101 } 102 103 go h() 104 105 for i := 0; i < N; i++ { 106 <-allDone 107 } 108 } 109 110 func TestNoRaceAfterFunc1(t *testing.T) { 111 i := 2 112 c := make(chan bool) 113 var f func() 114 f = func() { 115 i-- 116 if i >= 0 { 117 time.AfterFunc(0, f) 118 } else { 119 c <- true 120 } 121 } 122 123 time.AfterFunc(0, f) 124 <-c 125 } 126 127 func TestNoRaceAfterFunc2(t *testing.T) { 128 var x int 129 timer := time.AfterFunc(10, func() { 130 x = 1 131 }) 132 defer timer.Stop() 133 _ = x 134 } 135 136 func TestNoRaceAfterFunc3(t *testing.T) { 137 c := make(chan bool, 1) 138 x := 0 139 _ = x 140 time.AfterFunc(1e7, func() { 141 x = 1 142 c <- true 143 }) 144 <-c 145 } 146 147 func TestRaceAfterFunc3(t *testing.T) { 148 c := make(chan bool, 2) 149 x := 0 150 _ = x 151 time.AfterFunc(1e7, func() { 152 x = 1 153 c <- true 154 }) 155 time.AfterFunc(2e7, func() { 156 x = 2 157 c <- true 158 }) 159 <-c 160 <-c 161 } 162 163 // This test's output is intended to be 164 // observed manually. One should check 165 // that goroutine creation stack is 166 // comprehensible. 167 func TestRaceGoroutineCreationStack(t *testing.T) { 168 var x int 169 _ = x 170 var ch = make(chan bool, 1) 171 172 f1 := func() { 173 x = 1 174 ch <- true 175 } 176 f2 := func() { go f1() } 177 f3 := func() { go f2() } 178 f4 := func() { go f3() } 179 180 go f4() 181 x = 2 182 <-ch 183 } 184 185 // A nil pointer in a mutex method call should not 186 // corrupt the race detector state. 187 // Used to hang indefinitely. 188 func TestNoRaceNilMutexCrash(t *testing.T) { 189 var mutex sync.Mutex 190 panics := 0 191 defer func() { 192 if x := recover(); x != nil { 193 mutex.Lock() 194 panics++ 195 mutex.Unlock() 196 } else { 197 panic("no panic") 198 } 199 }() 200 var othermutex *sync.RWMutex 201 othermutex.RLock() 202 }