Home | History | Annotate | Download | only in testdata
      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 	"runtime"
      9 	"sync"
     10 	"sync/atomic"
     11 	"testing"
     12 	"unsafe"
     13 )
     14 
     15 func TestNoRaceAtomicAddInt64(t *testing.T) {
     16 	var x1, x2 int8
     17 	var s int64
     18 	ch := make(chan bool, 2)
     19 	go func() {
     20 		x1 = 1
     21 		if atomic.AddInt64(&s, 1) == 2 {
     22 			x2 = 1
     23 		}
     24 		ch <- true
     25 	}()
     26 	go func() {
     27 		x2 = 1
     28 		if atomic.AddInt64(&s, 1) == 2 {
     29 			x1 = 1
     30 		}
     31 		ch <- true
     32 	}()
     33 	<-ch
     34 	<-ch
     35 }
     36 
     37 func TestRaceAtomicAddInt64(t *testing.T) {
     38 	var x1, x2 int8
     39 	var s int64
     40 	ch := make(chan bool, 2)
     41 	go func() {
     42 		x1 = 1
     43 		if atomic.AddInt64(&s, 1) == 1 {
     44 			x2 = 1
     45 		}
     46 		ch <- true
     47 	}()
     48 	go func() {
     49 		x2 = 1
     50 		if atomic.AddInt64(&s, 1) == 1 {
     51 			x1 = 1
     52 		}
     53 		ch <- true
     54 	}()
     55 	<-ch
     56 	<-ch
     57 }
     58 
     59 func TestNoRaceAtomicAddInt32(t *testing.T) {
     60 	var x1, x2 int8
     61 	var s int32
     62 	ch := make(chan bool, 2)
     63 	go func() {
     64 		x1 = 1
     65 		if atomic.AddInt32(&s, 1) == 2 {
     66 			x2 = 1
     67 		}
     68 		ch <- true
     69 	}()
     70 	go func() {
     71 		x2 = 1
     72 		if atomic.AddInt32(&s, 1) == 2 {
     73 			x1 = 1
     74 		}
     75 		ch <- true
     76 	}()
     77 	<-ch
     78 	<-ch
     79 }
     80 
     81 func TestNoRaceAtomicLoadAddInt32(t *testing.T) {
     82 	var x int64
     83 	var s int32
     84 	go func() {
     85 		x = 2
     86 		atomic.AddInt32(&s, 1)
     87 	}()
     88 	for atomic.LoadInt32(&s) != 1 {
     89 		runtime.Gosched()
     90 	}
     91 	x = 1
     92 }
     93 
     94 func TestNoRaceAtomicLoadStoreInt32(t *testing.T) {
     95 	var x int64
     96 	var s int32
     97 	go func() {
     98 		x = 2
     99 		atomic.StoreInt32(&s, 1)
    100 	}()
    101 	for atomic.LoadInt32(&s) != 1 {
    102 		runtime.Gosched()
    103 	}
    104 	x = 1
    105 }
    106 
    107 func TestNoRaceAtomicStoreCASInt32(t *testing.T) {
    108 	var x int64
    109 	var s int32
    110 	go func() {
    111 		x = 2
    112 		atomic.StoreInt32(&s, 1)
    113 	}()
    114 	for !atomic.CompareAndSwapInt32(&s, 1, 0) {
    115 		runtime.Gosched()
    116 	}
    117 	x = 1
    118 }
    119 
    120 func TestNoRaceAtomicCASLoadInt32(t *testing.T) {
    121 	var x int64
    122 	var s int32
    123 	go func() {
    124 		x = 2
    125 		if !atomic.CompareAndSwapInt32(&s, 0, 1) {
    126 			panic("")
    127 		}
    128 	}()
    129 	for atomic.LoadInt32(&s) != 1 {
    130 		runtime.Gosched()
    131 	}
    132 	x = 1
    133 }
    134 
    135 func TestNoRaceAtomicCASCASInt32(t *testing.T) {
    136 	var x int64
    137 	var s int32
    138 	go func() {
    139 		x = 2
    140 		if !atomic.CompareAndSwapInt32(&s, 0, 1) {
    141 			panic("")
    142 		}
    143 	}()
    144 	for !atomic.CompareAndSwapInt32(&s, 1, 0) {
    145 		runtime.Gosched()
    146 	}
    147 	x = 1
    148 }
    149 
    150 func TestNoRaceAtomicCASCASInt32_2(t *testing.T) {
    151 	var x1, x2 int8
    152 	var s int32
    153 	ch := make(chan bool, 2)
    154 	go func() {
    155 		x1 = 1
    156 		if !atomic.CompareAndSwapInt32(&s, 0, 1) {
    157 			x2 = 1
    158 		}
    159 		ch <- true
    160 	}()
    161 	go func() {
    162 		x2 = 1
    163 		if !atomic.CompareAndSwapInt32(&s, 0, 1) {
    164 			x1 = 1
    165 		}
    166 		ch <- true
    167 	}()
    168 	<-ch
    169 	<-ch
    170 }
    171 
    172 func TestNoRaceAtomicLoadInt64(t *testing.T) {
    173 	var x int32
    174 	var s int64
    175 	go func() {
    176 		x = 2
    177 		atomic.AddInt64(&s, 1)
    178 	}()
    179 	for atomic.LoadInt64(&s) != 1 {
    180 		runtime.Gosched()
    181 	}
    182 	x = 1
    183 }
    184 
    185 func TestNoRaceAtomicCASCASUInt64(t *testing.T) {
    186 	var x int64
    187 	var s uint64
    188 	go func() {
    189 		x = 2
    190 		if !atomic.CompareAndSwapUint64(&s, 0, 1) {
    191 			panic("")
    192 		}
    193 	}()
    194 	for !atomic.CompareAndSwapUint64(&s, 1, 0) {
    195 		runtime.Gosched()
    196 	}
    197 	x = 1
    198 }
    199 
    200 func TestNoRaceAtomicLoadStorePointer(t *testing.T) {
    201 	var x int64
    202 	var s unsafe.Pointer
    203 	var y int = 2
    204 	var p unsafe.Pointer = unsafe.Pointer(&y)
    205 	go func() {
    206 		x = 2
    207 		atomic.StorePointer(&s, p)
    208 	}()
    209 	for atomic.LoadPointer(&s) != p {
    210 		runtime.Gosched()
    211 	}
    212 	x = 1
    213 }
    214 
    215 func TestNoRaceAtomicStoreCASUint64(t *testing.T) {
    216 	var x int64
    217 	var s uint64
    218 	go func() {
    219 		x = 2
    220 		atomic.StoreUint64(&s, 1)
    221 	}()
    222 	for !atomic.CompareAndSwapUint64(&s, 1, 0) {
    223 		runtime.Gosched()
    224 	}
    225 	x = 1
    226 }
    227 
    228 func TestRaceAtomicStoreLoad(t *testing.T) {
    229 	c := make(chan bool)
    230 	var a uint64
    231 	go func() {
    232 		atomic.StoreUint64(&a, 1)
    233 		c <- true
    234 	}()
    235 	_ = a
    236 	<-c
    237 }
    238 
    239 func TestRaceAtomicLoadStore(t *testing.T) {
    240 	c := make(chan bool)
    241 	var a uint64
    242 	go func() {
    243 		_ = atomic.LoadUint64(&a)
    244 		c <- true
    245 	}()
    246 	a = 1
    247 	<-c
    248 }
    249 
    250 func TestRaceAtomicAddLoad(t *testing.T) {
    251 	c := make(chan bool)
    252 	var a uint64
    253 	go func() {
    254 		atomic.AddUint64(&a, 1)
    255 		c <- true
    256 	}()
    257 	_ = a
    258 	<-c
    259 }
    260 
    261 func TestRaceAtomicAddStore(t *testing.T) {
    262 	c := make(chan bool)
    263 	var a uint64
    264 	go func() {
    265 		atomic.AddUint64(&a, 1)
    266 		c <- true
    267 	}()
    268 	a = 42
    269 	<-c
    270 }
    271 
    272 // A nil pointer in an atomic operation should not deadlock
    273 // the rest of the program. Used to hang indefinitely.
    274 func TestNoRaceAtomicCrash(t *testing.T) {
    275 	var mutex sync.Mutex
    276 	var nilptr *int32
    277 	panics := 0
    278 	defer func() {
    279 		if x := recover(); x != nil {
    280 			mutex.Lock()
    281 			panics++
    282 			mutex.Unlock()
    283 		} else {
    284 			panic("no panic")
    285 		}
    286 	}()
    287 	atomic.AddInt32(nilptr, 1)
    288 }
    289