Skip to content

Commit a6ade83

Browse files
committed
sync: fix TestMutexConcurrent test
Accessing the same variable from multiple goroutines is unsafe, and will fail with parallelism. A lightweight way to avoid issues is by using atomic variables.
1 parent 888d957 commit a6ade83

File tree

1 file changed

+11
-10
lines changed

1 file changed

+11
-10
lines changed

src/sync/mutex_test.go

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,9 @@ func TestMutexUncontended(t *testing.T) {
5858
// It will fail if multiple goroutines hold the lock simultaneously.
5959
func TestMutexConcurrent(t *testing.T) {
6060
var mu sync.Mutex
61-
var active uint
62-
var completed uint
63-
ok := true
61+
var active atomic.Uint32
62+
var completed atomic.Uint32
63+
var fail atomic.Uint32
6464

6565
const n = 10
6666
for i := 0; i < n; i++ {
@@ -74,11 +74,11 @@ func TestMutexConcurrent(t *testing.T) {
7474
mu.Lock()
7575

7676
// Increment the active counter.
77-
active++
77+
nowActive := active.Add(1)
7878

79-
if active > 1 {
79+
if nowActive > 1 {
8080
// Multiple things are holding the lock at the same time.
81-
ok = false
81+
fail.Store(1)
8282
} else {
8383
// Delay a bit.
8484
for k := j; k < n; k++ {
@@ -87,10 +87,11 @@ func TestMutexConcurrent(t *testing.T) {
8787
}
8888

8989
// Decrement the active counter.
90-
active--
90+
var one = 1
91+
active.Add(uint32(-one))
9192

9293
// This is completed.
93-
completed++
94+
completed.Add(1)
9495

9596
mu.Unlock()
9697
}()
@@ -104,10 +105,10 @@ func TestMutexConcurrent(t *testing.T) {
104105

105106
// Acquire the lock and check whether everything has completed.
106107
mu.Lock()
107-
done = completed == n
108+
done = completed.Load() == n
108109
mu.Unlock()
109110
}
110-
if !ok {
111+
if fail.Load() != 0 {
111112
t.Error("lock held concurrently")
112113
}
113114
}

0 commit comments

Comments
 (0)