github.com/likebike/go--@v0.0.0-20190911215757-0bd925d16e96/go/src/runtime/race/testdata/rwmutex_test.go (about) 1 // Copyright 2012 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 TestRaceMutexRWMutex(t *testing.T) { 14 var mu1 sync.Mutex 15 var mu2 sync.RWMutex 16 var x int16 = 0 17 _ = x 18 ch := make(chan bool, 2) 19 go func() { 20 mu1.Lock() 21 defer mu1.Unlock() 22 x = 1 23 ch <- true 24 }() 25 go func() { 26 mu2.Lock() 27 x = 2 28 mu2.Unlock() 29 ch <- true 30 }() 31 <-ch 32 <-ch 33 } 34 35 func TestNoRaceRWMutex(t *testing.T) { 36 var mu sync.RWMutex 37 var x, y int64 = 0, 1 38 _ = y 39 ch := make(chan bool, 2) 40 go func() { 41 mu.Lock() 42 defer mu.Unlock() 43 x = 2 44 ch <- true 45 }() 46 go func() { 47 mu.RLock() 48 y = x 49 mu.RUnlock() 50 ch <- true 51 }() 52 <-ch 53 <-ch 54 } 55 56 func TestRaceRWMutexMultipleReaders(t *testing.T) { 57 var mu sync.RWMutex 58 var x, y int64 = 0, 1 59 ch := make(chan bool, 4) 60 go func() { 61 mu.Lock() 62 defer mu.Unlock() 63 x = 2 64 ch <- true 65 }() 66 // Use three readers so that no matter what order they're 67 // scheduled in, two will be on the same side of the write 68 // lock above. 69 go func() { 70 mu.RLock() 71 y = x + 1 72 mu.RUnlock() 73 ch <- true 74 }() 75 go func() { 76 mu.RLock() 77 y = x + 2 78 mu.RUnlock() 79 ch <- true 80 }() 81 go func() { 82 mu.RLock() 83 y = x + 3 84 mu.RUnlock() 85 ch <- true 86 }() 87 <-ch 88 <-ch 89 <-ch 90 <-ch 91 _ = y 92 } 93 94 func TestNoRaceRWMutexMultipleReaders(t *testing.T) { 95 var mu sync.RWMutex 96 x := int64(0) 97 ch := make(chan bool, 4) 98 go func() { 99 mu.Lock() 100 defer mu.Unlock() 101 x = 2 102 ch <- true 103 }() 104 go func() { 105 mu.RLock() 106 y := x + 1 107 _ = y 108 mu.RUnlock() 109 ch <- true 110 }() 111 go func() { 112 mu.RLock() 113 y := x + 2 114 _ = y 115 mu.RUnlock() 116 ch <- true 117 }() 118 go func() { 119 mu.RLock() 120 y := x + 3 121 _ = y 122 mu.RUnlock() 123 ch <- true 124 }() 125 <-ch 126 <-ch 127 <-ch 128 <-ch 129 } 130 131 func TestNoRaceRWMutexTransitive(t *testing.T) { 132 var mu sync.RWMutex 133 x := int64(0) 134 ch := make(chan bool, 2) 135 go func() { 136 mu.RLock() 137 _ = x 138 mu.RUnlock() 139 ch <- true 140 }() 141 go func() { 142 time.Sleep(1e7) 143 mu.RLock() 144 _ = x 145 mu.RUnlock() 146 ch <- true 147 }() 148 time.Sleep(2e7) 149 mu.Lock() 150 x = 42 151 mu.Unlock() 152 <-ch 153 <-ch 154 }