code wiki / _hdl_build / nx_clock_sched.nx
nx_clock_sched.nx
buildroot/runtime/_hdl_build/nx_clock_sched.nx
about
nx_clock_sched.nx -- RENAMED FROM nx_clock.nx 2026-07-31 (lib-reconcile). PERMANENT FIX for a
two-libraries-one-name collision: runtime/nx_clock.nx is the TIMING library (nx_clock_monotonic_ns,
62 importers); THIS file is an unrelated tickless JOB SCHEDULER (clk_* registry + dispatcher) that
only shared the filename. nx_cc binds an import to the IMPORTER'S OWN DIRECTORY FIRST, so every
_hdl_build organ importing nx_clock.nx silently got the SCHEDULER -- _clk_probe.nx, whose whole
purpose is to prove nx_clock_monotonic_ns works, could not resolve it. The RENAME is the fix.
so we avoid issues ... dont have a million pulses and daemons"). Researched (knowledge/fetched/sched_*.raw:
clock-distribution = ONE oscillator -> a tree of DIVIDERS; PLL derives every frequency from ONE reference;
cron = ONE daemon reads ONE table of timed jobs; tickless = don't burn a constant tick when idle). The S-class
pattern is identical: ONE tick source + ONE durable JOB REGISTRY + ONE dispatcher. Every periodic capability
REGISTERS a job (name, interval-in-ticks) = a divider off the single clock -- it does NOT spin up its own
daemon/pulse loop. So N capabilities cost ONE loop, not N. This library is the registry + dispatcher; the single
tick source drives it (one external spark, like a crystal). license_tier: ORIGINAL
dependencies 2 imports · 9 importers
imports: nx_syscalls.nxnx_store_seed_lib.nx
imported by: _clksched_probe.nxnx_clock_dispatch_gate.nxnx_clock_edf_gate.nxnx_clock_gate.nxnx_clock_run.nxnx_clock_status.nxnx_clock_status_gate.nxnx_clock_tickless.nxnx_clock_tickless_gate.nx
structs
| none |
consts
| 16 | const CLK_MAGIC_1000000: i64 = 1000000 |
| 18 | const CLK_MAXJOBS: i64 = 128 |
| 19 | const CLK_NAMEW: i64 = 128 // bytes per name/organ slot. WAS 48 (2026-08-03, debt 1784413227): |
| 25 | const CLK_ROWW: i64 = 320 // per-row serialization budget (2 slots + 2 numbers + tabs) |
| 26 | const CLK_REG: *u8 = "knowledge/sched/jobs.tsv" // RETIRED LEGACY PATH (2026-08-03, debt 1785792856): |
| 392 | const CLK_EPOCH_FLOOR: i64 = 1000000000 |
functions
| 30 | func clk_slot(names: *u8, i: i64) -> *u8 { return ((names as i64) + i*CLK_NAMEW) as *u8 } |
| 31 | func clk_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 } |
| 33 | func clk_find(names: *u8, n: i64, name: *u8) -> i64 { var i: i64=0; while i<n { if clk_streq(clk_slot(names,i), name)==1 { return i } i=i+1 } return 0-1 } |
| 37 | func clk_register(names: *u8, organs: *u8, intervals: *i64, next_due: *i64, np: *i64, name: *u8, organ: *u8, interval: i64) -> i64 |
| 54 | func clk_tick(intervals: *i64, next_due: *i64, n: i64, now: i64, fired: *i64) -> i64 called by 1: main |
| 71 | func clk_dispatch_run(organs: *u8, intervals: *i64, next_due: *i64, n: i64, now: i64, fired: *i64) -> i64 |
| 103 | func clk_run_tickless(organs: *u8, intervals: *i64, next_due: *i64, n: i64, start_tick: i64, maxbeats: i64, tick_ms: i64, out: *i64) -> i64 |
| 126 | func clk_due_in(next_due_i: i64, now: i64) -> i64 { return next_due_i - now } |
| 127 | func clk_twin_ok(organ: *u8) -> i64 { let fd: i64 = sys_openat_rd(organ); if fd < 0 { return 0 } sys_close(fd); return 1 } |
| 129 | func clk_itoa(buf: *u8, o: i64, v: i64) -> i64 { var w: i64=o; var m: i64=v; if m==0{buf[w]=48 as u8;return w+1} if m<0{buf[w]=45 as u8;w=w+1;m=0-m} let t:*u8=sys_mmap(24); var k:i64=0; while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var j:i64=0; while j<k{buf[w]=t[k-1-j];w=w+1;j=j+1} return w } |
| 132 | func clk_save(path: *u8, names: *u8, organs: *u8, intervals: *i64, next_due: *i64, n: i64) -> i64 |
| 232 | func clk_load_plane(prefix: *u8, names: *u8, organs: *u8, intervals: *i64, next_due: *i64, np: *i64) -> i64 |
| 271 | func clk_save_plane(prefix: *u8, names: *u8, organs: *u8, intervals: *i64, next_due: *i64, n: i64) -> i64 |
| 310 | func clk_load_state(prefix: *u8, legacy: *u8, names: *u8, organs: *u8, intervals: *i64, next_due: *i64, np: *i64) -> i64 |
| 322 | func clk_merge_store(prefix: *u8, names: *u8, organs: *u8, intervals: *i64, next_due: *i64, np: *i64, base_tick: i64) -> i64 |
| 396 | func clk_edf_pick(deadlines: *i64, n: i64, now: i64) -> i64 |
| 411 | func clk_edf_next(deadlines: *i64, n: i64) -> i64 called by 1: clk_run_edf |
| 421 | func clk_edf_missed(deadlines: *i64, intervals: *i64, i: i64, now: i64) -> i64 |
| 430 | func clk_edf_rearm(deadlines: *i64, intervals: *i64, i: i64, now: i64) -> i64 |
| 442 | func clk_edf_migrate(deadlines: *i64, intervals: *i64, n: i64, now: i64) -> i64 |
| 461 | func clk_run_edf(organs: *u8, intervals: *i64, deadlines: *i64, n: i64, maxdispatch: i64, budget_secs: i64, tick_ms: i64, out: *i64) -> i64 called by 1: main calls 7: sys_mmapsys_now_realtime_secclk_edf_pickclk_edf_missedclk_edf_rearmclk_dispatch_one+1 |
| 515 | func clk_dispatch_one(organs: *u8, i: i64) -> i64 |
| 534 | func clk_load(path: *u8, names: *u8, organs: *u8, intervals: *i64, next_due: *i64, np: *i64) -> i64 |