code wiki / _hdl_build / nx_procchurn.nx

nx_procchurn.nx

buildroot/runtime/_hdl_build/nx_procchurn.nx

11273 B206 linesdepth 4pulls 4 transitivereach 0 importersview sourcekind tool
docsdependenciesstructsconstsfunctions

about

nx_procchurn.nx -- the PROCESS-CHURN axis the health plane never had (debt seq1317 / seq1318). WHY THIS EXISTS: 2026-07-30, nx_health said {overall:OK, degraded:0, down:0} with all 14 services UP while the NAS was forking 78.3 processes/sec sustained, burning 231 permil of an 8-core box in the KERNEL against 98 permil in userspace (a 2.36x kernel:user inversion) and taking 91718 context switches/sec. nx_resmon owns MEMORY, nx_netobs owns NETWORK -- the process-churn axis had NO organ, so the largest CPU consumer on the platform was invisible to every instrument we owned and was found by hand. This is that instrument. LAW: liveness is not performance. A board that only asks "is it up" cannot see the machine burning. WHAT IT MEASURES (two /proc/stat samples bracketing a real window -- deltas, never since-boot totals, because a since-boot average hides a storm that started an hour ago): forks/sec -- `processes` delta. THE headline: fork+exec is the most expensive thing a kernel does. ctxsw/sec -- `ctxt` delta. Rises with churn AND with thrash; corroborates, never diagnoses alone. intr/sec -- `intr` delta, first field. Device pressure, reported for context (not thresholded). kernel:user -- system:user+nice jiffies as permil. 1000 = parity. THE inversion detector. busy/idle -- share of measured capacity, self-normalising (no HZ and no core count needed -- every share is a fraction of the SAME jiffy total, so the arithmetic cannot drift when the box changes size. That is what makes this instrument hardware-portable). Policy lives in nx_procchurn_lib.nx so the gate exercises the SAME code (rule 9 + rule 15); thresholds are data-driven from knowledge/status/procchurn.conf (rule 11). Read-only. No hw writes (Rule 26). Exit code IS the verdict so a caller can gate on it: 0=GREEN 1=AMBER 2=RED 3=UNMEASURED. license_tier: ORIGINAL expect_exit: 0

dependencies 1 imports · 0 importers

nx_procchurn_lib.nx nx_procchurn.nx

imports: nx_procchurn_lib.nx

imported by: nobody (leaf or entry point)

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main rm_conf rm_field rm_slen sys_now_us sys_mmap sys_clock_gettime_mono pc_scalar pc_line_ints rm_slen ↻ pc_line_ints ↻ sys_sleep_ms sys_mmap ↻ sys_munmap pc_rate pc_ratio_permil pc_verdict pc_frame pc_cat pc_catn sys_munmap ↻ sys_now_realtime_sec sys_mmap ↻ sys_clock_gettime_real pc_jappend sys_openat_append

structs

none

consts

27const PC_STATBUF: i64 = 8192
28const PC_CONFBUF: i64 = 4096
29const PC_FIELD_BYTES: i64 = 256
30const PC_NCPU_FIELDS: i64 = 10
31const PC_DEF_WINDOW_MS: i64 = 3000
32const PC_MIN_WINDOW_MS: i64 = 1000
33const PC_MAX_WINDOW_MS: i64 = 10000
34const PC_US_PER_MS: i64 = 1000
35const PC_DEF_F_AMBER: i64 = 20
36const PC_DEF_F_RED: i64 = 50
37const PC_DEF_R_AMBER: i64 = 1000
38const PC_DEF_R_RED: i64 = 1500
39const PC_DEF_C_AMBER: i64 = 20000
40const PC_DEF_C_RED: i64 = 50000
41const PC_EXIT_UNMEASURED: i64 = 3
42const PC_JBUF: i64 = 512
43const PC_MODE_644: i64 = 420

functions

49func pc_jappend(path: *u8, buf: *u8, n: i64) -> i64
called by 1: main calls 1: sys_openat_append
58func pc_scalar(buf: *u8, n: i64, key: *u8, out: *i64) -> i64
called by 1: main calls 1: pc_line_ints
64func main() -> i64