code wiki / (root) / nx_clock.nx

nx_clock.nx source

↩ module page · 38 lines · 2545 B

1// nx_clock.nx -- MONOTONIC CLOCK PRIMITIVE for the runtime layer. 2// 3// THE WOUND (found 2026-07-30): nx_clock_monotonic_ns() was CALLED by nx_loop.nx (its watchdog, lines 4// 219/237) and by 8+ other organs, and DEFINED NOWHERE IN THE TREE. Because nx_loop.nx is imported by 5// nx_bpe.nx, which is imported by the whole nx_gguf/nx_f32_llm family, that single missing function 6// darkened 174 organs: every one of them failed to compile, which is why nx_f32_llm_serve.elf had been 7// frozen at Jul 16 and the sovereign LLM capability was unreachable. 8// 9// It presented as -- a diagnostic naming no file, no symbol and 10// no line, which is why it survived so long. The real chain took a five-step bisect to reach: 11// probe imports nx_bpe -> FAILS | nx_f32 -> BUILDS (isolates nx_bpe) 12// nx_bpe's imports: nx_loop -> FAILS, others BUILD (isolates nx_loop) 13// nx_loop's own imports all BUILD (so it is nx_loop's CONTENT) 14// identical content builds in _hdl_build/, fails in runtime/ (so it is RESOLUTION, not syntax) 15// -> runtime/nx_loop.nx imports nx_clock.nx, which existed ONLY in _hdl_build/ 16// ★LAW CONFIRMED THE HARD WAY: runtime/ CANNOT import _hdl_build/. A layering violation does not fail 17// at the violating file -- it fails at every transitive dependent, with a message that names none of them. 18// 19// ⚠TWO MODULES, ONE NAME: _hdl_build/nx_clock.nx is a SCHEDULER (clk_tick/clk_dispatch_run/clk_register). 20// This is NOT that module and must not be confused with it -- resolving the import to the scheduler made 21// imports expand and then failed differently, which is how the real missing symbol finally got named. 22// 23// license_tier: ORIGINAL No hw writes (Rule 26). 24import "nx_syscalls.nx" 25 26// derived: struct timespec is { tv_sec: i64, tv_nsec: i64 } on x86-64; CLOCK_MONOTONIC = 1, applied by 27// sys_clock_gettime_mono. 1e9 ns per second is the ABI's unit, not a tunable. 28const NXCLK_NS_PER_S: i64 = 1000000000 29 30// Monotonic nanoseconds since an unspecified epoch. NEVER goes backwards and is unaffected by wall-clock 31// adjustment, which is exactly why watchdogs and benchmarks must use this and not realtime. 32// Returns 0 - 1 if the syscall fails, so a caller can tell 'no clock' from 'time zero' -- an error that 33// silently reads as 0 would make every elapsed-time computation look instantaneous. 34func nx_clock_monotonic_ns() -> i64 { 35 let ts: *i64 = sys_mmap(16) as *i64 36 if sys_clock_gettime_mono(ts) != 0 { return 0 - 1 } 37 return ts[0] * NXCLK_NS_PER_S + ts[1] 38}