code wiki / (root) / nx_headroom.nx

nx_headroom.nx source

↩ module page · 211 lines · 9794 B

1// nx_headroom.nx -- S4 of the SRE program (seq1295, incident 2026-07-29): the SPAWN-TIME HEADROOM 2// GATE every background producer must consult before forking work. The outage proof: an 8-wide TLS 3// fork pool spooling to tmpfs on a memory-tight box (which had ALREADY refused a build on the 4// MemAvailable floor) co-produced a host-wide starvation + hard crash. /api/build has this gate 5// baked in; this organ EXTRACTS it as the shared, config-driven primitive so no producer derives 6// width from taste again (bounds-derived law). 7// nx_headroom width <cap> <child_cost_mb> [meminfo] [loadavg] [cpuinfo] 8// -> NX-HEADROOM ok width=<n> avail_mb= usable_mb= cores= load1_centi= (exit 0) 9// -> NX-HEADROOM REFUSED reason=mem_floor|load_ceiling ... (exit 5) 10// width = min(cap, cores/2, (MemAvailable-floor)/child_cost), floor 1 -- else REFUSED. 11// nx_headroom gate <need_mb> [meminfo] [loadavg] [cpuinfo] 12// -> ok (exit 0) iff need_mb fits above the floor AND load is under ceiling; else REFUSED exit 5. 13// Conf headroom.conf in CWD: floor_mb= loadceil_centi_per_core= (else derived defaults below). 14// Path override args exist so the GATE can prove exact math on fixture files -- real callers omit them. 15// Read-only; no hw writes (Rule 26). 16// license_tier: ORIGINAL expect_exit: 0 17import "nx_syscalls.nx" 18const H_MAGIC_1024: i64 = 1024 19const H_MAGIC_4096: i64 = 4096 20const H_MAGIC_4095: i64 = 4095 21 22const H_EXIT_USAGE: i64 = 2 23const H_EXIT_REFUSED: i64 = 5 24const H_READCAP: i64 = 131072 25const H_DEF_FLOOR_MB: i64 = 4096 // derived: control plane + page-cache reserve ~11% of the 36GB hub 26const H_DEF_LOADCEIL: i64 = 200 // 2.00 load per core: beyond that the box is already saturated 27 28func h_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 29func h_putn(v: i64) -> i64 { 30 if v == 0 { sys_write(1, "0" as *u8, 1); return 0 } 31 var m: i64 = v; if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m } 32 let d: *u8 = sys_mmap(24); var k: i64 = 0 33 while m > 0 { d[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 34 let o: *u8 = sys_mmap(24); var w: i64 = 0 35 while w < k { o[w] = d[k-1-w]; w = w + 1 } 36 sys_write(1, o, k) 37 sys_munmap(d, 24); sys_munmap(o, 24) 38 return 0 39} 40func h_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 41func h_streq(a: *u8, b: *u8) -> i64 { var i: i64 = 0; while a[i] != (0 as u8) { if a[i] != b[i] { return 0 } i = i + 1 } if b[i] != (0 as u8) { return 0 } return 1 } 42func h_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 } 43func h_read(path: *u8, buf: *u8, cap: i64) -> i64 { 44 let fd: i64 = sys_openat_rd(path) 45 if fd < 0 { return 0 - 1 } 46 var tot: i64 = 0 47 var n: i64 = sys_read(fd, buf, cap) 48 while n > 0 { tot = tot + n; if tot >= cap { n = 0 } else { n = sys_read(fd, (buf as i64 + tot) as *u8, cap - tot) } } 49 sys_close(fd) 50 return tot 51} 52// first integer after <key>, skipping spaces/tabs between key and digits (meminfo shape). -1 if absent. 53func h_num_after(buf: *u8, n: i64, key: *u8) -> i64 { 54 let kn: i64 = h_slen(key) 55 var i: i64 = 0 56 while i + kn <= n { 57 var j: i64 = 0 58 var ok: i64 = 1 59 while j < kn { if buf[i+j] != key[j] { ok = 0; j = kn } else { j = j + 1 } } 60 if ok == 1 { 61 var p: i64 = i + kn 62 var sk: i64 = 1 63 while sk == 1 { sk = 0; if p < n { if buf[p] == (32 as u8) { p = p + 1; sk = 1 } else { if buf[p] == (9 as u8) { p = p + 1; sk = 1 } } } } 64 var v: i64 = 0 65 var any: i64 = 0 66 var go: i64 = 1 67 while go == 1 { 68 go = 0 69 if p < n { 70 let c: i64 = buf[p] as i64 71 if c >= 48 { if c <= 57 { v = v * 10 + (c - 48); any = 1; p = p + 1; go = 1 } } 72 } 73 } 74 if any == 1 { return v } 75 return 0 - 1 76 } 77 i = i + 1 78 } 79 return 0 - 1 80} 81// parse leading "D.DD" of loadavg as centi-load (12.44 -> 1244). -1 on empty. 82func h_load_centi(buf: *u8, n: i64) -> i64 { 83 var v: i64 = 0 84 var any: i64 = 0 85 var i: i64 = 0 86 var go: i64 = 1 87 while go == 1 { 88 go = 0 89 if i < n { let c: i64 = buf[i] as i64; if c >= 48 { if c <= 57 { v = v * 10 + (c - 48); any = 1; i = i + 1; go = 1 } } } 90 } 91 if any == 0 { return 0 - 1 } 92 v = v * 100 93 if i < n { if buf[i] == (46 as u8) { 94 i = i + 1 95 var f: i64 = 0 96 var fd: i64 = 0 97 var go2: i64 = 1 98 while go2 == 1 { 99 go2 = 0 100 if i < n { if fd < 2 { let c2: i64 = buf[i] as i64; if c2 >= 48 { if c2 <= 57 { f = f * 10 + (c2 - 48); fd = fd + 1; i = i + 1; go2 = 1 } } } } 101 } 102 if fd == 1 { f = f * 10 } 103 v = v + f 104 } } 105 return v 106} 107// count lines beginning with "processor" (cpuinfo core count); floor 1 108func h_cores(buf: *u8, n: i64) -> i64 { 109 var k: i64 = 0 110 var i: i64 = 0 111 var bol: i64 = 1 112 while i < n { 113 if bol == 1 { 114 if i + 9 <= n { 115 var j: i64 = 0 116 var ok: i64 = 1 117 let key: *u8 = "processor" as *u8 118 while j < 9 { if buf[i+j] != key[j] { ok = 0; j = 9 } else { j = j + 1 } } 119 if ok == 1 { k = k + 1 } 120 } 121 } 122 if buf[i] == (10 as u8) { bol = 1 } else { bol = 0 } 123 i = i + 1 124 } 125 if k < 1 { return 1 } 126 return k 127} 128func h_refuse(reason: *u8, avail: i64, usable: i64, cores: i64, load: i64) -> i64 { 129 h_puts("NX-HEADROOM REFUSED reason=" as *u8); h_puts(reason) 130 h_puts(" avail_mb=" as *u8); h_putn(avail) 131 h_puts(" usable_mb=" as *u8); h_putn(usable) 132 h_puts(" cores=" as *u8); h_putn(cores) 133 h_puts(" load1_centi=" as *u8); h_putn(load) 134 h_puts(" (spawn NOTHING; shed or wait -- the floor exists because 2026-07-29 did)\n" as *u8) 135 return 0 136} 137func main(argc: i64, argv: *i64) -> i64 { 138 if argc < 3 { h_puts("usage: nx_headroom width <cap> <child_cost_mb> [meminfo] [loadavg] [cpuinfo] | gate <need_mb> [meminfo] [loadavg] [cpuinfo]\n" as *u8); return H_EXIT_USAGE } 139 let verb: *u8 = argv[1] as *u8 140 var mode: i64 = 0 - 1 141 var pbase: i64 = 0 142 if h_streq(verb, "width" as *u8) == 1 { mode = 0; pbase = 4 } 143 if h_streq(verb, "gate" as *u8) == 1 { mode = 1; pbase = 3 } 144 if mode < 0 { h_puts("usage: nx_headroom width <cap> <child_cost_mb> [...] | gate <need_mb> [...]\n" as *u8); return H_EXIT_USAGE } 145 if mode == 0 { if argc < 4 { h_puts("width needs <cap> <child_cost_mb>\n" as *u8); return H_EXIT_USAGE } } 146 var pm: *u8 = "/proc/meminfo" as *u8 147 var pl: *u8 = "/proc/loadavg" as *u8 148 var pc: *u8 = "/proc/cpuinfo" as *u8 149 if argc > pbase { pm = argv[pbase] as *u8 } 150 if argc > pbase + 1 { pl = argv[pbase+1] as *u8 } 151 if argc > pbase + 2 { pc = argv[pbase+2] as *u8 } 152 // conf-or-derived-default bounds 153 var floor_mb: i64 = H_DEF_FLOOR_MB 154 var loadceil: i64 = H_DEF_LOADCEIL 155 let cbuf: *u8 = sys_mmap(256) 156 let cn: i64 = h_read("headroom.conf" as *u8, cbuf, 255) 157 if cn > 0 { 158 let v1: i64 = h_num_after(cbuf, cn, "floor_mb=" as *u8) 159 if v1 > 0 { floor_mb = v1 } 160 let v2: i64 = h_num_after(cbuf, cn, "loadceil_centi_per_core=" as *u8) 161 if v2 > 0 { loadceil = v2 } 162 } 163 sys_munmap(cbuf, 256) 164 // measure 165 let mb: *u8 = sys_mmap(H_READCAP) 166 let mn: i64 = h_read(pm, mb, H_READCAP - 1) 167 if mn <= 0 { h_puts("NX-HEADROOM ERROR: cannot read meminfo\n" as *u8); return 1 } 168 let kb: i64 = h_num_after(mb, mn, "MemAvailable:" as *u8) 169 if kb < 0 { h_puts("NX-HEADROOM ERROR: no MemAvailable in meminfo\n" as *u8); return 1 } 170 let avail_mb: i64 = kb / H_MAGIC_1024 171 let lb: *u8 = sys_mmap(H_MAGIC_4096) 172 let ln: i64 = h_read(pl, lb, H_MAGIC_4095) 173 var load1: i64 = 0 174 if ln > 0 { let lv: i64 = h_load_centi(lb, ln); if lv >= 0 { load1 = lv } } 175 let cb: *u8 = sys_mmap(H_READCAP) 176 let cnn: i64 = h_read(pc, cb, H_READCAP - 1) 177 var cores: i64 = 1 178 if cnn > 0 { cores = h_cores(cb, cnn) } 179 let usable: i64 = avail_mb - floor_mb 180 // load ceiling first: a saturated box refuses regardless of free memory 181 if load1 > loadceil * cores { h_refuse("load_ceiling" as *u8, avail_mb, usable, cores, load1); return H_EXIT_REFUSED } 182 if mode == 1 { 183 let need: i64 = h_atoi(argv[2] as *u8) 184 if usable < need { h_refuse("mem_floor" as *u8, avail_mb, usable, cores, load1); return H_EXIT_REFUSED } 185 h_puts("NX-HEADROOM ok need_mb=" as *u8); h_putn(need) 186 h_puts(" avail_mb=" as *u8); h_putn(avail_mb) 187 h_puts(" usable_mb=" as *u8); h_putn(usable) 188 h_puts(" cores=" as *u8); h_putn(cores) 189 h_puts(" load1_centi=" as *u8); h_putn(load1) 190 h_puts("\n" as *u8) 191 return 0 192 } 193 let cap: i64 = h_atoi(argv[2] as *u8) 194 let cost: i64 = h_atoi(argv[3] as *u8) 195 if cap < 1 { h_puts("width needs cap >= 1\n" as *u8); return H_EXIT_USAGE } 196 if cost < 1 { h_puts("width needs child_cost_mb >= 1\n" as *u8); return H_EXIT_USAGE } 197 if usable < cost { h_refuse("mem_floor" as *u8, avail_mb, usable, cores, load1); return H_EXIT_REFUSED } 198 var w: i64 = usable / cost 199 var wb: i64 = cores / 2 200 if wb < 1 { wb = 1 } 201 if w > wb { w = wb } 202 if w > cap { w = cap } 203 if w < 1 { w = 1 } 204 h_puts("NX-HEADROOM ok width=" as *u8); h_putn(w) 205 h_puts(" avail_mb=" as *u8); h_putn(avail_mb) 206 h_puts(" usable_mb=" as *u8); h_putn(usable) 207 h_puts(" cores=" as *u8); h_putn(cores) 208 h_puts(" load1_centi=" as *u8); h_putn(load1) 209 h_puts("\n" as *u8) 210 return 0 211}