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}