mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-17 11:13:27 +00:00
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:
committed by
Ron Evans
parent
83de8ff77d
commit
525c41bac9
+11
-10
@@ -58,9 +58,9 @@ func TestMutexUncontended(t *testing.T) {
|
|||||||
// It will fail if multiple goroutines hold the lock simultaneously.
|
// It will fail if multiple goroutines hold the lock simultaneously.
|
||||||
func TestMutexConcurrent(t *testing.T) {
|
func TestMutexConcurrent(t *testing.T) {
|
||||||
var mu sync.Mutex
|
var mu sync.Mutex
|
||||||
var active uint
|
var active atomic.Uint32
|
||||||
var completed uint
|
var completed atomic.Uint32
|
||||||
ok := true
|
var fail atomic.Uint32
|
||||||
|
|
||||||
const n = 10
|
const n = 10
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
@@ -74,11 +74,11 @@ func TestMutexConcurrent(t *testing.T) {
|
|||||||
mu.Lock()
|
mu.Lock()
|
||||||
|
|
||||||
// Increment the active counter.
|
// 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.
|
// Multiple things are holding the lock at the same time.
|
||||||
ok = false
|
fail.Store(1)
|
||||||
} else {
|
} else {
|
||||||
// Delay a bit.
|
// Delay a bit.
|
||||||
for k := j; k < n; k++ {
|
for k := j; k < n; k++ {
|
||||||
@@ -87,10 +87,11 @@ func TestMutexConcurrent(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Decrement the active counter.
|
// Decrement the active counter.
|
||||||
active--
|
var one = 1
|
||||||
|
active.Add(uint32(-one))
|
||||||
|
|
||||||
// This is completed.
|
// This is completed.
|
||||||
completed++
|
completed.Add(1)
|
||||||
|
|
||||||
mu.Unlock()
|
mu.Unlock()
|
||||||
}()
|
}()
|
||||||
@@ -104,10 +105,10 @@ func TestMutexConcurrent(t *testing.T) {
|
|||||||
|
|
||||||
// Acquire the lock and check whether everything has completed.
|
// Acquire the lock and check whether everything has completed.
|
||||||
mu.Lock()
|
mu.Lock()
|
||||||
done = completed == n
|
done = completed.Load() == n
|
||||||
mu.Unlock()
|
mu.Unlock()
|
||||||
}
|
}
|
||||||
if !ok {
|
if fail.Load() != 0 {
|
||||||
t.Error("lock held concurrently")
|
t.Error("lock held concurrently")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user