code wiki / _hdl_build / nx_job_concurrent_canonical_gate_t182.nx

nx_job_concurrent_canonical_gate_t182.nx source

↩ module page · 61 lines · 3706 B

1import "nx_jobclaim_lib.nx" 2import "nx_gate_verdict.nx" 3import "nx_tool_exec_allow.nx" 4func jc_write(path:*u8,data:*u8,n:i64)->i64{ 5 let fd:i64=sys_openat_exclusive(path,MODE_0644);if fd<0{return fd} 6 let w:i64=sys_write(fd,data,n);let rc:i64=sys_close(fd) 7 if w!=n{return JR_ERR_IO};return rc 8} 9func jc_child(dir:*u8,first:i64,label:*u8,idpath:*u8,rfd:i64,wfd:i64)->i64{ 10 sys_close(wfd);let start:*u8=sys_mmap(1);if sys_read(rfd,start,1)!=1{return 3};sys_close(rfd) 11 let path:*u8=sys_mmap(JR_PATH);let line:*u8=sys_mmap(JR_LINE);let info:*i64=sys_mmap(32) as *i64 12 let id:i64=jr_reserve(dir,first,sys_now_ms()+tea_reply_reserve_ms(),path,JR_PATH,line,JR_LINE,info) 13 if id<=0{return 4} 14 if jr_mkpath(path,JR_PATH,dir,id,JR_EXT_OUT)<0{return 5} 15 if jc_write(path,label,jr_slen(label))!=0{return 6} 16 let n:i64=jr_catnum(line,0,id) 17 if jc_write(idpath,line,n)!=0{return 7} 18 return 0 19} 20func main()->i64{ 21 let c:*i64=gv_ctr();gv_head("Concurrent reservation and FIFO occupancy") 22 let dir:*u8=sys_mmap(JR_PATH);let d:i64=jr_catnum(dir,jr_cat(dir,0,"/tmp/nishi-job-concurrent-t182-"),sys_now_ms());dir[d]=0 23 if sys_mkdir(dir,MODE_0755)!=0{return 3} 24 let p:*u8=sys_mmap(JR_PATH);let line:*u8=sys_mmap(JR_LINE);let info:*i64=sys_mmap(32) as *i64 25 let first:i64=sys_now_realtime_sec() 26 jr_mkpath(p,JR_PATH,dir,first,JR_EXT_OUT) 27 // Same verified Linux x86-64 FIFO fixture syscall as nx_mcp_body_gate. 28 if __syscall(259,AT_FDCWD,p,4516,0,0,0)!=0{return 3} 29 let start:i64=sys_now_ms();let id:i64=jr_reserve(dir,first,start+tea_reply_reserve_ms(),p,JR_PATH,line,JR_LINE,info) 30 gv_check("FIFO output treated occupied without blocking",id==first+1 && info[3]==1,c) 31 gv_check("FIFO lookup completes inside existing budget",sys_now_ms()-start<tea_reply_reserve_ms(),c) 32 let a:*u8=sys_mmap(JR_PATH);let an:i64=jr_cat(a,jr_cat(a,0,dir),"/a.id");a[an]=0 33 let b:*u8=sys_mmap(JR_PATH);let bn:i64=jr_cat(b,jr_cat(b,0,dir),"/b.id");b[bn]=0 34 let fds:*i64=sys_mmap(16) as *i64;if sys_pipe2(fds,0)!=0{return 3} 35 let rfd:i64=fds[0]&4294967295;let wfd:i64=(fds[0]/4294967296)&4294967295 36 let pa:i64=sys_fork() 37 if pa==0{sys_exit_group(jc_child(dir,first+10,"worker-A",a,rfd,wfd));return 8} 38 if pa<0{return 3} 39 let pb:i64=sys_fork() 40 if pb==0{sys_exit_group(jc_child(dir,first+10,"worker-B",b,rfd,wfd));return 8} 41 if pb<0{return 3} 42 sys_close(rfd);if sys_write(wfd,"go",2)!=2{return 3};sys_close(wfd) 43 let st:*i64=sys_mmap(16) as *i64 44 sys_wait4(pa,st,0);let ar:i64=wait_status_rc(st[0]) 45 sys_wait4(pb,st,0);let br:i64=wait_status_rc(st[0]) 46 gv_check("both competing processes reserve successfully",ar==0 && br==0,c) 47 let sz:*i64=sys_mmap(16) as *i64 48 let ab:*u8=sys_read_file(a,sz);if (ab as i64)==0{return 3};let ai:i64=jr_atoi_strict(ab) 49 let bb:*u8=sys_read_file(b,sz);if (bb as i64)==0{return 3};let bi:i64=jr_atoi_strict(bb) 50 gv_check("same-first-ID contenders receive distinct IDs",ai>0 && bi>0 && ai!=bi,c) 51 jr_mkpath(p,JR_PATH,dir,ai,JR_EXT_CLAIM);let ac:*u8=sys_read_file(p,sz) 52 gv_check("A has its own claim",jr_state_of(ac,sz[0])==JR_ST_CLAIMED,c) 53 jr_mkpath(p,JR_PATH,dir,bi,JR_EXT_CLAIM);let bc:*u8=sys_read_file(p,sz) 54 gv_check("B has its own claim",jr_state_of(bc,sz[0])==JR_ST_CLAIMED,c) 55 jr_mkpath(p,JR_PATH,dir,ai,JR_EXT_OUT);let ao:*u8=sys_read_file(p,sz) 56 gv_check("A output retains A identity",sz[0]==8 && jr_has(ao,sz[0],"worker-A")==1,c) 57 jr_mkpath(p,JR_PATH,dir,bi,JR_EXT_OUT);let bo:*u8=sys_read_file(p,sz) 58 gv_check("B output retains B identity",sz[0]==8 && jr_has(bo,sz[0],"worker-B")==1,c) 59 gv_puts("first=");gv_num(first+10);gv_puts(" A=");gv_num(ai);gv_puts(" B=");gv_num(bi);gv_puts("\n") 60 return gv_verdict("job-concurrent-ownership",c,"Two native processes, isolated FIFO and files; no live stress") 61}