Commit 02ba71e5 authored by Austin Clements's avatar Austin Clements

runtime/race: fix failing tests

Some race tests were sensitive to the goroutine scheduling order.
When this changed in commit e870f06c, these tests started to fail.

Fix TestRaceHeapParam by ensuring that the racing goroutine has
run before the test exits. Fix TestRaceRWMutexMultipleReaders by
adding a third reader to ensure that two readers wind up on the
same side of the writer (and race with each other) regardless of
the schedule. Fix TestRaceRange by ensuring that the racing
goroutine runs before the main goroutine exits the loop it races
with.

Change-Id: Iaf002f8730ea42227feaf2f3c51b9a1e57ccffdd
Reviewed-on: https://go-review.googlesource.com/9402Reviewed-by: 's avatarRuss Cox <rsc@golang.org>
parent f774e6a1
...@@ -335,6 +335,8 @@ func TestRaceRange(t *testing.T) { ...@@ -335,6 +335,8 @@ func TestRaceRange(t *testing.T) {
} }
done <- true done <- true
}(i) }(i)
// Ensure the goroutine runs before we continue the loop.
runtime.Gosched()
} }
for i := 0; i < N; i++ { for i := 0; i < N; i++ {
<-done <-done
...@@ -1727,13 +1729,16 @@ func TestNoRaceAsFunc4(t *testing.T) { ...@@ -1727,13 +1729,16 @@ func TestNoRaceAsFunc4(t *testing.T) {
} }
func TestRaceHeapParam(t *testing.T) { func TestRaceHeapParam(t *testing.T) {
done := make(chan bool)
x := func() (x int) { x := func() (x int) {
go func() { go func() {
x = 42 x = 42
done <- true
}() }()
return return
}() }()
_ = x _ = x
<-done
} }
func TestNoRaceEmptyStruct(t *testing.T) { func TestNoRaceEmptyStruct(t *testing.T) {
......
...@@ -54,13 +54,16 @@ func TestNoRaceRWMutex(t *testing.T) { ...@@ -54,13 +54,16 @@ func TestNoRaceRWMutex(t *testing.T) {
func TestRaceRWMutexMultipleReaders(t *testing.T) { func TestRaceRWMutexMultipleReaders(t *testing.T) {
var mu sync.RWMutex var mu sync.RWMutex
var x, y int64 = 0, 1 var x, y int64 = 0, 1
ch := make(chan bool, 3) ch := make(chan bool, 4)
go func() { go func() {
mu.Lock() mu.Lock()
defer mu.Unlock() defer mu.Unlock()
x = 2 x = 2
ch <- true ch <- true
}() }()
// Use three readers so that no matter what order they're
// scheduled in, two will be on the same side of the write
// lock above.
go func() { go func() {
mu.RLock() mu.RLock()
y = x + 1 y = x + 1
...@@ -73,6 +76,13 @@ func TestRaceRWMutexMultipleReaders(t *testing.T) { ...@@ -73,6 +76,13 @@ func TestRaceRWMutexMultipleReaders(t *testing.T) {
mu.RUnlock() mu.RUnlock()
ch <- true ch <- true
}() }()
go func() {
mu.RLock()
y = x + 3
mu.RUnlock()
ch <- true
}()
<-ch
<-ch <-ch
<-ch <-ch
<-ch <-ch
...@@ -82,7 +92,7 @@ func TestRaceRWMutexMultipleReaders(t *testing.T) { ...@@ -82,7 +92,7 @@ func TestRaceRWMutexMultipleReaders(t *testing.T) {
func TestNoRaceRWMutexMultipleReaders(t *testing.T) { func TestNoRaceRWMutexMultipleReaders(t *testing.T) {
var mu sync.RWMutex var mu sync.RWMutex
x := int64(0) x := int64(0)
ch := make(chan bool, 3) ch := make(chan bool, 4)
go func() { go func() {
mu.Lock() mu.Lock()
defer mu.Unlock() defer mu.Unlock()
...@@ -103,6 +113,14 @@ func TestNoRaceRWMutexMultipleReaders(t *testing.T) { ...@@ -103,6 +113,14 @@ func TestNoRaceRWMutexMultipleReaders(t *testing.T) {
mu.RUnlock() mu.RUnlock()
ch <- true ch <- true
}() }()
go func() {
mu.RLock()
y := x + 3
_ = y
mu.RUnlock()
ch <- true
}()
<-ch
<-ch <-ch
<-ch <-ch
<-ch <-ch
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment