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