code wiki / _hdl_build / nx_initlive_probe.nx
nx_initlive_probe.nx source
↩ module page · 39 lines · 2513 B
1// nx_initlive_probe.nx -- PROBE (cardinal rule 2): does REAL fork + wait4(WNOHANG) child-liveness work on this host?
2// (a) fork a child that exits code 7 -> parent polls wait4(pid,&st,WNOHANG) -> detects the reaped pid + exit code.
3// (b) fork a child that sleeps ~400ms -> wait4 WNOHANG returns 0 (ALIVE) while it sleeps -> reap with a blocking wait.
4// This is the primitive nx_init_live needs (detect death, distinguish alive-vs-dead). expect_exit: 0
5import "nx_syscalls.nx"
6import "nx_g_puts_lib.nx"
7
8func g_pn(v: i64) -> i64 { let b: *u8=sys_mmap(28); var x: i64=v; if x<0{b[0]=45;sys_write(1,b,1);x=0-x} if x==0{b[0]=48;sys_write(1,b,1);return 0} var d: i64=0; var y: i64=x; while y>0{d=d+1;y=y/10} var i: i64=d-1; y=x; while i>=0{b[i]=(48+(y%10)) as u8;y=y/10;i=i-1} sys_write(1,b,d); return 0 }
9func sleep_ms(ms: i64) -> i64 { sys_poll(0 as *u8, 0, ms); return 0 }
10
11func main() -> i64 {
12 g_puts("nx_initlive_probe (real fork + wait4 WNOHANG liveness?)\n" as *u8)
13 let st: *i64 = sys_mmap(16) as *i64
14
15 // (a) a child that exits immediately with code 7
16 let pid1: i64 = sys_fork()
17 if pid1 == 0 { sys_exit(7); return 0 }
18 var reaped: i64 = 0 - 1; var code: i64 = 0 - 1
19 var tries: i64 = 0
20 while tries < 100 {
21 st[0] = 0
22 let r: i64 = sys_wait4(pid1, st, WNOHANG)
23 if r == pid1 { reaped = r; code = wait_exit_code(st[0]); tries = 100 } else { sleep_ms(20); tries = tries + 1 }
24 }
25 g_puts(" (a) forked child pid="); g_pn(pid1); g_puts(" -> reaped="); g_pn(reaped); g_puts(" exit-code="); g_pn(code); g_puts(" (expect 7)\n" as *u8)
26
27 // (b) a child that sleeps ~400ms; wait4 WNOHANG must report ALIVE (0) at least once, then a blocking wait reaps it
28 let pid2: i64 = sys_fork()
29 if pid2 == 0 { sleep_ms(400); sys_exit(0); return 0 }
30 st[0] = 0
31 let alive: i64 = sys_wait4(pid2, st, WNOHANG) // child still sleeping -> 0 (no state change)
32 let rb: i64 = sys_wait4(pid2, st, 0) // blocking -> reaps when it exits
33 g_puts(" (b) sleeping child pid="); g_pn(pid2); g_puts(" -> wait4-WNOHANG(while alive)="); g_pn(alive); g_puts(" (expect 0) blocking-reap="); g_pn(rb); g_puts("\n" as *u8)
34
35 var ok: i64 = 0
36 if reaped == pid1 { if code == 7 { if alive == 0 { if rb == pid2 { ok = 1 } } } }
37 if ok == 1 { g_puts("verdict=GREEN (real fork + wait4 WNOHANG liveness WORKS: death detected w/ exit code, alive distinguished)\n" as *u8); sys_exit(0); return 0 }
38 g_puts("verdict=RED\n" as *u8); sys_exit(1); return 1
39}