---
name: "FUTEX_CMP_REQUEUE"
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_CMP_REQUEUE"
---

# FUTEX\_CMP\_REQUEUE(2const)

compare a futex, wake some waiters, and requeue others

## NAME

FUTEX\_CMP\_REQUEUE - compare a futex, wake some waiters, and requeue others

## 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\_CMP\_REQUEUE,**              **uint32\_t** *val***, uint32\_t** *val2***, uint32\_t \****uaddr2***,**              **uint32\_t** *val3***);**

## DESCRIPTION

This operation first checks whether the location *uaddr* still contains the value *val3*. If not, the operation fails with the error **EAGAIN**. Otherwise, the operation wakes up a maximum of *val* waiters that are waiting on the futex at *uaddr*. If there are more than *val* waiters, then the remaining waiters are removed from the wait queue of the source futex at *uaddr* and added to the wait queue of the target futex at *uaddr2*. The *val2* argument specifies an upper limit on the number of waiters that are requeued to the futex at *uaddr2*.

The load from *uaddr* is an atomic memory access (i.e., using atomic machine instructions of the respective architecture). This load, the comparison with *val3*, and the requeueing of any waiters are performed atomically and totally ordered with respect to other operations on the same futex word.

Typical values to specify for *val* are 0 or 1. (Specifying *val* as **INT\_MAX** is not useful, because it would make the **FUTEX\_CMP\_REQUEUE** operation equivalent to [**FUTEX\_WAKE**(2const)](/FUTEX_WAKE/2const.md).) The limit value specified via *val2* is typically either 1 or **INT\_MAX**. (Specifying *val2* as 0 is not useful, because it would make the **FUTEX\_CMP\_REQUEUE** operation equivalent to [**FUTEX\_WAKE**(2const)](/FUTEX_WAKE/2const.md).)

The **FUTEX\_CMP\_REQUEUE** operation was added as a replacement for the earlier [**FUTEX\_REQUEUE**(2const)](/FUTEX_REQUEUE/2const.md). The difference is that the check of the value at *uaddr* can be used to ensure that requeueing happens only under certain conditions, which allows race conditions to be avoided in certain use cases.

Both [**FUTEX\_REQUEUE**(2const)](/FUTEX_REQUEUE/2const.md) and **FUTEX\_CMP\_REQUEUE** can be used to avoid "thundering herd" wake-ups that could occur when using [**FUTEX\_WAKE**(2const)](/FUTEX_WAKE/2const.md) in cases where all of the waiters that are woken need to acquire another futex. Consider the following scenario, where multiple waiter threads are waiting on B, a wait queue implemented using a futex:

```
lock(A)
while (!check_value(V)) {
    unlock(A);
    block_on(B);
    lock(A);
};
unlock(A);
```

If a waker thread used [**FUTEX\_WAKE**(2const)](/FUTEX_WAKE/2const.md), then all waiters waiting on B would be woken up, and they would all try to acquire lock A. However, waking all of the threads in this manner would be pointless because all except one of the threads would immediately block on lock A again. By contrast, a requeue operation wakes just one waiter and moves the other waiters to lock A, and when the woken waiter unlocks A then the next waiter can proceed.

## RETURN VALUE

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

On success, **FUTEX\_CMP\_REQUEUE** returns the total number of waiters that were woken up or requeued to the futex for the futex word at *uaddr2*. If this value is greater than *val*, then the difference is the number of waiters requeued to the futex for the futex word at *uaddr2*.

## ERRORS

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

- **EAGAIN**

  The value pointed to by *uaddr* is not equal to the expected value *val3*.

- **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.7.

## SEE ALSO

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