code wiki / (root) / nx_commitbench.nx

nx_commitbench.nx

buildroot/runtime/nx_commitbench.nx

7892 B184 linesdepth 3pulls 3 transitivereach 0 importersview sourcekind bench
docsdependenciesstructsconstsfunctions

about

nx_commitbench.nx -- IS ss_commit_deferred WORTH ADOPTING? MEASURE BEFORE MIGRATING. WHY. ss_commit fsyncs the segment AND the directory on every call, so a logical transaction that appends N rows pays N durability barriers. ss_commit_deferred exists to make that ONE barrier -- it has existed since 2026-08-01, and as of 2026-08-07 NOTHING CALLS IT (debt 1786111613). The obvious move is to go adopt it everywhere. The disciplined move is to find out what it buys first: an unmeasured migration across a shared store is a lot of risk for a number nobody has. ★CORRECTNESS IS MEASURED ALONGSIDE SPEED, NOT AFTER IT. Both arms are counted for surviving keys, because a faster arm that loses rows is not faster, it is broken -- and ss_commit_deferred's own header states the honest bound it trades: after it returns the data IS VISIBLE (segment written, manifest renamed), only DURABILITY ACROSS POWER LOSS is deferred to the caller's ss_sync_now. So the row counts MUST match; if they ever do not, the deferred path is not what it claims. ⚠WHAT THIS CANNOT MEASURE, STATED SO THE NUMBER IS NOT OVERSOLD: it cannot measure the crash window. Arm B is exposed between its last deferred commit and its ss_sync_now, and no benchmark on a running host can price that. The speed number is real; the risk it buys is a judgement call that belongs to whoever adopts it, per-caller. usage: nx_commitbench [n] default 40 commits per arm license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0

dependencies 2 imports · 0 importers

nx_seg_store.nx nx_syscalls.nx nx_commitbench.nx

imports: nx_seg_store.nxnx_syscalls.nx

imported by: nobody (leaf or entry point)

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main cb_atoi cb_w sys_write cb_n cb_w ↻ sys_mmap nxa_die sys_write ↻ sys_exit nxa_lock_take nxa_lock_addr sys_write ↻ nxa_lock_give nxa_lock_addr ↻ nxa_report_overrun sys_write ↻ nxa_dump_printable sys_write ↻ nxa_dump_sizes sys_write ↻ sys_write ↻ sys_mmap ↻ cb_arm cb_reset sys_mmap ↻ ss_cat ss_writefile sys_openat_wr sys_write ↻ sys_close sys_fsync sys_mmap ↻ sys_now_ms sys_mmap ↻ sys_clock_gettime_mono cb_key ss_cat ↻ ss_catn sys_mmap ↻

structs

none

consts

24const CB_DEFAULT_N: i64 = 40
25const CB_CAP: i64 = 4096
26const CB_KEYCAP: i64 = 64
27const CB_KIND_LIVE: i64 = 1
28const CB_ZERO: i64 = 48
29const CB_NINE: i64 = 57
30const CB_B10: i64 = 10
31const CB_ROUNDS: i64 = 5 // interleaved A/B rounds; the reported figure is their MEDIAN ratio

functions

33func cb_w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
called by 2: cb_nmain calls 1: sys_write
34func cb_n(v: i64) -> i64
called by 1: main calls 3: cb_wsys_mmapsys_write
44func cb_atoi(s: *u8) -> i64
called by 1: main
55func cb_key(out: *u8, i: i64) -> i64
called by 2: cb_armcb_survivors calls 2: ss_catss_catn
63func cb_reset(prefix: *u8) -> i64
called by 1: cb_arm calls 3: sys_mmapss_catss_writefile
75func cb_arm(prefix: *u8, n: i64, deferred: i64) -> i64
94func cb_survivors(prefix: *u8, n: i64) -> i64
called by 1: main calls 3: sys_mmapcb_keyss_get
108func main(argc: i64, argv: *i64) -> i64