Skip to content

futex()

Purpose

futex() (Fast Userspace Mutex) is a Linux system call used to implement efficient userspace synchronization primitives.

Most synchronization operations execute entirely in userspace.

The kernel is only involved when a thread must block or wake another thread.

This design minimizes system call overhead and improves synchronization performance.


#include <linux/futex.h>
#include <sys/syscall.h>
#include <unistd.h>

Prototype

long syscall(SYS_futex,
             uint32_t *uaddr,
             int futex_op,
             uint32_t val,
             const struct timespec *timeout,
             uint32_t *uaddr2,
             uint32_t val3);

Simplified Wrapper

Many applications use a helper function:

static int futex(uint32_t *uaddr,
                 int op,
                 uint32_t val)
{
    return syscall(SYS_futex,
                   uaddr,
                   op,
                   val,
                   NULL,
                   NULL,
                   0);
}

Design Goal

Fast path:

Userspace Only

Slow path:

Userspace
Kernel Wait Queue
Sleep / Wakeup

Common Operations

FUTEX_WAIT

Sleep if the futex value matches the expected value.

futex(&lock,
      FUTEX_WAIT,
      expected);

FUTEX_WAKE

Wake one or more waiting threads.

futex(&lock,
      FUTEX_WAKE,
      nr_wakeup);

Typical Mutex Flow

Acquire:

Try Atomic CAS
Success
Continue

Failure
FUTEX_WAIT

Release:

Unlock
FUTEX_WAKE

Example

Thread A:

while (atomic_exchange(&lock, 1) != 0)
    futex(&lock, FUTEX_WAIT, 1);

Thread B:

atomic_store(&lock, 0);

futex(&lock, FUTEX_WAKE, 1);

Why Futex Is Fast

Uncontended case:

Atomic Operation Only

No system call.

No context switch.

No kernel involvement.


Typical Users

Many POSIX synchronization primitives are implemented using futex:

pthread_mutex
pthread_cond_wait
pthread_rwlock

Advantages

Fast Uncontended Path

Userspace Only

Low Kernel Overhead

Kernel involvement occurs only when blocking is required.


Foundation of Linux Userspace Synchronization

Most pthread synchronization mechanisms rely on futex internally.


Limitations

Linux Specific

Not part of POSIX.


Low-Level Interface

Most applications should use:

pthread mutex
pthread condition variable
pthread rwlock

instead of directly calling futex().