Formatting
This commit is contained in:
+32
-34
@@ -189,10 +189,10 @@ import "core:sync"
|
||||
import "core:testing"
|
||||
import "core:thread"
|
||||
|
||||
// Multiple threads will each add 1.0 this many times.
|
||||
// If any updates are lost due to race conditions, the final sum will be wrong.
|
||||
@(test)
|
||||
test_concurrent_atomic_add_no_lost_updates :: proc(t: ^testing.T) {
|
||||
// Multiple threads will each add 1.0 this many times.
|
||||
// If any updates are lost due to race conditions, the final sum will be wrong.
|
||||
NUM_THREADS :: 8
|
||||
ITERATIONS_PER_THREAD :: 10_000
|
||||
|
||||
@@ -234,10 +234,10 @@ test_concurrent_atomic_add_no_lost_updates :: proc(t: ^testing.T) {
|
||||
testing.expect_value(t, shared_value, expected)
|
||||
}
|
||||
|
||||
// Start with a known value, multiple threads subtract.
|
||||
// If any updates are lost due to race conditions, the final result will be wrong.
|
||||
@(test)
|
||||
test_concurrent_atomic_sub_no_lost_updates :: proc(t: ^testing.T) {
|
||||
// Start with a known value, multiple threads subtract.
|
||||
// If any updates are lost due to race conditions, the final result will be wrong.
|
||||
NUM_THREADS :: 8
|
||||
ITERATIONS_PER_THREAD :: 10_000
|
||||
|
||||
@@ -278,11 +278,11 @@ test_concurrent_atomic_sub_no_lost_updates :: proc(t: ^testing.T) {
|
||||
testing.expect_value(t, shared_value, 0.0)
|
||||
}
|
||||
|
||||
// Each thread multiplies by 2.0 then divides by 2.0.
|
||||
// Since these are inverses, the final value should equal the starting value
|
||||
// regardless of how operations interleave.
|
||||
@(test)
|
||||
test_concurrent_atomic_mul_div_round_trip :: proc(t: ^testing.T) {
|
||||
// Each thread multiplies by 2.0 then divides by 2.0.
|
||||
// Since these are inverses, the final value should equal the starting value
|
||||
// regardless of how operations interleave.
|
||||
NUM_THREADS :: 8
|
||||
ITERATIONS_PER_THREAD :: 10_000
|
||||
|
||||
@@ -324,10 +324,10 @@ test_concurrent_atomic_mul_div_round_trip :: proc(t: ^testing.T) {
|
||||
testing.expect_value(t, shared_value, 1000.0)
|
||||
}
|
||||
|
||||
// Verify the f32 type dispatch works correctly under contention.
|
||||
// Same approach as the f64 add test but with f32.
|
||||
@(test)
|
||||
test_atomic_add_with_f32 :: proc(t: ^testing.T) {
|
||||
// Verify the f32 type dispatch works correctly under contention.
|
||||
// Same approach as the f64 add test but with f32.
|
||||
NUM_THREADS :: 8
|
||||
ITERATIONS_PER_THREAD :: 10_000
|
||||
|
||||
@@ -369,17 +369,17 @@ test_atomic_add_with_f32 :: proc(t: ^testing.T) {
|
||||
testing.expect_value(t, shared_value, expected)
|
||||
}
|
||||
|
||||
// Tests that the memory order passed to atomic_float_op's CAS success condition
|
||||
// provides full ordering guarantees for the entire float operation.
|
||||
//
|
||||
// Both sides use atomic_add_float (not raw intrinsics) to verify:
|
||||
// - Release on CAS success publishes prior non-atomic writes
|
||||
// - Acquire on CAS success makes those writes visible to the reader
|
||||
//
|
||||
// NOTE: This test may pass even with Relaxed ordering on x86 due to its strong memory model.
|
||||
// On ARM or other weak-memory architectures, using Relaxed here would likely cause failures.
|
||||
@(test)
|
||||
test_atomic_release_acquire_publish_visibility :: proc(t: ^testing.T) {
|
||||
// Tests that the memory order passed to atomic_float_op's CAS success condition
|
||||
// provides full ordering guarantees for the entire float operation.
|
||||
//
|
||||
// Both sides use atomic_add_float (not raw intrinsics) to verify:
|
||||
// - Release on CAS success publishes prior non-atomic writes
|
||||
// - Acquire on CAS success makes those writes visible to the reader
|
||||
//
|
||||
// NOTE: This test may pass even with Relaxed ordering on x86 due to its strong memory model.
|
||||
// On ARM or other weak-memory architectures, using Relaxed here would likely cause failures.
|
||||
NUM_READERS :: 4
|
||||
|
||||
Shared_State :: struct {
|
||||
@@ -476,20 +476,20 @@ test_atomic_release_acquire_publish_visibility :: proc(t: ^testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Stress test for every spinlock acquisition variant: N threads contend on a
|
||||
// single lock and perform a deliberate non-atomic read-modify-write on shared
|
||||
// data. Each iteration rotates through spinlock_try_lock, spinlock_lock,
|
||||
// spinlock_guard, and spinlock_tryguard so every variant runs concurrently and
|
||||
// must uphold mutual exclusion on the same lock.
|
||||
//
|
||||
// If mutual exclusion holds:
|
||||
// - `counter` ends at exactly NUM_THREADS * ITERATIONS_PER_THREAD
|
||||
// - `concurrent_holders` never exceeds 1
|
||||
//
|
||||
// A multi-step RMW (read → relax → write) widens the critical section so
|
||||
// any failure to exclude is virtually guaranteed to corrupt the counter.
|
||||
@(test)
|
||||
test_spinlock_mutual_exclusion :: proc(t: ^testing.T) {
|
||||
// Stress test for every spinlock acquisition variant: N threads contend on a
|
||||
// single lock and perform a deliberate non-atomic read-modify-write on shared
|
||||
// data. Each iteration rotates through spinlock_try_lock, spinlock_lock,
|
||||
// spinlock_guard, and spinlock_tryguard so every variant runs concurrently and
|
||||
// must uphold mutual exclusion on the same lock.
|
||||
//
|
||||
// If mutual exclusion holds:
|
||||
// - `counter` ends at exactly NUM_THREADS * ITERATIONS_PER_THREAD
|
||||
// - `concurrent_holders` never exceeds 1
|
||||
//
|
||||
// A multi-step RMW (read → relax → write) widens the critical section so
|
||||
// any failure to exclude is virtually guaranteed to corrupt the counter.
|
||||
NUM_THREADS :: 8
|
||||
ITERATIONS_PER_THREAD :: 50_000
|
||||
|
||||
@@ -560,13 +560,11 @@ test_spinlock_mutual_exclusion :: proc(t: ^testing.T) {
|
||||
spinlock_lock(&s.lock)
|
||||
critical_section(s)
|
||||
spinlock_unlock(&s.lock)
|
||||
case 2:
|
||||
// Scoped guard: unlocks automatically at the end of the block.
|
||||
case 2: // Scoped guard: unlocks automatically at the end of the block.
|
||||
if spinlock_guard(&s.lock) {
|
||||
critical_section(s)
|
||||
}
|
||||
case 3:
|
||||
// Scoped try-guard: retry until acquired, auto-unlocks on success.
|
||||
case 3: // Scoped try-guard: retry until acquired, auto-unlocks on success.
|
||||
for {
|
||||
if spinlock_tryguard(&s.lock) {
|
||||
critical_section(s)
|
||||
|
||||
Reference in New Issue
Block a user