code wiki / (root) / nx_atomic_intrinsic_test.nx

nx_atomic_intrinsic_test.nx source

↩ module page · 113 lines · 4153 B

1// nx_atomic_intrinsic_test.nx -- exercise the __atomic_* compiler 2// builtins. Single-threaded smoke; SMP semantics get exercised by 3// nx_thread_pool integration tests once threads ship. 4// 5// Each test isolates one builtin so a failure points at the exact 6// codegen path: load / store / cas / faa / fence. 7 8import "nx_kernel_v2.nx" 9import "nx_log.nx" 10 11// The memory-ordering constants are no longer declared here: they moved to nx_syscalls.nx on 12// 2026-08-25 and this file already imports it transitively. This local copy was one of THREE 13// independent declarations of the same values (corpus_complete=1); it is deleted rather than kept 14// in sync, because a constant with three homes is three rulers that agree until one does not. 15 16func t1_load_store_round_trip() -> i64 { 17 let raw: *u8 = sys_mmap(16) 18 let cell: *i64 = raw as *i64 19 *cell = 0 20 __atomic_store_i64(cell, 42, NX_MO_SEQ_CST) 21 let r: i64 = __atomic_load_i64(cell, NX_MO_SEQ_CST) 22 if r != 42 { return 1 } 23 return 0 24} 25 26func t2_cas_success() -> i64 { 27 let raw: *u8 = sys_mmap(16) 28 let cell: *i64 = raw as *i64 29 *cell = 100 30 let ok: i64 = __atomic_cas_i64(cell, 100, 200, NX_MO_SEQ_CST) 31 if ok != 1 { return 21 } 32 if *cell != 200 { return 22 } 33 return 0 34} 35 36func t3_cas_failure_leaves_cell() -> i64 { 37 let raw: *u8 = sys_mmap(16) 38 let cell: *i64 = raw as *i64 39 *cell = 100 40 let r: i64 = __atomic_cas_i64(cell, 999, 7, NX_MO_SEQ_CST) 41 if r != 0 { return 31 } 42 if *cell != 100 { return 32 } 43 return 0 44} 45 46func t4_faa_returns_prior() -> i64 { 47 let raw: *u8 = sys_mmap(16) 48 let cell: *i64 = raw as *i64 49 *cell = 10 50 let prior: i64 = __atomic_faa_i64(cell, 5, NX_MO_SEQ_CST) 51 if prior != 10 { return 41 } 52 if *cell != 15 { return 42 } 53 let prior2: i64 = __atomic_faa_i64(cell, -3, NX_MO_SEQ_CST) 54 if prior2 != 15 { return 43 } 55 if *cell != 12 { return 44 } 56 return 0 57} 58 59func t5_fence_compiles_and_runs() -> i64 { 60 __atomic_fence(NX_MO_SEQ_CST) 61 __atomic_fence(NX_MO_RELAXED) 62 __atomic_fence(NX_MO_ACQUIRE) 63 __atomic_fence(NX_MO_RELEASE) 64 return 0 65} 66 67// Composite spinlock pattern. Take + take-fail + release + take. 68func t6_spinlock_via_cas() -> i64 { 69 let raw: *u8 = sys_mmap(16) 70 let lock: *i64 = raw as *i64 71 *lock = 0 72 let take_a: i64 = __atomic_cas_i64(lock, 0, 1, NX_MO_ACQUIRE) 73 if take_a != 1 { return 61 } 74 let take_b: i64 = __atomic_cas_i64(lock, 0, 1, NX_MO_ACQUIRE) 75 if take_b != 0 { return 62 } 76 __atomic_store_i64(lock, 0, NX_MO_RELEASE) 77 let take_c: i64 = __atomic_cas_i64(lock, 0, 1, NX_MO_ACQUIRE) 78 if take_c != 1 { return 63 } 79 return 0 80} 81 82func main() -> nx_exit { 83 println("=== nx_atomic intrinsic smoke (compiler-builtin codegen) ===" as *u8) 84 85 let r1: i64 = t1_load_store_round_trip() 86 if r1 != 0 { println("T1 load/store FAIL" as *u8); return r1 } 87 println("T1 load/store PASS __atomic_load_i64 + __atomic_store_i64 round-trip" as *u8) 88 89 let r2: i64 = t2_cas_success() 90 if r2 != 0 { println("T2 cas success FAIL" as *u8); return r2 } 91 println("T2 cas success PASS __atomic_cas_i64 swaps + reports 1" as *u8) 92 93 let r3: i64 = t3_cas_failure_leaves_cell() 94 if r3 != 0 { println("T3 cas failure FAIL" as *u8); return r3 } 95 println("T3 cas failure PASS __atomic_cas_i64 leaves cell + reports 0" as *u8) 96 97 let r4: i64 = t4_faa_returns_prior() 98 if r4 != 0 { println("T4 faa FAIL" as *u8); return r4 } 99 println("T4 faa PASS __atomic_faa_i64 returns prior + adds delta" as *u8) 100 101 let r5: i64 = t5_fence_compiles_and_runs() 102 if r5 != 0 { println("T5 fence FAIL" as *u8); return r5 } 103 println("T5 fence PASS __atomic_fence at all 5 memory orders" as *u8) 104 105 let r6: i64 = t6_spinlock_via_cas() 106 if r6 != 0 { println("T6 spinlock FAIL" as *u8); return r6 } 107 println("T6 spinlock PASS CAS-based take/release discipline holds" as *u8) 108 109 println("" as *u8) 110 println("All atomic intrinsics emit real RV64A AMO + lr.d/sc.d (riscv) /" as *u8) 111 println("LOCK CMPXCHG / XADD (x86_64). Single-threaded today; SMP-ready bits." as *u8) 112 return 0 113}