---
name: "FUTEX_WAKE_OP"
section: "2const"
platform: "linux"
package: "man-pages"
version: "6.19-1"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/FUTEX_WAKE_OP"
---

# FUTEX\_WAKE\_OP(2const)

fast user-space locking

## NAME

FUTEX\_WAKE\_OP - fast user-space locking

## LIBRARY

Standard C library (*libc*, *-lc*)

## SYNOPSIS

```
#include <linux/futex.h>  /* Definition of FUTEX_* constants */
#include <sys/syscall.h>  /* Definition of SYS_* constants */
#include <unistd.h>
```

**long syscall(SYS\_futex, uint32\_t \****uaddr***, FUTEX\_WAKE\_OP, uint32\_t** *val***,**              **uint32\_t** *val2***, uint32\_t \****uaddr2***,**              **uint32\_t** *val3***);**

## DESCRIPTION

This operation was added to support some user-space use cases where more than one futex must be handled at the same time. The most notable example is the implementation of [**pthread\_cond\_signal**(3)](/pthread_cond_signal/3.md), which requires operations on two futexes, the one used to implement the mutex and the one used in the implementation of the wait queue associated with the condition variable. **FUTEX\_WAKE\_OP** allows such cases to be implemented without leading to high rates of contention and context switching.

The **FUTEX\_WAKE\_OP** operation is equivalent to executing the following code atomically and totally ordered with respect to other futex operations on any of the two supplied futex words:

```
uint32_t oldval = *(uint32_t *) uaddr2;
*(uint32_t *) uaddr2 = oldval op oparg;
futex(uaddr, FUTEX_WAKE, val, 0, 0, 0);
if (oldval cmp cmparg)
    futex(uaddr2, FUTEX_WAKE, val2, 0, 0, 0);
```

In other words, **FUTEX\_WAKE\_OP** does the following:

- •

  saves the original value of the futex word at *uaddr2* and performs an operation to modify the value of the futex at *uaddr2*; this is an atomic read-modify-write memory access (i.e., using atomic machine instructions of the respective architecture)

- •

  wakes up a maximum of *val* waiters on the futex for the futex word at *uaddr*; and

- •

  dependent on the results of a test of the original value of the futex word at *uaddr2*, wakes up a maximum of *val2* waiters on the futex for the futex word at *uaddr2*.

The operation and comparison that are to be performed are encoded in the bits of the argument *val3*. Pictorially, the encoding is:

```
+---+---+-----------+-----------+
|op |cmp|   oparg   |  cmparg   |
+---+---+-----------+-----------+
  4   4       12          12    <== # of bits
```

Expressed in code, the encoding is:

```
#define FUTEX_OP(op, oparg, cmp, cmparg) \
                (((op & 0xf) << 28) | \
                ((cmp & 0xf) << 24) | \
                ((oparg & 0xfff) << 12) | \
                (cmparg & 0xfff))
```

In the above, *op* and *cmp* are each one of the codes listed below. The *oparg* and *cmparg* components are literal numeric values, except as noted below.

The *op* component has one of the following values:

| | | |
| --- | --- | --- |
| FUTEX\_OP\_SET | 0 | /\* uaddr2 = oparg; \*/ |
| FUTEX\_OP\_ADD | 1 | /\* uaddr2 += oparg; \*/ |
| FUTEX\_OP\_OR | 2 | /\* uaddr2 \|= oparg; \*/ |
| FUTEX\_OP\_ANDN | 3 | /\* uaddr2 &= ~oparg; \*/ |
| FUTEX\_OP\_XOR | 4 | /\* uaddr2 ^= oparg; \*/ |

In addition, bitwise ORing the following value into *op* causes *(1 \<\< oparg)* to be used as the operand:

```
FUTEX_OP_ARG_SHIFT  8  /* Use (1 << oparg) as operand */
```

The *cmp* field is one of the following:

```
FUTEX_OP_CMP_EQ     0  /* if (oldval == cmparg) wake */
FUTEX_OP_CMP_NE     1  /* if (oldval != cmparg) wake */
FUTEX_OP_CMP_LT     2  /* if (oldval < cmparg) wake */
FUTEX_OP_CMP_LE     3  /* if (oldval <= cmparg) wake */
FUTEX_OP_CMP_GT     4  /* if (oldval > cmparg) wake */
FUTEX_OP_CMP_GE     5  /* if (oldval >= cmparg) wake */
```

The return value of **FUTEX\_WAKE\_OP** is the sum of the number of waiters woken on the futex *uaddr* plus the number of waiters woken on the futex *uaddr2*.

## RETURN VALUE

On error, -1 is returned, and *errno* is set to indicate the error.

On success, **FUTEX\_WAKE\_OP** Returns the total number of waiters that were woken up. This is the sum of the woken waiters on the two futexes for the futex words at *uaddr* and *uaddr2*.

## ERRORS

See [**futex**(2)](/futex/2.md).

- **EFAULT**

  *uaddr2* did not point to a valid user-space address.

- **EINVAL**

  *uaddr2* does not point to a valid object—that is, the address is not four-byte-aligned.

- **EINVAL**

  The kernel detected an inconsistency between the user-space state at *uaddr* and the kernel state—that is, it detected a waiter which waits in [**FUTEX\_LOCK\_PI**(2const)](/FUTEX_LOCK_PI/2const.md) or [**FUTEX\_LOCK\_PI2**(2const)](/FUTEX_LOCK_PI2/2const.md) on *uaddr*.

## STANDARDS

Linux.

## HISTORY

Linux 2.6.14.

## SEE ALSO

[**futex**(2)](/futex/2.md)
