nx_clock_full.nx source
↩ module page · 74 lines · 2546 B
1// nx_clock.nx -- sovereign wall-clock + monotonic time primitive.
2//
3// Replaces Python's time.perf_counter_ns() in bench harnesses. Calls
4// the Linux clock_gettime syscall directly via __syscall.
5//
6// genealogy_id: posix_clock_gettime
7// lineage_id: function
8
9// nx_safety_envelope:
10// intended_use: AUTO_APPLIED -- primitive-specific tuning queued
11// sil_target: SIL1
12// evidence: [bulk_applied_2026-05-16, see-file-comment-for-detail]
13// verdict: NOT_YET_EVALUATED
14//
15// nx_capability_manifest:
16// variant_class: monotonic_clock
17// variant_id: monotonic_clock_linux_v1
18// requires_isa: [rv64imac, x86_64]
19// requires_syscalls: [clock_gettime]
20// requires_ram_min_b: 64
21// tier_floor: NX_TIER_MCU
22// tier_ceiling: NX_TIER_HPC
23// cost_model:
24// flops_per_n: 0.0
25// bytes_per_n: 16.0 // one NxTimespec (sec + nsec)
26// syscalls_per_n: 1.0 // one clock_gettime per call
27// adversary_class: THREAT_OPPORTUNISTIC
28
29import "syscalls.nx"
30
31// --- syscall + clock-id constants (no magic numbers in call sites) ---
32const NX_SYS_CLOCK_GETTIME: i64 = 113 // Linux RISC-V syscall number
33const NX_CLOCK_REALTIME: i64 = 0 // clock_gettime clockid: wall time
34const NX_CLOCK_MONOTONIC: i64 = 1 // clock_gettime clockid: since-boot
35
36// --- unit conversions (named, not literal) ---
37const NX_NS_PER_SEC: i64 = 1000000000 // 1e9 nanoseconds per second
38const NX_NS_PER_US: i64 = 1000 // 1e3 nanoseconds per microsecond
39const NX_NS_PER_MS: i64 = 1000000 // 1e6 nanoseconds per millisecond
40
41// --- timespec struct ---
42struct NxTimespec {
43 sec: i64,
44 nsec: i64,
45}
46
47// clock_gettime(clockid, *timespec): returns ns since epoch (REALTIME)
48// or ns since boot (MONOTONIC).
49func nx_clock_gettime(clock_id: i64) -> i64 {
50 let ts_raw: *u8 = sys_mmap(16)
51 let ts: *NxTimespec = ts_raw as *NxTimespec
52 ts.sec = 0
53 ts.nsec = 0
54 __syscall(NX_SYS_CLOCK_GETTIME, clock_id, ts_raw as i64, 0, 0, 0, 0)
55 return ts.sec * NX_NS_PER_SEC + ts.nsec
56}
57
58func nx_clock_realtime_ns() -> i64 {
59 return nx_clock_gettime(NX_CLOCK_REALTIME)
60}
61
62func nx_clock_monotonic_ns() -> i64 {
63 return nx_clock_gettime(NX_CLOCK_MONOTONIC)
64}
65
66func nx_clock_elapsed_us(start_ns: i64) -> i64 {
67 let now: i64 = nx_clock_monotonic_ns()
68 return (now - start_ns) / NX_NS_PER_US
69}
70
71func nx_clock_elapsed_ms(start_ns: i64) -> i64 {
72 let now: i64 = nx_clock_monotonic_ns()
73 return (now - start_ns) / NX_NS_PER_MS
74}