Futex
This document describes the futex (Fast Userspace Mutex) implementation in the Kyronix kernel. It is the child of Syscalls.
Syscall Table
- 202
futex- Fast Userspace Mutex operations
Operations
The futex syscall supports four operation commands, selected by the op argument. The FUTEX_PRIVATE_FLAG (128) and FUTEX_CLOCK_REALTIME (256) flags may be OR’d with the operation but are currently ignored.
FUTEX_WAIT (0)
Atomically checks that the value at uaddr equals val, then blocks the calling process until woken:
- Verify
*uaddr == val. If not, returnEAGAIN. - Find a free slot in
g_futex_tab. If no slot is available, returnENOMEM. - Register the current process and
uaddrin the slot. - If a timeout is provided (a
timespecpointer), compute the deadline in milliseconds:deadline = g_ticks + (sec * 1000 + nsec / 1000000). - Block in a loop until the process is woken, the deadline expires, or a signal is delivered.
- On timeout, return
ETIMEDOUT. Otherwise, return 0.
FUTEX_WAKE (1)
Wakes up to val processes waiting on uaddr:
- Scan
g_futex_tabfor entries matchinguaddr. - For each matching entry, verify the waiting process is in the same jail as the caller (
g_futex_tab[i].proc->jail_id == self->jail_id). - Transition the waiting process from
PROC_WAITINGtoPROC_READYviaproc_set_ready(). - Return the count of processes woken.
FUTEX_REQUEUE (3)
Moves waiters from uaddr to uaddr2:
- Wake up to
valwaiters onuaddr. - Requeue up to the second argument (passed in the timeout slot) waiters from
uaddrtouaddr2by updating theiruaddrfield. - Cross-jail checks apply: only processes in the same jail as the caller are affected.
FUTEX_CMP_REQUEUE (4)
Same as FUTEX_REQUEUE, but first verifies that *uaddr == val3. Returns EAGAIN if the comparison fails.
Data Structure
Futex state is stored in the global g_futex_tab array with FUTEX_MAX_WAITERS (PROC_MAX) entries. Each entry contains:
uaddr- The userspace address being waited onproc- Pointer to the waiting process (NULL if the slot is free)
The table is protected by g_futex_lock, a spinlock acquired on all read and write operations. Waiter registration and wakeup use __sync_bool_compare_and_swap for atomic state transitions.
CLONE_CHILD_CLEARTID Integration
When a thread created with CLONE_CHILD_CLEARTID (flag 0x00200000) exits:
- The kernel writes zero to the
cleartid_addrstored in the thread’s process structure. - The kernel calls
cleartid_wake(cleartid_addr). cleartid_wakescansg_futex_tabfor all entries whoseuaddrmatchescleartid_addr.- Each matching process is transitioned from
PROC_WAITINGtoPROC_READY.
This mechanism enables pthread library implementations to use CLONE_CHILD_CLEARTID with a futex address, ensuring that joiners blocked on futex(CLEARTID) are woken when the thread exits.
Last reviewed: 2026-07-22