nx_atom.nx
buildroot/runtime/nx_atom.nx
about
nx_atom.nx -- atomic primitives + memory ordering.
FOUNDATION LAYER. Every lock-free data structure, every SMP-safe
counter, every message queue in NishiOS sits on top of these
operations: load, store, CAS, FAA, and memory barriers.
Why now (DARPA-class concurrency correctness):
The current observability stack (nx_log, nx_trace, nx_metrics,
nx_arena, nx_ring, nx_id) is single-threaded-only. The moment
NishiOS ships its SMP scheduler, every one of those modules
either gains an atomic primitive or silently corrupts. Land
the primitive FIRST -- mechanical retrofit, not rescue.
seL4 / Nemesis lineage: concurrency correctness is the
second-highest cost in kernel verification (after memory
safety). seL4's proof rests on a uniprocessor model; the
multi-core extension (MCS seL4) required re-proving sizable
chunks around synchronisation primitives. Getting the atomic
memory model RIGHT AT THE SOURCE LANGUAGE LAYER pays that cost
once.
MEMORY ORDERING TAXONOMY (RV64A, C11 atomic_*, Rust atomic_*):
NX_MO_RELAXED No ordering. Counter bumps. Fastest.
NX_MO_CONSUME Data-dependent loads (C11 intent; rarely used).
NX_MO_ACQUIRE Load-acquire: no load/store after this op can
migrate BEFORE it. Standard lock acquire.
NX_MO_RELEASE Store-release: no load/store before this op
can migrate AFTER it. Standard lock release.
NX_MO_ACQ_REL Both -- used on RMW (read-modify-write) ops.
NX_MO_SEQ_CST Sequential consistency: single global order
across all seq-cst ops on the machine. Slowest.
Default for userland until profiling warrants
weaker ordering.
RV64A MAPPING (RISC-V A extension) -- emit targets when nxc2 grows
inline asm:
load-acquire lr.d / ld + fence r,rw (aq bit on lr.d)
dependencies 1 imports · 28 importers
diagram shows first 10 each side; +0 more imports, +18 more importers in the complete lists below.
imports: nx_syscalls.nx
imported by: nx_atom_kat.nxnx_chan.nxnx_chan_mpmc_test.nxnx_dot_simd_demo.nxnx_mutex.nxnx_mutex_race_test.nxnx_natfu_probe.nxnx_net_chan.nxnx_net_chan_blob_test.nxnx_net_chan_test.nxnx_parallel.nxnx_parallel_simd_reduce.nxnx_parallel_test.nxnx_pipeline.nxnx_pipeline_test.nxnx_pool_ring_gate.nxnx_pteam.nxnx_remote_worker.nxnx_remote_worker_test.nxnx_rpc.nxnx_rpc_test.nxnx_socket_pingpong_test.nxnx_sum_bench_all.nxnx_task_graph.nxnx_task_graph_test.nxnx_thread_pool.nxnx_thread_pool_test.nxnx_thread_spawn_test.nx
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 91 | const NX_MO_RELAXED: i64 = 0 |
| 92 | const NX_MO_CONSUME: i64 = 1 |
| 93 | const NX_MO_ACQUIRE: i64 = 2 |
| 94 | const NX_MO_RELEASE: i64 = 3 |
| 95 | const NX_MO_ACQ_REL: i64 = 4 |
| 96 | const NX_MO_SEQ_CST: i64 = 5 |
functions
| 103 | func nx_atom_load_i64(addr: *i64, mo: i64) -> i64 |
| 109 | func nx_atom_store_i64(addr: *i64, val: i64, mo: i64) -> i64 |
| 117 | func nx_atom_cas_i64(addr: *i64, expected: i64, new_val: i64, mo: i64) -> i64 |
| 123 | func nx_atom_faa_i64(addr: *i64, delta: i64, mo: i64) -> i64 |
| 130 | func nx_atom_fence(mo: i64) -> i64 |
| 138 | func nx_atom_inc_i64(addr: *i64) -> i64 |
| 144 | func nx_atom_dec_i64(addr: *i64) -> i64 |
| 150 | func nx_atom_try_lock_i64(addr: *i64) -> i64 |
| 155 | func nx_atom_unlock_i64(addr: *i64) -> i64 |
| 162 | func main() -> i64 |