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
5package race_test
6
7import (
8	"sync"
9	"testing"
10	"time"
11)
12
13func TestNoRaceMutex(t *testing.T) {
14	var mu sync.Mutex
15	var x int16 = 0
16	_ = x
17	ch := make(chan bool, 2)
18	go func() {
19		mu.Lock()
20		defer mu.Unlock()
21		x = 1
22		ch <- true
23	}()
24	go func() {
25		mu.Lock()
26		x = 2
27		mu.Unlock()
28		ch <- true
29	}()
30	<-ch
31	<-ch
32}
33
34func TestRaceMutex(t *testing.T) {
35	var mu sync.Mutex
36	var x int16 = 0
37	_ = x
38	ch := make(chan bool, 2)
39	go func() {
40		x = 1
41		mu.Lock()
42		defer mu.Unlock()
43		ch <- true
44	}()
45	go func() {
46		x = 2
47		mu.Lock()
48		mu.Unlock()
49		ch <- true
50	}()
51	<-ch
52	<-ch
53}
54
55func TestRaceMutex2(t *testing.T) {
56	var mu1 sync.Mutex
57	var mu2 sync.Mutex
58	var x int8 = 0
59	_ = x
60	ch := make(chan bool, 2)
61	go func() {
62		mu1.Lock()
63		defer mu1.Unlock()
64		x = 1
65		ch <- true
66	}()
67	go func() {
68		mu2.Lock()
69		x = 2
70		mu2.Unlock()
71		ch <- true
72	}()
73	<-ch
74	<-ch
75}
76
77func TestNoRaceMutexPureHappensBefore(t *testing.T) {
78	var mu sync.Mutex
79	var x int16 = 0
80	_ = x
81	written := false
82	ch := make(chan bool, 2)
83	go func() {
84		x = 1
85		mu.Lock()
86		written = true
87		mu.Unlock()
88		ch <- true
89	}()
90	go func() {
91		time.Sleep(100 * time.Microsecond)
92		mu.Lock()
93		for !written {
94			mu.Unlock()
95			time.Sleep(100 * time.Microsecond)
96			mu.Lock()
97		}
98		mu.Unlock()
99		x = 1
100		ch <- true
101	}()
102	<-ch
103	<-ch
104}
105
106func TestNoRaceMutexSemaphore(t *testing.T) {
107	var mu sync.Mutex
108	ch := make(chan bool, 2)
109	x := 0
110	_ = x
111	mu.Lock()
112	go func() {
113		x = 1
114		mu.Unlock()
115		ch <- true
116	}()
117	go func() {
118		mu.Lock()
119		x = 2
120		mu.Unlock()
121		ch <- true
122	}()
123	<-ch
124	<-ch
125}
126
127// from doc/go_mem.html
128func TestNoRaceMutexExampleFromHtml(t *testing.T) {
129	var l sync.Mutex
130	a := ""
131
132	l.Lock()
133	go func() {
134		a = "hello, world"
135		l.Unlock()
136	}()
137	l.Lock()
138	_ = a
139}
140
141func TestRaceMutexOverwrite(t *testing.T) {
142	c := make(chan bool, 1)
143	var mu sync.Mutex
144	go func() {
145		mu = sync.Mutex{}
146		c <- true
147	}()
148	mu.Lock()
149	<-c
150}
151