liveBook · Manning

SYS_futex

As explained in Learn Concurrent Programming with Go

A futex is an operating-system synchronization system call that allows user-space code to wait for and wake executions based on a shared memory value.

SYS_futex is the Linux system-call entry point for futex waiting and waking. A futex is not itself a mutex: it is a user-space-accessible wait-queue primitive that suspends or awakens an execution associated with a shared memory address. Mutexes, semaphores, and condition variables can use it to avoid wasting CPU while a resource remains locked. section 12.3.1 section 12.0

A wait operation receives an address and expected value. If memory still contains that value, the caller is suspended and queued for that address; if it has changed, waiting returns immediately. A wake operation names the address and resumes a requested number of queued threads or processes, or all of them when the count is zero. section 12.3.1

Figure 12.6 Calling futex_wait() with two different outcomes

Compare the two wait outcomes: matching the expected value parks an execution, while a changed value lets it continue without sleeping. section 12.3.1

Futexes address a weakness of yielding spin locks. A yielding execution may be scheduled repeatedly even though the lock is still unavailable. By parking the waiter, the operating system knows it should not run again until another execution releases the lock and wakes a waiter. section 12.3 section 12.3.1

A futex-backed lock

A lock can first use CompareAndSwap to change its atomic state from 0 (unlocked) to 1 (locked). On failure, it waits only while the state is locked. Unlocking stores 0 and wakes one waiter. A refined version uses state 2 for “locked with waiters,” so Unlock calls futex_wakeup only when contention exists. After waking, a contender must still retry acquisition rather than assume it owns the lock. section 12.3.1 section 12.3.2

A futex-backed mutex combines fast user-space atomics with kernel assistance only when needed:

  • Acquire immediately with an atomic compare-and-swap when the state is unlocked. section 12.3.1
  • Mark contention and suspend on the futex when another execution owns the lock. section 12.3.2
  • Release atomically, then wake a waiter only if the prior state records waiting executions. section 12.3.2

The exact interface is operating-system-specific. On Linux, wait and wake are implemented through syscall(SYS_futex, ...) with FUTEX_WAIT and FUTEX_WAKE parameters. Windows provides corresponding address-wait and address-wake system calls. Go’s sync.Mutex does not directly use futexes: its runtime queues and parks goroutines in user space through an internal semaphore, avoiding suspension of the underlying kernel thread. section 12.3.1 section 12.3.3

How Learn Concurrent Programming with Go covers it

How deep it goes
Defines address-based wait queues and works through atomic mutex states, conditional waking, and contention optimization.
Examples
Illustrates pseudo-Go FutexLock operations and a state diagram for waiting versus immediate return.
What it assumes
Builds on mutexes and atomic CompareAndSwap while defining futex waiting and waking in plain operational terms.
What you can do after
Build it from scratch as an atomic mutex that waits under contention and wakes only when waiters exist.
How it connects
Connects atomic variables, CompareAndSwap, spin locks, mutexes, semaphores, condition variables, and Go runtime scheduling.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Learn Concurrent Programming with Go. The section links point to the parts of the book it draws on.