code wiki / _hdl_build / nx_ecomat_put.nx

nx_ecomat_put.nx source

↩ module page · 102 lines · 5864 B

1// nx_ecomat_put.nx -- store-native autoid domain adder for the ecomat maturity plane (acl F771). 2// Adds ONE domain to the seg-store at the next CONTIGUOUS id, atomically under flock. ss_commit REPLACES 3// the store with the write-set (gate-proven), so this RELOADS every existing domain + adds the new one + 4// commits the whole set (load-all/write-all, like nx_frontier_put). Kills the two-edit-surface seeder 5// clobber (no seeder-source edit). No hw writes (Rule 26). Gate: nx_ecomat_put_gate 3/3 on a throwaway. 6// nx_ecomat_put addauto <axis> <layer> <cur> <bar> <weight> <domain> <bench> <nextrung> [evlog] [evpat] [prefix] 7// exit: 0 ok (ECOMAT-PUT id=N) | 2 usage | 1 fail-closed. 8// license_tier: ORIGINAL expect_exit: 0 9import "nx_ecomat_lib.nx" 10import "nx_seg_store.nx" 11import "nx_syscalls.nx" 12const EP_MAGIC_1024: i64 = 1024 13 14const EP_STDERR: i64 = 2 15const EP_MODE: i64 = 420 16const EP_LOCK_EX: i64 = 2 17 18func ep_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 19func ep_werr(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(EP_STDERR, s, n); return 0 } 20func ep_vlen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 21func ep_atoi(s: *u8) -> i64 { var v: i64 = 0; var i: i64 = 0; while s[i] != (0 as u8) { let c: i64 = s[i] as i64; if c >= 48 { if c <= 57 { v = v * 10 + (c - 48) } } i = i + 1 } return v } 22func ep_catn(fd: i64, v: i64) -> i64 { var m: i64 = v; if m < 0 { m = 0 } let t: *u8 = sys_mmap(28); 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 } let o: *u8 = sys_mmap(28); var i: i64 = 0; while i < k { o[i] = t[k-1-i]; i = i + 1 } sys_write(fd, o, k); return 0 } 23func ep_lock(prefix: *u8) -> i64 { 24 let p: *u8 = sys_mmap(256) 25 var o: i64 = 0 26 var i: i64 = 0 27 while prefix[i] != (0 as u8) { p[o] = prefix[i]; o = o + 1; i = i + 1 } 28 let s: *u8 = "plock" as *u8 29 var j: i64 = 0 30 while s[j] != (0 as u8) { p[o] = s[j]; o = o + 1; j = j + 1 } 31 p[o] = 0 as u8 32 let fd: i64 = sys_openat_append(p, EP_MODE) 33 if fd < 0 { return 0 - 1 } 34 sys_flock(fd, EP_LOCK_EX) 35 return fd 36} 37func main(argc: i64, argv: *i64) -> i64 { 38 if argc < 10 { ep_werr("usage: nx_ecomat_put addauto <axis> <layer> <cur> <bar> <weight> <domain> <bench> <nextrung> [evlog] [evpat] [prefix]\n" as *u8); sys_exit(2); return 2 } 39 let verb: *u8 = argv[1] as *u8 40 if ep_vlen(verb) != 7 { ep_werr("PUT-FAIL only verb 'addauto' supported\n" as *u8); sys_exit(2); return 2 } 41 let axis: i64 = ep_atoi(argv[2] as *u8) 42 let layer: i64 = ep_atoi(argv[3] as *u8) 43 let cur: i64 = ep_atoi(argv[4] as *u8) 44 let bar: i64 = ep_atoi(argv[5] as *u8) 45 let weight: i64 = ep_atoi(argv[6] as *u8) 46 let domain: *u8 = argv[7] as *u8 47 let bench: *u8 = argv[8] as *u8 48 let nextrung: *u8 = argv[9] as *u8 49 var evlog: *u8 = "" as *u8 50 var evpat: *u8 = "" as *u8 51 var prefix: *u8 = ECOMAT_STORE 52 if argc > 10 { evlog = argv[10] as *u8 } 53 if argc > 11 { evpat = argv[11] as *u8 } 54 if argc > 12 { prefix = argv[12] as *u8 } 55 var ev: i64 = 0 56 var evkind: i64 = 0 57 if ep_vlen(evlog) > 0 { ev = 1; evkind = 2 } 58 if axis < 0 { ep_werr("PUT-FAIL axis must be 0..2\n" as *u8); sys_exit(1); return 1 } 59 if axis > 2 { ep_werr("PUT-FAIL axis must be 0..2\n" as *u8); sys_exit(1); return 1 } 60 61 let lk: i64 = ep_lock(prefix) 62 if lk < 0 { ep_werr("PUT-FAIL cannot lock\n" as *u8); sys_exit(1); return 1 } 63 let h: *i64 = ss_open(prefix) 64 let w: *i64 = ss_begin() 65 var nextid: i64 = 0 66 if (h as i64) != 0 { 67 let pq: *i64 = sys_mmap(16) as *i64 68 let lq: *i64 = sys_mmap(16) as *i64 69 var go: i64 = 1 70 while go == 1 { 71 let key: *u8 = sys_mmap(64) 72 ec_key(nextid, key) 73 if ss_hget(h, key, pq, lq) == 1 { 74 if ss_add(w, 1, key, pq[0] as *u8, lq[0]) != 0 { ep_werr("PUT-FAIL writeset overflow on reload\n" as *u8); sys_exit(1); return 1 } 75 nextid = nextid + 1 76 } else { go = 0 } 77 } 78 } 79 // Size the buffer from the DATA (ec_reclen), never a fixed guess: a long domain/bench/next-rung 80 // row used to overrun a fixed 1024 and then get blamed on a bogus "record too large". 81 let cap: i64 = ec_reclen(domain, bench, nextrung, evlog, evpat, "" as *u8, "" as *u8) 82 let val: *u8 = sys_mmap(cap) 83 let vlen: i64 = ec_pack(val, cap, axis, layer, cur, bar, weight, ev, evkind, 0, domain, bench, nextrung, evlog, evpat, "" as *u8, "" as *u8) 84 if vlen < 0 { ep_werr("PUT-FAIL pack refused: derived buffer too small (ec_reclen disagrees with ec_pack)\n" as *u8); sys_exit(1); return 1 } 85 let key2: *u8 = sys_mmap(64) 86 ec_key(nextid, key2) 87 // ss_add2 fail-closes ONLY on cumulative write-set overflow vs the ss_begin buffer -- there is no 88 // per-record size check anywhere in the store. Say what actually happened; the old "record too 89 // large" text misdescribed the sole failure this call can report and misdirected diagnosis. 90 if ss_add(w, 1, key2, val, vlen) != 0 { ep_werr("PUT-FAIL write-set full: reloaded domains plus this record exceed the ss_begin buffer\n" as *u8); sys_exit(1); return 1 } 91 let cnt: i64 = ss_commit(prefix, w, sys_now_realtime_sec()) 92 if cnt < 0 { ep_werr("PUT-FAIL commit error\n" as *u8); sys_exit(1); return 1 } 93 ep_puts("ECOMAT-PUT id=" as *u8); ep_catn(1, nextid) 94 ep_puts(" domain=" as *u8); ep_puts(domain) 95 ep_puts(" axis=" as *u8); ep_catn(1, axis) 96 ep_puts(" cur=" as *u8); ep_catn(1, cur) 97 ep_puts(" bar=" as *u8); ep_catn(1, bar) 98 if ev == 1 { ep_puts(" ev=single-src" as *u8) } else { ep_puts(" ev=stored" as *u8) } 99 ep_puts(" (store-append RMW; seeder-clobber avoided)\n" as *u8) 100 sys_exit(0) 101 return 0 102}