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.
This commit is contained in:
Ayke van Laethem
2025-06-10 17:10:48 +02:00
committed by Ron Evans
parent 83de8ff77d
commit 525c41bac9
+11 -10
View File
@@ -58,9 +58,9 @@ func TestMutexUncontended(t *testing.T) {
// It will fail if multiple goroutines hold the lock simultaneously.
func TestMutexConcurrent(t *testing.T) {
var mu sync.Mutex
var active uint
var completed uint
ok := true
var active atomic.Uint32
var completed atomic.Uint32
var fail atomic.Uint32
const n = 10
for i := 0; i < n; i++ {
@@ -74,11 +74,11 @@ func TestMutexConcurrent(t *testing.T) {
mu.Lock()
// Increment the active counter.
active++
nowActive := active.Add(1)
if active > 1 {
if nowActive > 1 {
// Multiple things are holding the lock at the same time.
ok = false
fail.Store(1)
} else {
// Delay a bit.
for k := j; k < n; k++ {
@@ -87,10 +87,11 @@ func TestMutexConcurrent(t *testing.T) {
}
// Decrement the active counter.
active--
var one = 1
active.Add(uint32(-one))
// This is completed.
completed++
completed.Add(1)
mu.Unlock()
}()
@@ -104,10 +105,10 @@ func TestMutexConcurrent(t *testing.T) {
// Acquire the lock and check whether everything has completed.
mu.Lock()
done = completed == n
done = completed.Load() == n
mu.Unlock()
}
if !ok {
if fail.Load() != 0 {
t.Error("lock held concurrently")
}
}