code wiki / _hdl_build / nx_job_concurrent_gate_t182.nx
nx_job_concurrent_gate_t182.nx source
↩ module page · 61 lines · 3717 B
1import "nx_jobclaim_candidate_t182.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}