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