code wiki / _hdl_build / nx_resource_governor.nx

nx_resource_governor.nx source

↩ module page · 73 lines · 4708 B

1// nx_resource_governor.nx -- the POLITE resource governor: decides how many workers the team may run so it 2// never overwhelms the host, backing off under load and scaling up as resources free (operator: "an 3// intelligent begin setup for the team to pick up work without overwhelming this system or any system they 4// are on but to be polite... till the resources are available... living auto scaling"). Two modes: 5// POLITE (default) -- leave headroom, run low-priority (nice), back off when load is high. 6// CRASH_GATES (override) -- full throttle for a user-chosen task, ignore politeness. 7// Pure policy (host signals passed in by nx_sysload); load is in MILLI cores (load_avg x1000). license_tier: ORIGINAL 8 9import "nx_syscalls.nx" 10 11const RG_POLITE: i64 = 1 12const RG_CRASH_GATES: i64 = 2 13 14// worker budget. POLITE: spare capacity = (ncpu - reserve) - current_load, floored at 0, and 0 if load is 15// over the ceiling. CRASH_GATES: all cores. (HPA-style target-utilization headroom, the research-to-come tunes it.) 16func rg_worker_budget(mode: i64, ncpu: i64, load_milli: i64, reserve: i64, ceil_factor_milli: i64) -> i64 { 17 if mode == RG_CRASH_GATES { return ncpu } 18 let capacity: i64 = ncpu - reserve 19 if capacity <= 0 { return 0 } 20 if load_milli > ncpu * ceil_factor_milli { return 0 } // over the ceiling -> fully back off 21 let load_cores: i64 = load_milli / 1000 22 let headroom: i64 = capacity - load_cores 23 if headroom <= 0 { return 0 } 24 if headroom > capacity { return capacity } 25 return headroom 26} 27 28// should we PAUSE this beat entirely (be polite and wait)? polite + over the load ceiling. 29func rg_should_backoff(mode: i64, ncpu: i64, load_milli: i64, ceil_factor_milli: i64) -> i64 { 30 if mode == RG_CRASH_GATES { return 0 } 31 if load_milli > ncpu * ceil_factor_milli { return 1 } 32 return 0 33} 34 35// process priority: polite workers run nice (yield to foreground); crash-gates run normal. 36func rg_nice(mode: i64) -> i64 { if mode == RG_CRASH_GATES { return 0 } return 10 } 37 38// memory admission: don't start work if free memory is below the floor (avoid thrash/OOM on any host). 39func rg_memory_ok(free_mb: i64, floor_mb: i64) -> i64 { if free_mb >= floor_mb { return 1 } return 0 } 40 41// polite backoff sleep (ms) grows with how far over the ceiling we are -> AIMD-style gentle retreat. 42func rg_backoff_ms(mode: i64, ncpu: i64, load_milli: i64, ceil_factor_milli: i64, base_ms: i64) -> i64 { 43 if mode == RG_CRASH_GATES { return 0 } 44 let ceil: i64 = ncpu * ceil_factor_milli 45 if load_milli <= ceil { return 0 } 46 let over: i64 = load_milli - ceil 47 return base_ms + (over * base_ms / 1000) // additive increase proportional to overload 48} 49 50func rg_mode_label(mode: i64) -> *u8 { if mode == RG_CRASH_GATES { return "CRASH-GATES" as *u8 } return "POLITE" as *u8 } 51 52// ===== HOSTING-FIRST (the node is ALSO the live hosting platform; serving QoS is sacred) ============== 53// SERVE-FIRST: any active hosting connection -> the loop yields ENTIRELY this beat (latency for visitors 54// must never suffer for background work). The single strongest politeness rule on a hosting node. 55func rg_serve_first(active_conns: i64) -> i64 { if active_conns > 0 { return 1 } return 0 } 56// reserve MORE on a hosting node: leave HALF the cores for the web daemon + fork-per-conn handlers (min 1). 57func rg_hosting_reserve(ncpu: i64) -> i64 { let r: i64 = ncpu / 2; if r < 1 { return 1 } return r } 58// the hosting ceiling is tighter (back off at HALF a core/cpu, not 0.8) so the loop never crowds serving. 59func rg_hosting_ceil_milli() -> i64 { return 500 } 60 61// ===== HARDWARE-UNIVERSAL (operator: "everything from this laptop to a sensor to a super computer") =========== 62// rg_hosting_reserve reserves HALF the cores -- right for a multi-core hosting node, but it STARVES a 1-2 core 63// sensor (capacity = ncpu - reserve <= 0 -> budget 0). The governor is god-rooted = "any hardware substrate"; the 64// reserve must scale to the substrate CLASS so the SAME governor fits a sensor up to a supercomputer. 65func rg_hw_class_reserve(ncpu: i64) -> i64 { 66 if ncpu <= 2 { return 0 } // SENSOR / microcontroller / edge: use the whole chip (no hosting reserve) 67 if ncpu <= 64 { return ncpu/2 } // LAPTOP / server / hosting node: polite half 68 return ncpu/8 // SUPERCOMPUTER / many-core: use ~7/8, reserve a sliver 69} 70// the substrate-fitting budget: class-aware reserve so growth sizes itself from a 1-core sensor to a many-core super. 71func rg_hw_budget(mode: i64, ncpu: i64, load_milli: i64, ceil_factor_milli: i64) -> i64 { 72 return rg_worker_budget(mode, ncpu, load_milli, rg_hw_class_reserve(ncpu), ceil_factor_milli) 73}