code wiki / _hdl_build / nx_team_out_lock_gate.nx
nx_team_out_lock_gate.nx
buildroot/runtime/_hdl_build/nx_team_out_lock_gate.nx
about
nx_team_out_lock_gate.nx -- REFEREE for the team_out.tsv concurrent-writer lock (WMS torn-write
follow-on). Proves an rt_lock-serialized WRITE SESSION keeps a MULTI-LINE record block contiguous
under concurrency, AND that the detector sees failure without the lock (mandatory neg-control).
WHY a lock, not fa_appendz: express_lane writes a MULTI-LINE block (ACK lines + the SITREP block);
per-line atomicity (fa_appendz) keeps each LINE intact but does NOT stop a second writer's lines
from interleaving BETWEEN this writer's lines -> the block is shredded. The fix (this gate proves)
is to hold rt_lock across the whole multi-line session so no other writer can slip a line in.
GOOD lane: NWORKERS fork; each acquires rt_lock(GOODLOCK), writes NRECS records (each = L lines,
each line emitted as a SEQUENCE of sys_write so it CAN tear), releases. Expect: ZERO
torn lines AND ZERO block-contiguity breaks AND all N*NRECS*L lines present.
BAD lane (NEG-CONTROL): identical, but NO lock -> concurrent workers interleave -> torn lines
AND/OR block breaks MUST appear. If bad has none, the detector is worthless -> RED.
A line is CLEAN iff it begins "BLK w=" AND the 4 bytes before '\n' are " END" AND exactly one
"BLK w=" head AND its w field == its z field (the two wid copies bracket the line; an interleave
splits them). A BLOCK BREAK = a clean line with s>0 whose immediately-preceding line is not the
same (w,r) at s-1 (the block's L lines were not contiguous). Per-run unique /tmp paths.
Self-log via the assembled single sys_write (fd is uncontended). GREEN(0) iff all hold.
Sovereign: nx_registry_lock (rt_lock/rt_unlock; nx_syscalls transitive). license_tier: ORIGINAL
dependencies 1 imports · 0 importers
imports: nx_registry_lock.nx
imported by: nobody (leaf or entry point)
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 24 | const NWORKERS: i64 = 16 |
| 25 | const NRECS: i64 = 60 |
| 26 | const LPB: i64 = 4 // lines per record block |
| 27 | const MAXLINES: i64 = 8192 // >= NWORKERS*NRECS*LPB (3840) with headroom |
functions
| 29 | func so(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 1: main |
| 30 | func son(v: i64) -> i64 called by 1: main |
| 39 | func tl_cat(dst: *u8, off: i64, s: *u8) -> i64 { var i: i64=0; while s[i]!=(0 as u8){dst[off+i]=s[i];i=i+1} return off+i } |
| 40 | func tl_catn(dst: *u8, off: i64, v: i64) -> i64 |
| 48 | func tl_path(out: *u8, tag: *u8, epoch: i64, suffix: *u8) -> i64 |
| 55 | func emit_line(fd: i64, wid: i64, r: i64, s: i64) -> i64 called by 1: worker |
| 90 | func worker(path: *u8, lockpath: *u8, wid: i64, locked: i64) -> i64 |
| 106 | func spawn_all(path: *u8, lockpath: *u8, locked: i64) -> i64 |
| 122 | func int_after(b: *u8, ls: i64, le: i64, tok: *u8, tlen: i64) -> i64 called by 1: scan |
| 140 | func head_count(b: *u8, ls: i64, le: i64) -> i64 called by 1: scan |
| 154 | func scan(path: *u8, wA: *i64, rA: *i64, sA: *i64, clA: *i64, outs: *i64) -> i64 |
| 222 | func main() -> i64 |