code wiki / _hdl_build / nx_registry_lock.nx

nx_registry_lock.nx

buildroot/runtime/_hdl_build/nx_registry_lock.nx

4085 B81 linesdepth 2pulls 2 transitivereach 13 importersview sourcekind librarytopic registry
docsdependenciesstructsconstsfunctions

about

nx_registry_lock.nx -- the SHARED race-free lock PRIMITIVE, extracted (DRY, rule 15) from nx_registry_txn so every queue WRITER (reconcile / mark_migrate / express_lane + side-organs + the pulse/autorun daemons) can acquire ONE serializable, crash-safe, drvfs-portable lock around its read-modify-write of assignment_queue.tsv / row_markers.tsv. This is the hardware rung the operator asked for ("build the coordination from the hardware rung up so we can keep moving in parallel through daemons / orchestration"). PRIMITIVE: an O_CREAT|O_EXCL lockfile (the kernel guarantees exactly ONE creator wins -- no TOCTOU) stamped with the holder's acquire-epoch; a contender spin-serializes and STEALS a lock older than RT_STALE_SEC (a crashed holder, so the beat can never wedge). It deliberately does NOT use flock(2): flock is dead on /mnt/c drvfs AND the rv64->x86_64 syscall map (32->73) only activates on an nx_cc self-host redeploy (currently gated behind a RED cc_equiv run). O_EXCL needs neither -- it works today on drvfs with NO compiler redeploy. S-CLASS EXCEED over ad_acquire_lock (hard-fails on contention, no staleness recovery) and over atomic-rename-alone (saves a torn file but LOSES updates): this serializes contenders AND self-heals a crashed holder = serializable + crash-safe + drvfs-portable. MAINLESS LIBRARY: a consumer imports THIS file only (it pulls in nx_syscalls transitively) and must NOT also `import "nx_syscalls.nx"` directly -- the proven nx_assign_core<-nx_dep_audit convention, which dodges the double-import rc=6. Gate-proven (no separate gate authored) by nx_registry_txn's existing RTXN-GATE: fork 2 writers x N guarded increments -> lossless (==2N) while the unguarded control loses (<2N). license_tier: ORIGINAL module: nishi-core.autonomy.registry_lock depends: nishi-core.sys.syscalls capability: SHARED_REGISTRY_WRITE_LOCK_OEXCL

dependencies 1 imports · 13 importers

nx_syscalls.nx nx_registry_lock.nx _express_lane_gate_authored.nx nx_ale_gap_filer.nx nx_ecomat_beat.nx nx_ecomat_beat_gate.nx nx_ecomat_target_emit.nx nx_express_lane.nx nx_mark_migrate.nx nx_novel_close.nx nx_reader_coordinate.nx nx_reconcile.nx

diagram shows first 10 each side; +0 more imports, +3 more importers in the complete lists below.

imports: nx_syscalls.nx

imported by: _express_lane_gate_authored.nxnx_ale_gap_filer.nxnx_ecomat_beat.nxnx_ecomat_beat_gate.nxnx_ecomat_target_emit.nxnx_express_lane.nxnx_mark_migrate.nxnx_novel_close.nxnx_reader_coordinate.nxnx_reconcile.nxnx_registry_txn.nxnx_stackaudit_targets.nxnx_team_out_lock_gate.nx

structs

none

consts

29const RT_MAGIC_8000000: i64 = 8000000
30const RT_MAGIC_8192: i64 = 8192
32const RT_OEXCL: i64 = 193 // O_CREAT(0x40)|O_EXCL(0x80)|O_WRONLY(0x1)
33const RT_MODE: i64 = 420 // 0644
34const RT_STALE_SEC: i64 = 30 // steal a lockfile whose stamped epoch is older than this (crashed holder)

functions

36func rt_now() -> i64 { return sys_now_realtime_sec() }
called by 2: rt_lockmain calls 1: sys_now_realtime_sec
39func rt_writeint_fd(fd: i64, v: i64) -> i64
51func rt_readint(path: *u8) -> i64
65func rt_lock(lockpath: *u8) -> i64
81func rt_unlock(lockpath: *u8, fd: i64) -> i64 { sys_close(fd); rt_unlink(lockpath); return 0 }