FUTEX(2) | System Calls Manual | FUTEX(2)

# NAME

`futex` — fast userspace locking primitive

# SYNOPSIS

`#include <sys/time.h>`
`#include <sys/futex.h>`

int
`futex`(volatile uint32_t *uaddr, int op, int val, const struct timespec *timeout, volatile uint32_t *uaddr2);

# DESCRIPTION

The `futex`() syscall provides sleep and wakeup primitives related to a particular address.

Three op operations are currently supported:

`FUTEX_WAIT`
  If val is equal to *uaddr, the calling thread is blocked on the “wait channel” identified by uaddr until timeout expires or until another thread issues a `FUTEX_WAKE` or `FUTEX_REQUEUE` operation with the same uaddr address. uaddr2 is ignored.
`FUTEX_WAKE`
  Unblocks val threads sleeping on the wait channel identified by uaddr. timeout and uaddr2 are ignored.
`FUTEX_REQUEUE`
  Similar to `FUTEX_WAKE` but also requeue remaining threads from the wait channel uaddr to uaddr2. In this case, pass uint32_t val2 as the fourth argument instead of timeout. At most that number of threads is requeued.

# RETURN VALUES

For `FUTEX_WAKE` and `FUTEX_REQUEUE`, `futex`() returns the number of woken threads.

For `FUTEX_WAIT`, `futex`() returns zero if woken by a matching `FUTEX_WAKE` or `FUTEX_REQUEUE` call. Otherwise, a value of -1 is returned and errno is set to indicate the error.

# ERRORS

`futex`() will fail if:

[`ENOSYS`]
  The op argument is invalid.
[`EFAULT`]
  The userspace address uaddr is invalid.
[`EAGAIN`]
  The value pointed to by uaddr is not the same as the expected value val.
[`EINVAL`]
  The timeout specified a second value less than zero, or a nanosecond value less than zero or greater than or equal to 1000 million.
[`ETIMEDOUT`]
  The timeout expired before the thread was woken up.
[`EINTR`]
  A signal arrived.
[`ECANCELED`]
  A signal arrived and SA_RESTART was set.

# SEE ALSO

sigaction(2), pthread_cond_wait(3), pthread_mutex_lock(3), tsleep(9)

Ulrich Drepper, Futexes Are Tricky, https://www.akkadia.org/drepper/futex.pdf, November 5, 2011.

# HISTORY

The `futex`() syscall first appeared in Linux 2.5.7 and was added to OpenBSD 6.2.

November 9, 2023 | Debian