code wiki / _hdl_build / nx_apistack_bulkhead_gate.nx
nx_apistack_bulkhead_gate.nx source
↩ module page · 40 lines · 2705 B
1// nx_apistack_bulkhead_gate.nx -- hermetic gate for CAP-API-BULKHEAD. Proves the concurrency cap: acquire up to max,
2// reject at max, release frees a slot, never below zero. expect_exit: 0
3import "nx_syscalls.nx"
4import "nx_apistack_bulkhead.nx"
5import "nx_gate_verdict.nx"
6
7func gp(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
8func gn(v: i64) -> i64 { var t: i64=v; if t<0{sys_write(1,"-" as *u8,1);t=0-t} let tm:*u8=sys_mmap(24); var k:i64=0; if t==0{tm[0]=48 as u8;k=1} while t>0{tm[k]=(48+(t%10)) as u8;t=t/10;k=k+1} let b:*u8=sys_mmap(24); var j:i64=0; while j<k{b[j]=tm[k-1-j];j=j+1} sys_write(1,b,k); return 0 }
9
10func main(argc: i64, argv: *i64) -> i64 {
11 gp("=== nx_apistack_bulkhead_gate (concurrency isolation) ===\n" as *u8)
12 let bh: *i64 = sys_mmap(16) as *i64 // bh[0]=0
13 var pass: i64 = 0; var fail: i64 = 0
14
15 // T1 acquire up to max=3
16 let a1: i64 = bh_acquire(bh, 3); let a2: i64 = bh_acquire(bh, 3); let a3: i64 = bh_acquire(bh, 3)
17 if a1==1 { if a2==1 { if a3==1 { if bh[0]==3 { pass=pass+1; gp(" T1 acquire up to max=3 PASS\n" as *u8) } else { fail=fail+1; gp(" T1 FAIL active\n" as *u8) } } else { fail=fail+1; gp(" T1 FAIL a3\n" as *u8) } } else { fail=fail+1; gp(" T1 FAIL a2\n" as *u8) } } else { fail=fail+1; gp(" T1 FAIL a1\n" as *u8) }
18
19 // T2 at max -> reject
20 if bh_acquire(bh, 3) == 0 { pass=pass+1; gp(" T2 at max -> reject PASS\n" as *u8) } else { fail=fail+1; gp(" T2 FAIL admitted over max\n" as *u8) }
21
22 // T3 release frees a slot
23 bh_release(bh)
24 if bh[0]==2 { if bh_acquire(bh, 3) == 1 { pass=pass+1; gp(" T3 release frees a slot PASS\n" as *u8) } else { fail=fail+1; gp(" T3 FAIL no slot\n" as *u8) } } else { fail=fail+1; gp(" T3 FAIL active=" as *u8); gn(bh[0]); gp("\n" as *u8) }
25
26 // T4 never below zero
27 bh_release(bh); bh_release(bh); bh_release(bh); bh_release(bh)
28 if bh[0]==0 { pass=pass+1; gp(" T4 release never below zero PASS\n" as *u8) } else { fail=fail+1; gp(" T4 FAIL=" as *u8); gn(bh[0]); gp("\n" as *u8) }
29
30 gp("RESULT pass=" as *u8); gn(pass); gp(" fail=" as *u8); gn(fail)
31 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check
32 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled
33 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify.
34 let ctr__dry: *i64 = gv_ctr()
35 ctr__dry[0] = pass
36 ctr__dry[1] = pass + fail
37 let rc__dry: i64 = gv_verdict("APISTACK-BULKHEAD-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8)
38 sys_exit(rc__dry)
39 return rc__dry
40}