Home | History | Annotate | Download | only in testdata
      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 }
    153