nx_hw.nx
buildroot/runtime/nx_hw.nx
about
nx_hw.nx -- runtime hardware probes (CPU count, cache line, page).
SOVEREIGN: every probe goes through a real syscall or CPUID-class
instruction. No /proc parsing, no libc sysconf. Same code paths
on RV64 + x86_64 because the syscalls are number-portable.
FOUNDATION for [[feedback-dynamic-hw-sizing-no-hardcoded-thread-counts]]:
every threading / parallel / pool / partition primitive in the
substrate must derive its sizing from THESE functions, not from
hardcoded literals.
Syscall numbers used:
123 = sched_getaffinity (rv64/asm-generic) -- cpu count. The
compiler's x86ctx_rv64_to_x86_64_syscall table translates
123 -> x86_64 204 (row added + blessed 2026-07-07).
HISTORY: the original constant 122 was WRONG twice over --
rv64 122 is sched_SETaffinity, and 122 was not in the swap
table so it passed through to x86_64 setfsgid, which
SUCCEEDS, leaves the mask all-zero, popcounts to 0, and
made this probe silently report 1 CPU forever (every
auto-sized pool ran single-threaded; caught by
nx_conv2d_mt_gate check 10, 2026-07-07, interim-fixed with
raw 204 pass-through, then made portable via the table
row the same day).
Cache-line probe is currently a sealed-enum default (64 B, the
near-universal value across x86 / ARM / RISC-V); CPUID-based
probing on x86 lands when we add an inline-asm intrinsic.
Page size is fixed at 4 KiB (Linux RV64 + x86_64 default).
Larger pages (2 MiB hugepages) handled by future nx_hugepage.nx.
dependencies 1 imports · 20 importers
diagram shows first 10 each side; +0 more imports, +10 more importers in the complete lists below.
imports: nx_syscalls.nx
imported by: _offc_la_repro.nxnx_chan_mpmc_test.nxnx_dot_simd_demo.nxnx_mutex_race_test.nxnx_parallel.nxnx_parallel_simd_reduce.nxnx_parallel_test.nxnx_pipeline.nxnx_pipeline_test.nxnx_poolgov.nxnx_poolwidth_lib.nxnx_pteam.nxnx_reader_squad_f32_gate.nxnx_sdfrender_mt_gate.nxnx_sum_bench_all.nxnx_ta_parallel_grad_gate.nxnx_task_graph_test.nxnx_thread_pool.nxnx_thread_pool_test.nxnx_thread_spawn_test.nx
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 39 | const NX_MAGIC_4096: i64 = 4096 |
| 41 | const NX_SYS_SCHED_GETAFFINITY: i64 = 123 |
| 46 | const NX_HW_CPUSET_BYTES: i64 = 128 |
| 47 | const NX_HW_CPUSET_BITS: i64 = 1024 |
| 102 | const NX_HW_BYTE_MASK: i64 = 255 |
| 103 | const NX_HW_CLFLUSH_UNIT: i64 = 8 |
functions
| 58 | func nx_hw_cpu_count() -> i64 called by 6: nx_hw_worker_countmainpg_budget_from_hwmainmainpw_budget_from_hw calls 2: sys_mmapsys_munmap |
| 105 | func nx_hw_cache_line_size() -> i64 called by 1: main |
| 117 | func nx_hw_logical_procs() -> i64 |
| 129 | func nx_hw_page_size() -> i64 called by 1: main |
| 137 | func nx_hw_worker_count() -> i64 |
| 143 | func main() -> i64 |