nx_mutex.nx
buildroot/runtime/nx_mutex.nx
about
nx_mutex.nx -- futex-based mutex (FUTEX_WAIT / FUTEX_WAKE).
Companion to nx_atom (atomic primitives). When SMP arrives,
mutual exclusion needs more than a spinlock -- spinning under
contention burns CPU and starves the holder. Futex (fast
userspace mutex) lets contended waiters sleep in the kernel
until the lock is released.
State word:
0 = unlocked
1 = locked, no waiters
2 = locked, possibly contended (waiters parked in kernel)
Lock fast path: CAS(0, 1).
Lock slow path: spin a few times, then transition to 2 + futex_wait.
Unlock fast path: store 0; if previous == 2, futex_wake one.
Today the sim is single-threaded, so we just track lock/unlock
state without actual blocking; the API matches the SMP path so
callers don't need to change later.
Linux RV64 futex syscall: 98.
Pairs with nx_atom for the CAS primitive (which is currently
non-atomic since SMP isn't on); will be a no-source-change
upgrade once nx_atom emits real LR/SC sequences.
dependencies 2 imports · 2 importers
imports: nx_syscalls.nxnx_atom.nx
imported by: nx_cond.nxnx_mutex_race_test.nx
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| 50 | struct NxMutex |
consts
| 37 | const NX_SYS_FUTEX: i64 = 98 |
| 40 | const NX_FUTEX_WAIT: i64 = 0 |
| 41 | const NX_FUTEX_WAKE: i64 = 1 |
| 42 | const NX_FUTEX_PRIVATE_FLAG: i64 = 128 |
| 44 | const NX_MUTEX_UNLOCKED: i64 = 0 |
| 45 | const NX_MUTEX_LOCKED: i64 = 1 |
| 46 | const NX_MUTEX_CONTENDED: i64 = 2 |
| 48 | const NX_MUTEX_SPIN_TRIES: i64 = 100 |
| 54 | const NX_MUTEX_BYTES: i64 = 8 |
functions
| 56 | func nx_mutex_new() -> *NxMutex |
| 66 | func nx_mutex_cas(m: *NxMutex, expect: i64, new_val: i64) -> i64 |
| 74 | func nx_mutex_futex_wait(m: *NxMutex, expected: i64) -> i64 called by 1: nx_mutex_lock |
| 80 | func nx_mutex_futex_wake(m: *NxMutex, n: i64) -> i64 called by 1: nx_mutex_unlock |
| 86 | func nx_mutex_lock(m: *NxMutex) -> i64 |
| 122 | func nx_mutex_try_lock(m: *NxMutex) -> i64 |
| 129 | func nx_mutex_unlock(m: *NxMutex) -> i64 |
| 141 | func main() -> i64 |