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}