code wiki / (root) / nx_scratch.nx

nx_scratch.nx

buildroot/runtime/nx_scratch.nx

3365 B82 linesdepth 2pulls 2 transitivereach 1 importersview sourcekind librarytopic scratch
docsdependenciesstructsconstsfunctions

about

nx_scratch.nx -- SOVEREIGN SCRATCH ARENA. The god-level fix for the unfreed-mmap class. THE ROOT DEFECT, stated plainly: NishiLang has no scratch allocator. `sys_mmap` is a raw page-granular syscall with NO allocator and NO free behind it, so every organ that needs a temporary buffer hand-rolls `sys_mmap(N)` -- and every one of them re-derives the same bug. That is 455 occurrences across ~210 files. Fixing them one at a time is 455 chances to get it wrong; fixing the missing primitive is one chance to get it right, inherited by everything below. MEASURED cost of the status quo (nx_mmapleak_gate): an unpaired scratch mmap leaks a full 4096-byte page per call -- even sys_mmap(4) -- so 2000 calls grow a process by 4000 pages. In a supervised daemon that is unbounded: nx_seed_announce_all reached 8.8 GB committed and drove the build host into swap. MODEL: one process-lifetime arena, bump-allocated, reset at the top of each work iteration (per request, per sweep, per connection). Scratch is by definition dead at the end of an iteration, so a reset is the whole free. ★FAIL-SAFE BY CONSTRUCTION: on overflow nxs_alloc does NOT return null and does NOT truncate -- it falls back to exactly the sys_mmap the caller performed BEFORE adopting this library, and counts it. So adoption can never make a caller worse or introduce a null it does not check, and the arena gets sized from evidence (nxs_overflows) instead of guesswork. Refuse-and-report, never silently shrink. ⚠CONTRACT: memory returned by nxs_alloc is INVALID after the next nxs_reset(). Never hold it across an iteration boundary, and never use it for state that must outlive the request. license_tier: ORIGINAL layer: runtime-core module: nishi-core.runtime.scratch

dependencies 1 imports · 1 importers

nx_syscalls.nx nx_scratch.nx nx_scratch_gate.nx

imports: nx_syscalls.nx

imported by: nx_scratch_gate.nx

structs

none

consts

29const NXS_CAP_DEFAULT: i64 = 1048576
30const NXS_ALIGN: i64 = 16

functions

39func nxs_init(cap: i64) -> i64
called by 2: nxs_allocmain calls 1: sys_mmap
50func nxs_reset() -> i64
called by 1: main
56func nxs_alloc(n: i64) -> *u8
called by 2: nxs_alloc0main calls 2: nxs_initsys_mmap
72func nxs_alloc0(n: i64) -> *u8
calls 1: nxs_alloc
79func nxs_used() -> i64 { return NXS_OFF }
80func nxs_cap_bytes() -> i64 { return NXS_CAP }
called by 1: main
81func nxs_hwm() -> i64 { return NXS_HWM }
called by 1: main
82func nxs_overflows() -> i64 { return NXS_OVF }
called by 1: main