code wiki / _hdl_build / nx_clock_dispatch_gate.nx

nx_clock_dispatch_gate.nx source

↩ module page · 50 lines · 3791 B

1// nx_clock_dispatch_gate.nx -- proves the clock is FUNCTIONAL: its ONE dispatcher actually RUNS a registered job's 2// organ (fork+exec) at the job's interval. Job A (interval 1, the marker organ) must run on every tick; job B 3// (interval 3) must run only when due. Over ticks 1..4: A runs 4x, B runs 1x -- proven by the marker file length 4// and the dispatch counts. This is the divider property realized as REAL execution, from ONE loop, no per-job 5// daemon. Pre-req: _build/nx_clock_marker.sov.elf must be built (run `nx_sov_build_run nx_clock_marker 6// --build-only` first; cwd = buildroot). ⚠THE FIXTURE MUST NOT LIVE IN /tmp: this NAS mounts /tmp 7// noexec (measured 2026-08-03: tmpfs rw,nosuid,nodev,noexec), so the old /tmp path made every 8// dispatch exec fail 127 and the gate was RED ON THIS HOST FROM BIRTH -- an environmentally-dead 9// gate that never once measured what it claims. license_tier: ORIGINAL expect_exit: 0 10import "nx_clock_sched.nx" 11import "nx_syscalls.nx" 12 13func w(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 14func wn(v: i64) -> i64 { var m: i64=v; if m<0{w("-" as *u8);m=0-m} let t:*u8=sys_mmap(24); var k:i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var i:i64=0; let o:*u8=sys_mmap(24); while i<k{o[i]=t[k-1-i];i=i+1} sys_write(1,o,k); return 0 } 15func dun(p: *u8) -> i64 { __syscall(87, p as i64, 0, 0, 0, 0, 0); return 0 } 16func readnum(p: *u8) -> i64 { let lp: *i64 = sys_mmap(8) as *i64; let d: *u8 = sys_read_file(p, lp); if (d as i64)==0 { return 0 } var c: i64=0; var i: i64=0; while i<lp[0] { if d[i]>=(48 as u8) { if d[i]<=(57 as u8) { c=c*10+(d[i]-(48 as u8)) as i64 } } i=i+1 } return c } 17func setslot(buf: *u8, i: i64, s: *u8) -> i64 { let d: *u8 = clk_slot(buf, i); var c: i64=0; while s[c]!=(0 as u8){ if c<CLK_NAMEW-1 { d[c]=s[c] } c=c+1 } d[c]=0 as u8; return 0 } 18 19func main(argc: i64, argv: *i64) -> i64 { 20 w("=== nx_clock_dispatch_gate -- ONE dispatcher actually RUNS due jobs (fork+exec) ===\n" as *u8) 21 let organs: *u8 = sys_mmap(CLK_MAXJOBS*CLK_NAMEW) 22 let iv: *i64 = sys_mmap(CLK_MAXJOBS*8) as *i64 23 let nd: *i64 = sys_mmap(CLK_MAXJOBS*8) as *i64 24 let fired: *i64 = sys_mmap(CLK_MAXJOBS*8) as *i64 25 26 // Job A: the marker organ, interval 1 (runs every tick). Job B: same organ, interval 3 (runs only when due). 27 setslot(organs, 0, "_build/nx_clock_marker.sov.elf" as *u8); iv[0]=1; nd[0]=1 28 setslot(organs, 1, "_build/nx_clock_marker.sov.elf" as *u8); iv[1]=3; nd[1]=3 29 let n: i64 = 2 30 dun("/tmp/clk_mark.txt" as *u8) 31 32 var total: i64 = 0 33 var now: i64 = 1 34 while now <= 4 { 35 let c: i64 = clk_dispatch_run(organs, iv, nd, n, now, fired) 36 total = total + c 37 now = now + 1 38 } 39 let runs: i64 = readnum("/tmp/clk_mark.txt" as *u8) 40 w(" dispatched (A int1 + B int3) over ticks 1..4: total dispatch="); wn(total); w(", organ actually ran="); wn(runs); w(" times\n" as *u8) 41 42 var pass: i64=0; var tot: i64=0 43 // A (int1) ran 4x + B (int3) ran 1x (tick 3) = 5 real organ executions from ONE dispatcher loop 44 tot=tot+1; if runs==5 { pass=pass+1; w(" PASS the clock RAN the registered organ exactly 5x (A:4 + B:1) = divider as REAL execution\n" as *u8) } else { w(" FAIL organ ran "); wn(runs); w(" times (expected 5)\n" as *u8) } 45 tot=tot+1; if total==5 { pass=pass+1; w(" PASS dispatch count matches (5), one loop drove both jobs\n" as *u8) } else { w(" FAIL dispatch count "); wn(total); w("\n" as *u8) } 46 47 w("nx_clock_dispatch_gate pass="); wn(pass); w("/"); wn(tot) 48 if pass==tot { w(" verdict=GREEN (the ONE clock executes real organs at their intervals -- no per-job daemon)\n" as *u8); sys_exit(0); return 0 } 49 w(" verdict=RED\n" as *u8); sys_exit(1); return 1 50}