code wiki / (root) / nx_heavyio_lib.nx

nx_heavyio_lib.nx source

↩ module page · 375 lines · 19788 B

1// nx_heavyio_lib.nx -- THE HEAVY-I/O CONCURRENCY BOUND, in the PRIMITIVE layer (runtime/) so every bulk-I/O 2// producer can reach it (the seq1450 layering rule: primitives may not import the organ layer). 3// 4// WHY (measured 2026-09-02): the estate's storm ruler nx_ioadmit_lib is an INSTANTANEOUS, PER-CALLER check. 5// The clock scheduler, nx_compare_regen's fork burst, seg-compact, a daemon restart and a seat-launched job 6// EACH read "not stormed" at their own instant and all proceed -- and the storm is their SUM, which none of 7// them individually caused (a TOCTOU / thundering-herd gap). Operator: "this is not sota or best of breed 8// coordination and discipline for hub spoke resource management". A bound must count what is RUNNING across 9// every surface, not what was true at one caller's instant. 10// 11// IT COMPOSES THE TWO INCUMBENTS, NEVER A THIRD RULER: nx_poolgov.pg_width derives K from THIS box (hw budget, 12// PROPORTIONAL squeeze above the load ceiling, fail-safe to wmin) and pg_count_procs counts the running heavy 13// class across every surface; nx_ioadmit_lib.ioa_spawn_budget stays as the storm witness, a SECOND conjunct. 14// Data (rule 11): knowledge/heavyio.conf -- 15// producer <proc-name-needle> one row per heavy-I/O producer (the class this bound governs) 16// slots_per_cpu <n> floor <n> max_centi <n> wmin <n> wmax <n> size the width (reasoning in the conf) 17// hio_decide() is PURE and gate-driven; hio_admit() is the thin /proc wrapper. Three states, never a guess: 18// HIO_ADMIT 1 | HIO_DEFER 0 | HIO_UNOBSERVABLE (-1): conf or /proc unreadable. THE CALLER OWNS THE 19// UNOBSERVABLE POLICY and must NAME it: a periodic beat announces and proceeds (a missing conf must never 20// silence the estate's publishers -- the clock's own ioadmit dispatch check still guards the storm); an 21// interactive spawner may refuse. 22// license_tier: ORIGINAL Read-only. No hw writes (Rule 26). lib (no main) 23import "nx_syscalls.nx" 24import "nx_poolgov.nx" 25import "nx_ioadmit_lib.nx" 26import "nx_lease_lib.nx" // the K-slot POOL is K atomic leases (2026-09-03): acquisition is CAS, never read-then-act 27 28const HIO_CONF: *u8 = "knowledge/heavyio.conf" 29const HIO_ADMIT: i64 = 1 30const HIO_DEFER: i64 = 0 31const HIO_UNOBSERVABLE: i64 = 0 - 1 32const HIO_MAXP: i64 = 32 // producer rows the conf may carry; the reader announces when it fills 33const HIO_NAMEW: i64 = 64 // one producer needle slot (comm names are 15 bytes; cmdline needles longer) 34const HIO_CONFCAP: i64 = 65536 35const HIO_SPACE: i64 = 32 36const HIO_NL: i64 = 10 37const HIO_HASH: i64 = 35 38// cfg[] layout (i64 slots) 39const HIO_C_NPROD: i64 = 0 40const HIO_C_SLOTS: i64 = 1 41const HIO_C_FLOOR: i64 = 2 42const HIO_C_MAXC: i64 = 3 43const HIO_C_WMIN: i64 = 4 44const HIO_C_WMAX: i64 = 5 45const HIO_C_FILLED: i64 = 6 // 1 when HIO_MAXP was reached (rows beyond it were NOT read -- announced) 46const HIO_C_TTL: i64 = 7 // slot_ttl <sec>: crash guard for a HUNG-BUT-ALIVE holder (a dead one frees at once) 47const HIO_C_SLOTS_N: i64 = 8 48const HIO_C_BYTES: i64 = 64 // HIO_C_SLOTS_N * 8 49// out[] layout for hio_admit: 0 running 1 width 2 storm_budget 3 slot (-1 none). Adopters allocate HIO_C_BYTES (64), 50// which covers all four; HIO_OUT_BYTES names the minimum for new callers. 51const HIO_O_RUNNING: i64 = 0 52const HIO_O_WIDTH: i64 = 1 53const HIO_O_STORM: i64 = 2 54const HIO_O_SLOT: i64 = 3 55const HIO_OUT_BYTES: i64 = 32 56// THE POOL ROOT IS RESOLVED, NEVER ASSUMED (measured 2026-09-03: nx_compare_regen chdirs to buildroot, where 57// knowledge/heavyio.conf is ABSENT, so its admission read UNOBSERVABLE and it ran unbounded while the census said 58// ADOPTED). Probe the conf at knowledge/ then ../knowledge/; the lease dir follows the SAME root, so every CWD 59// shares ONE pool. hio_root returns 1 = knowledge/ 2 = ../knowledge/ 0 = neither (UNOBSERVABLE). 60const HIO_ROOT_A: *u8 = "knowledge/" 61const HIO_ROOT_B: *u8 = "../knowledge/" 62const HIO_CONF_LEAF: *u8 = "heavyio.conf" 63const HIO_LEASE_LEAF: *u8 = "lease/" 64const HIO_SLOT_PFX: *u8 = "heavyio-slot-" 65const HIO_OWNER_PFX: *u8 = "pid" 66const HIO_PROC_PFX: *u8 = "/proc/" 67const HIO_PROC_LEAF: *u8 = "/stat" 68const HIO_PATHCAP: i64 = 256 69const HIO_TTL_DEFAULT: i64 = 900 // used ONLY when the conf carries no slot_ttl row; the conf explains 900 70const HIO_POOL_NONE: i64 = 0 - 1 // every slot held by a LIVE holder -> DEFER 71const HIO_POOL_IO: i64 = 0 - 2 // every slot attempt failed with io (lease root unwritable) -> UNOBSERVABLE, never a stall 72 73func hio_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 74func hio_cat(d: *u8, o: i64, s: *u8) -> i64 { var i: i64 = 0; var p: i64 = o; while s[i] != (0 as u8) { d[p] = s[i]; p = p + 1; i = i + 1 } return p } 75func hio_catn(d: *u8, o: i64, v: i64) -> i64 { let t: *u8 = sys_mmap(28); var m: i64 = v; var p: i64 = o; if m < 0 { d[p] = 45 as u8; p = p + 1; m = 0 - m } 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 } var i: i64 = 0; while i < k { d[p] = t[k-1-i]; p = p + 1; i = i + 1 } return p } 76func hio_eol(q: *u8, i: i64, n: i64) -> i64 { var e: i64 = i; var s: i64 = 1; while s == 1 { if e >= n { s = 0 } else { if q[e] == (HIO_NL as u8) { s = 0 } else { e = e + 1 } } } return e } 77func hio_keyis(q: *u8, s: i64, e: i64, key: *u8) -> i64 { 78 var i: i64 = 0 79 while key[i] != (0 as u8) { if s + i >= e { return 0 } if q[s + i] != key[i] { return 0 } i = i + 1 } 80 if s + i >= e { return 0 } 81 if q[s + i] != (HIO_SPACE as u8) { return 0 } 82 return 1 83} 84func hio_atoi(q: *u8, s: i64, e: i64) -> i64 { 85 var v: i64 = 0; var i: i64 = s; var seen: i64 = 0 86 while i < e { let c: i64 = q[i] as i64; if c >= 48 { if c <= 57 { v = v * 10 + (c - 48); seen = 1; i = i + 1 } else { i = e } } else { i = e } } 87 if seen == 0 { return 0 - 1 } 88 return v 89} 90func hio_slot(names: *u8, i: i64) -> *u8 { return ((names as i64) + i * HIO_NAMEW) as *u8 } 91 92// Read the conf. cfg: HIO_C_SLOTS_N i64 slots; names: HIO_MAXP * HIO_NAMEW bytes. Returns 1, or 0 when the 93// conf is absent/unreadable/empty (the caller reports UNOBSERVABLE). Keys absent from the file read -1 so a 94// half-written conf cannot silently size the pool with a zero. 95func hio_conf_read(path: *u8, cfg: *i64, names: *u8) -> i64 { 96 var k: i64 = 0 97 while k < HIO_C_SLOTS_N { cfg[k] = 0 - 1; k = k + 1 } 98 cfg[HIO_C_NPROD] = 0 99 cfg[HIO_C_FILLED] = 0 100 let fd: i64 = sys_openat_rd(path) 101 if fd < 0 { return 0 } 102 let buf: *u8 = sys_mmap(HIO_CONFCAP) 103 var n: i64 = 0 104 var go: i64 = 1 105 while go == 1 { let r: i64 = sys_read(fd, ((buf as i64) + n) as *u8, HIO_CONFCAP - n); if r <= 0 { go = 0 } else { n = n + r } if n >= HIO_CONFCAP { go = 0 } } 106 sys_close(fd) 107 if n <= 0 { return 0 } 108 var i: i64 = 0 109 while i < n { 110 let le: i64 = hio_eol(buf, i, n) 111 if le > i { if (buf[i] as i64) != HIO_HASH { 112 if hio_keyis(buf, i, le, "producer" as *u8) == 1 { 113 let np: i64 = cfg[HIO_C_NPROD] 114 if np < HIO_MAXP { 115 let d: *u8 = hio_slot(names, np) 116 var p: i64 = i + 9 117 var w: i64 = 0 118 while p < le { if buf[p] == (HIO_SPACE as u8) { p = le } else { if w < HIO_NAMEW - 1 { d[w] = buf[p]; w = w + 1 } p = p + 1 } } 119 d[w] = 0 as u8 120 if w > 0 { cfg[HIO_C_NPROD] = np + 1 } 121 } else { cfg[HIO_C_FILLED] = 1 } 122 } 123 if hio_keyis(buf, i, le, "slots_per_cpu" as *u8) == 1 { cfg[HIO_C_SLOTS] = hio_atoi(buf, i + 14, le) } 124 if hio_keyis(buf, i, le, "floor" as *u8) == 1 { cfg[HIO_C_FLOOR] = hio_atoi(buf, i + 6, le) } 125 if hio_keyis(buf, i, le, "max_centi" as *u8) == 1 { cfg[HIO_C_MAXC] = hio_atoi(buf, i + 10, le) } 126 if hio_keyis(buf, i, le, "wmin" as *u8) == 1 { cfg[HIO_C_WMIN] = hio_atoi(buf, i + 5, le) } 127 if hio_keyis(buf, i, le, "wmax" as *u8) == 1 { cfg[HIO_C_WMAX] = hio_atoi(buf, i + 5, le) } 128 if hio_keyis(buf, i, le, "slot_ttl" as *u8) == 1 { cfg[HIO_C_TTL] = hio_atoi(buf, i + 9, le) } 129 } } 130 i = le + 1 131 } 132 return 1 133} 134 135// PURE: the decision, gate-driven. running = heavy producers observed running (INCLUDING the caller, which is 136// itself one of them); width = the derived K; storm_budget = ioa_spawn_budget (0 = the D-state line is reached). 137// Any negative input is an unobservable sensor and yields UNOBSERVABLE -- not knowing is never a verdict. 138func hio_decide(running: i64, width: i64, storm_budget: i64) -> i64 { 139 if running < 0 { return HIO_UNOBSERVABLE } 140 if width < 0 { return HIO_UNOBSERVABLE } 141 if storm_budget < 0 { return HIO_UNOBSERVABLE } 142 if storm_budget == 0 { return HIO_DEFER } 143 if running > width { return HIO_DEFER } 144 return HIO_ADMIT 145} 146 147// The derived K for this box, from the conf: pg_width(hw budget, 1 estate-wide instance, live load, ceiling, wmin, wmax). 148func hio_width(cfg: *i64) -> i64 { 149 if cfg[HIO_C_SLOTS] < 0 { return 0 - 1 } 150 if cfg[HIO_C_FLOOR] < 0 { return 0 - 1 } 151 if cfg[HIO_C_MAXC] < 0 { return 0 - 1 } 152 if cfg[HIO_C_WMIN] < 0 { return 0 - 1 } 153 if cfg[HIO_C_WMAX] < 0 { return 0 - 1 } 154 let budget: i64 = pg_budget_from_hw(cfg[HIO_C_SLOTS], cfg[HIO_C_FLOOR]) 155 return pg_width(budget, 1, pg_load_centi(), cfg[HIO_C_MAXC], cfg[HIO_C_WMIN], cfg[HIO_C_WMAX]) 156} 157 158// How many heavy producers are running RIGHT NOW across every launch surface (sum over the conf's class). 159// COUNTED WITH ioa_count_comm, NOT pg_count_procs -- MEASURED 2026-09-03 by this lib's own gate: pg_count_procs 160// ends `if cnt < 1 { return 1 }` because its contract is "instances INCLUDING at least myself" for a per-instance 161// pool (its one adopter, nx_torrent_get, IS an instance). Summed over a class that floor-of-1 yields one phantom 162// per needle (two fixture needles nothing ran read running=2). ioa_count_comm returns the TRUE count (0 when 163// none, -1 only when /proc is unreadable) on the kernel's 15-byte comm, and it is the same ruler the torrent 164// daemon's spawn admission already uses. ★READ THE COUNTER'S CONTRACT BEFORE SUMMING IT. 165func hio_running(cfg: *i64, names: *u8) -> i64 { 166 let np: i64 = cfg[HIO_C_NPROD] 167 if np <= 0 { return 0 - 1 } 168 var total: i64 = 0 169 var i: i64 = 0 170 while i < np { let c: i64 = ioa_count_comm(hio_slot(names, i)); if c < 0 { return 0 - 1 } total = total + c; i = i + 1 } 171 return total 172} 173 174// The storm witness as the second conjunct: the SAME ruler the build gate and the clock use. 175func hio_storm_budget() -> i64 { 176 let m: *i64 = sys_mmap(16) as *i64 177 if ioa_measure(m) != 0 { return 0 - 1 } 178 return ioa_spawn_budget(m[0], m[1], IOA_BLOCKED_PER_CPU, IOA_RESERVE_SLOTS) 179} 180 181// The thin wrapper a producer calls at ENTRY, before its bulk I/O. out[0]=running out[1]=width out[2]=storm_budget 182// so the caller can ANNOUNCE its numbers (a verdict without its figures is not actionable). 183// ---- THE K-SLOT POOL (2026-09-03): the TOCTOU fix. hio_decide above compares a COUNT read at one instant; N callers 184// can each read "under width" and all proceed. A slot is ACQUIRED atomically (nx_lease_lib: mkdir + CAS-verified 185// stamp), so at most K holders exist BY CONSTRUCTION regardless of check timing. The storm witness stays the FIRST 186// conjunct (never take a slot on a stormed box). A DEAD holder is reclaimed at once by pid-liveness (the stamp nonce 187// carries the pid); a HUNG-BUT-ALIVE holder frees after slot_ttl. No adopter has to release at exit -- but may. 188// Stated imprecision: a pid reused within slot_ttl by an unrelated live process keeps a dead holder's slot until 189// the ttl expires (bounded by the ttl, never unbounded). 190func hio_pid_alive(pid: i64) -> i64 { 191 if pid <= 0 { return 0 } 192 let p: *u8 = sys_mmap(HIO_PATHCAP) 193 var o: i64 = hio_cat(p, 0, HIO_PROC_PFX) 194 o = hio_catn(p, o, pid) 195 o = hio_cat(p, o, HIO_PROC_LEAF) 196 p[o] = 0 as u8 197 let fd: i64 = sys_openat_rd(p) 198 if fd < 0 { return 0 } 199 sys_close(fd) 200 return 1 201} 202// the pid encoded in an owner string of OUR shape (pid<n>); 0 for any other owner (never reclaimed by liveness, ttl only) 203func hio_owner_pid(owner: *u8) -> i64 { 204 if owner[0] != (112 as u8) { return 0 } 205 if owner[1] != (105 as u8) { return 0 } 206 if owner[2] != (100 as u8) { return 0 } 207 var v: i64 = 0 208 var i: i64 = 3 209 var seen: i64 = 0 210 while owner[i] != (0 as u8) { 211 let c: i64 = owner[i] as i64 212 if c < 48 { return 0 } 213 if c > 57 { return 0 } 214 v = v * 10 + (c - 48) 215 seen = 1 216 i = i + 1 217 } 218 if seen == 0 { return 0 } 219 return v 220} 221func hio_owner(out: *u8) -> i64 { 222 var o: i64 = hio_cat(out, 0, HIO_OWNER_PFX) 223 o = hio_catn(out, o, ls_pid()) 224 out[o] = 0 as u8 225 return o 226} 227func hio_slot_name(i: i64, out: *u8) -> i64 { 228 var o: i64 = hio_cat(out, 0, HIO_SLOT_PFX) 229 o = hio_catn(out, o, i) 230 out[o] = 0 as u8 231 return o 232} 233// resolve the root by probing the conf; fills root and returns 1 (knowledge/) | 2 (../knowledge/) | 0 (neither) 234func hio_root(root: *u8) -> i64 { 235 let p: *u8 = sys_mmap(HIO_PATHCAP) 236 var o: i64 = hio_cat(p, 0, HIO_ROOT_A) 237 o = hio_cat(p, o, HIO_CONF_LEAF) 238 p[o] = 0 as u8 239 var fd: i64 = sys_openat_rd(p) 240 if fd >= 0 { sys_close(fd); let ra: i64 = hio_cat(root, 0, HIO_ROOT_A); root[ra] = 0 as u8; return 1 } 241 o = hio_cat(p, 0, HIO_ROOT_B) 242 o = hio_cat(p, o, HIO_CONF_LEAF) 243 p[o] = 0 as u8 244 fd = sys_openat_rd(p) 245 if fd >= 0 { sys_close(fd); let rb: i64 = hio_cat(root, 0, HIO_ROOT_B); root[rb] = 0 as u8; return 2 } 246 root[0] = 0 as u8 247 return 0 248} 249func hio_lease_root(root: *u8, out: *u8) -> i64 { 250 var o: i64 = hio_cat(out, 0, root) 251 o = hio_cat(out, o, HIO_LEASE_LEAF) 252 out[o] = 0 as u8 253 return o 254} 255// try slots 0..width-1 under lroot; returns the slot index HELD, or -1 when every slot is held by a LIVE holder. 256// A slot whose holder pid is dead is released on the dead holder's behalf (owner string read from its stamp) and retaken. 257func hio_pool_acquire(lroot: *u8, width: i64, ttl: i64) -> i64 { 258 if width <= 0 { return HIO_POOL_NONE } 259 // The lease primitive FAILS TOWARD NOT HOLDING on io (its claim folds EEXIST and io into "lost", by design), so a 260 // pool cannot learn "unobservable" through acquire. Probe the root ITSELF: mkdir it, then open it -- a root that 261 // cannot be opened is a pool that cannot be seen, and that is UNOBSERVABLE, never "every slot held". 262 ls_mkdir(lroot) 263 let rfd: i64 = sys_openat_rd(lroot) 264 if rfd < 0 { return HIO_POOL_IO } 265 sys_close(rfd) 266 let owner: *u8 = sys_mmap(HIO_PATHCAP) 267 hio_owner(owner) 268 let name: *u8 = sys_mmap(HIO_PATHCAP) 269 let hb: *u8 = sys_mmap(HIO_PATHCAP) 270 var i: i64 = 0 271 while i < width { 272 hio_slot_name(i, name) 273 var r: i64 = ls_acquire_root(lroot, name, owner, ttl, hb) 274 if r == 0 { return i } 275 if r == 1 { 276 // hb carries the holder OWNER (ls_acquire_root fills it on busy); our owners are pid<n> by construction 277 let hp: i64 = hio_owner_pid(hb) 278 if hp > 0 { if hio_pid_alive(hp) == 0 { 279 ls_release_root(lroot, name, hb) 280 r = ls_acquire_root(lroot, name, owner, ttl, hb) 281 if r == 0 { return i } 282 } } 283 } 284 i = i + 1 285 } 286 return HIO_POOL_NONE 287} 288func hio_pool_release(lroot: *u8, slot: i64) -> i64 { 289 if slot < 0 { return 1 } 290 let owner: *u8 = sys_mmap(HIO_PATHCAP) 291 hio_owner(owner) 292 let name: *u8 = sys_mmap(HIO_PATHCAP) 293 hio_slot_name(slot, name) 294 return ls_release_root(lroot, name, owner) 295} 296// PURE: the pool decision, gate-driven. storm first (never take a slot on a stormed box), then the slot. A negative 297// width or storm is an unobservable sensor; slot -1 with a positive width = every slot held = DEFER. 298func hio_decide_pool(width: i64, storm_budget: i64, slot: i64) -> i64 { 299 if width < 0 { return HIO_UNOBSERVABLE } 300 if storm_budget < 0 { return HIO_UNOBSERVABLE } 301 if storm_budget == 0 { return HIO_DEFER } 302 if slot == HIO_POOL_IO { return HIO_UNOBSERVABLE } 303 if slot < 0 { return HIO_DEFER } 304 return HIO_ADMIT 305} 306// The thin wrapper a producer calls at ENTRY. out: running / width / storm_budget / slot. On ADMIT the caller HOLDS 307// slot out[3] for its lifetime (freed by exit through pid-liveness, or early via hio_release). hio_admit_conf keeps 308// its path argument for the gate's fixtures (root = the path's own dir is the caller's job); hio_admit resolves the root. 309func hio_admit_conf_root(root: *u8, path: *u8, out: *i64) -> i64 { 310 let cfg: *i64 = sys_mmap(HIO_C_BYTES) as *i64 311 let names: *u8 = sys_mmap(HIO_MAXP * HIO_NAMEW) 312 out[HIO_O_RUNNING] = 0 - 1; out[HIO_O_WIDTH] = 0 - 1; out[HIO_O_STORM] = 0 - 1; out[HIO_O_SLOT] = 0 - 1 313 if hio_conf_read(path, cfg, names) == 0 { return HIO_UNOBSERVABLE } 314 out[HIO_O_RUNNING] = hio_running(cfg, names) 315 out[HIO_O_WIDTH] = hio_width(cfg) 316 out[HIO_O_STORM] = hio_storm_budget() 317 if out[HIO_O_WIDTH] < 0 { return HIO_UNOBSERVABLE } 318 if out[HIO_O_STORM] < 0 { return HIO_UNOBSERVABLE } 319 if out[HIO_O_STORM] == 0 { return HIO_DEFER } 320 var ttl: i64 = cfg[HIO_C_TTL] 321 if ttl < 0 { ttl = HIO_TTL_DEFAULT } 322 let lroot: *u8 = sys_mmap(HIO_PATHCAP) 323 hio_lease_root(root, lroot) 324 out[HIO_O_SLOT] = hio_pool_acquire(lroot, out[HIO_O_WIDTH], ttl) 325 return hio_decide_pool(out[HIO_O_WIDTH], out[HIO_O_STORM], out[HIO_O_SLOT]) 326} 327func hio_admit_conf(path: *u8, out: *i64) -> i64 { return hio_admit_conf_root(HIO_ROOT_A, path, out) } 328func hio_admit(out: *i64) -> i64 { 329 let root: *u8 = sys_mmap(HIO_PATHCAP) 330 if hio_root(root) == 0 { 331 out[HIO_O_RUNNING] = 0 - 1; out[HIO_O_WIDTH] = 0 - 1; out[HIO_O_STORM] = 0 - 1; out[HIO_O_SLOT] = 0 - 1 332 return HIO_UNOBSERVABLE 333 } 334 let path: *u8 = sys_mmap(HIO_PATHCAP) 335 var o: i64 = hio_cat(path, 0, root) 336 o = hio_cat(path, o, HIO_CONF_LEAF) 337 path[o] = 0 as u8 338 return hio_admit_conf_root(root, path, out) 339} 340// early release for adopters that want the slot back before exit (optional: exit frees it by pid-liveness) 341func hio_release(out: *i64) -> i64 { 342 let root: *u8 = sys_mmap(HIO_PATHCAP) 343 if hio_root(root) == 0 { return 1 } 344 let lroot: *u8 = sys_mmap(HIO_PATHCAP) 345 hio_lease_root(root, lroot) 346 let r: i64 = hio_pool_release(lroot, out[HIO_O_SLOT]) 347 out[HIO_O_SLOT] = 0 - 1 348 return r 349} 350 351// Announce line for the caller: HEAVYIO running=N width=K storm_budget=S verdict=ADMIT|DEFER|UNOBSERVABLE 352func hio_announce(fd: i64, verdict: i64, out: *i64) -> i64 { 353 let b: *u8 = sys_mmap(256) 354 var o: i64 = 0 355 o = hio_cat(b, o, "HEAVYIO running=" as *u8); o = hio_catn(b, o, out[0]) 356 o = hio_cat(b, o, " width=" as *u8); o = hio_catn(b, o, out[1]) 357 o = hio_cat(b, o, " storm_budget=" as *u8); o = hio_catn(b, o, out[2]) 358 o = hio_cat(b, o, " slot=" as *u8); o = hio_catn(b, o, out[3]) 359 o = hio_cat(b, o, " verdict=" as *u8) 360 if verdict == HIO_ADMIT { o = hio_cat(b, o, "ADMIT" as *u8) } 361 if verdict == HIO_DEFER { o = hio_cat(b, o, "DEFER" as *u8) } 362 if verdict == HIO_UNOBSERVABLE { o = hio_cat(b, o, "UNOBSERVABLE" as *u8) } 363 o = hio_cat(b, o, "\n" as *u8) 364 sys_write(fd, b, o) 365 return 0 366} 367 368// RATCHET arithmetic for the adoption tooth (PURE): the floor only rises. Returns the floor to WRITE, or -1 369// when the observed count is BELOW the floor (a regression -- the gate goes RED and the baseline is NOT rewritten). 370func hio_ratchet_next(floor: i64, adopters: i64) -> i64 { 371 if adopters < 0 { return 0 - 1 } 372 if floor < 0 { return adopters } 373 if adopters < floor { return 0 - 1 } 374 return adopters 375}