code wiki / _hdl_build / nx_clock_sched.nx

nx_clock_sched.nx

buildroot/runtime/_hdl_build/nx_clock_sched.nx

32476 B567 linesdepth 5pulls 6 transitivereach 9 importersview sourcekind librarytopic clock
docsdependenciesstructsconstsfunctions

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

nx_syscalls.nx nx_store_seed_lib.nx nx_clock_sched.nx _clksched_probe.nx nx_clock_dispatch_gate.nx nx_clock_edf_gate.nx nx_clock_gate.nx nx_clock_run.nx nx_clock_status.nx nx_clock_status_gate.nx nx_clock_tickless.nx nx_clock_tickless_gate.nx

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

16const CLK_MAGIC_1000000: i64 = 1000000
18const CLK_MAXJOBS: i64 = 128
19const CLK_NAMEW: i64 = 128 // bytes per name/organ slot. WAS 48 (2026-08-03, debt 1784413227):
25const CLK_ROWW: i64 = 320 // per-row serialization budget (2 slots + 2 numbers + tabs)
26const CLK_REG: *u8 = "knowledge/sched/jobs.tsv" // RETIRED LEGACY PATH (2026-08-03, debt 1785792856):
392const CLK_EPOCH_FLOOR: i64 = 1000000000

functions

30func clk_slot(names: *u8, i: i64) -> *u8 { return ((names as i64) + i*CLK_NAMEW) as *u8 }
31func 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 }
called by 2: mainclk_find
33func 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 }
37func clk_register(names: *u8, organs: *u8, intervals: *i64, next_due: *i64, np: *i64, name: *u8, organ: *u8, interval: i64) -> i64
called by 2: mainmain calls 2: clk_findclk_slot
54func clk_tick(intervals: *i64, next_due: *i64, n: i64, now: i64, fired: *i64) -> i64
called by 1: main
71func clk_dispatch_run(organs: *u8, intervals: *i64, next_due: *i64, n: i64, now: i64, fired: *i64) -> i64
103func clk_run_tickless(organs: *u8, intervals: *i64, next_due: *i64, n: i64, start_tick: i64, maxbeats: i64, tick_ms: i64, out: *i64) -> i64
called by 1: main calls 2: sys_mmapclk_dispatch_run
126func clk_due_in(next_due_i: i64, now: i64) -> i64 { return next_due_i - now }
called by 2: mainmain
127func clk_twin_ok(organ: *u8) -> i64 { let fd: i64 = sys_openat_rd(organ); if fd < 0 { return 0 } sys_close(fd); return 1 }
called by 2: mainmain calls 2: sys_openat_rdsys_close
129func 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 }
called by 2: clk_saveclk_save_plane calls 1: sys_mmap
132func clk_save(path: *u8, names: *u8, organs: *u8, intervals: *i64, next_due: *i64, n: i64) -> i64
232func clk_load_plane(prefix: *u8, names: *u8, organs: *u8, intervals: *i64, next_due: *i64, np: *i64) -> i64
271func clk_save_plane(prefix: *u8, names: *u8, organs: *u8, intervals: *i64, next_due: *i64, n: i64) -> i64
310func clk_load_state(prefix: *u8, legacy: *u8, names: *u8, organs: *u8, intervals: *i64, next_due: *i64, np: *i64) -> i64
called by 2: mainmain calls 2: clk_load_planeclk_load
322func clk_merge_store(prefix: *u8, names: *u8, organs: *u8, intervals: *i64, next_due: *i64, np: *i64, base_tick: i64) -> i64
396func clk_edf_pick(deadlines: *i64, n: i64, now: i64) -> i64
called by 2: mainclk_run_edf
411func clk_edf_next(deadlines: *i64, n: i64) -> i64
called by 1: clk_run_edf
421func clk_edf_missed(deadlines: *i64, intervals: *i64, i: i64, now: i64) -> i64
called by 2: mainclk_run_edf
430func clk_edf_rearm(deadlines: *i64, intervals: *i64, i: i64, now: i64) -> i64
called by 2: mainclk_run_edf
442func clk_edf_migrate(deadlines: *i64, intervals: *i64, n: i64, now: i64) -> i64
called by 2: mainmain
461func clk_run_edf(organs: *u8, intervals: *i64, deadlines: *i64, n: i64, maxdispatch: i64, budget_secs: i64, tick_ms: i64, out: *i64) -> i64
515func clk_dispatch_one(organs: *u8, i: i64) -> i64
534func clk_load(path: *u8, names: *u8, organs: *u8, intervals: *i64, next_due: *i64, np: *i64) -> i64