.\" Copyright, the authors of the Linux man-pages project .\" .\" %%%LICENSE_START(FREELY_REDISTRIBUTABLE) .\" may be freely modified and distributed .\" %%%LICENSE_END .\" .TH FUTEX_CMP_REQUEUE 2const 2025-05-30 "Linux man-pages 6.15" .SH NAME FUTEX_CMP_REQUEUE \- compare a futex, wake some waiters, and requeue others .SH LIBRARY Standard C library .RI ( libc ,\~ \-lc ) .SH SYNOPSIS .nf .BR "#include " " /* Definition of " FUTEX_* " constants */" .BR "#include " " /* Definition of " SYS_* " constants */" .B #include .P .BI "long syscall(SYS_futex, uint32_t *" uaddr ", FUTEX_CMP_REQUEUE," .BI " uint32_t " val ", uint32_t " val2 ", uint32_t *" uaddr2 , .BI " uint32_t " val3 ); .fi .SH DESCRIPTION This operation first checks whether the location .I uaddr still contains the value .IR val3 . If not, the operation fails with the error .BR EAGAIN . Otherwise, the operation wakes up a maximum of .I val waiters that are waiting on the futex at .IR uaddr . If there are more than .I val waiters, then the remaining waiters are removed from the wait queue of the source futex at .I uaddr and added to the wait queue of the target futex at .IR uaddr2 . The .I val2 argument specifies an upper limit on the number of waiters that are requeued to the futex at .IR uaddr2 . .P .\" FIXME(Torvald) Is the following correct? Or is just the decision .\" which threads to wake or requeue part of the atomic operation? The load from .I uaddr is an atomic memory access (i.e., using atomic machine instructions of the respective architecture). This load, the comparison with .IR val3 , and the requeueing of any waiters are performed atomically and totally ordered with respect to other operations on the same futex word. .\" Notes from a f2f conversation with Thomas Gleixner (Aug 2015): ### .\" The operation is serialized with respect to operations on both .\" source and target futex. No other waiter can enqueue itself .\" for waiting and no other waiter can dequeue itself because of .\" a timeout or signal. .P Typical values to specify for .I val are 0 or 1. (Specifying .I val as .B INT_MAX is not useful, because it would make the .B FUTEX_CMP_REQUEUE operation equivalent to .BR FUTEX_WAKE (2const).) The limit value specified via .I val2 is typically either 1 or .BR INT_MAX . (Specifying .I val2 as 0 is not useful, because it would make the .B FUTEX_CMP_REQUEUE operation equivalent to .BR FUTEX_WAKE (2const).) .P The .B FUTEX_CMP_REQUEUE operation was added as a replacement for the earlier .BR FUTEX_REQUEUE (2const). The difference is that the check of the value at .I uaddr can be used to ensure that requeueing happens only under certain conditions, which allows race conditions to be avoided in certain use cases. .\" But, as Rich Felker points out, there remain valid use cases for .\" FUTEX_REQUEUE, for example, when the calling thread is requeuing .\" the target(s) to a lock that the calling thread owns .\" From: Rich Felker .\" Date: Wed, 29 Oct 2014 22:43:17 -0400 .\" To: Darren Hart .\" CC: libc-alpha@sourceware.org, ... .\" Subject: Re: Add futex wrapper to glibc? .P Both .BR FUTEX_REQUEUE (2const) and .B FUTEX_CMP_REQUEUE can be used to avoid "thundering herd" wake-ups that could occur when using .BR FUTEX_WAKE (2const) 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: .P .in +4n .EX lock(A) while (!check_value(V)) { unlock(A); block_on(B); lock(A); }; unlock(A); .EE .in .P If a waker thread used .BR FUTEX_WAKE (2const), 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. .\" .SH RETURN VALUE On error, \-1 is returned, and .I errno is set to indicate the error. .P On success, .B FUTEX_CMP_REQUEUE returns the total number of waiters that were woken up or requeued to the futex for the futex word at .IR uaddr2 . If this value is greater than .IR val , then the difference is the number of waiters requeued to the futex for the futex word at .IR uaddr2 . .SH ERRORS See .BR futex (2). .TP .B EAGAIN The value pointed to by .I uaddr is not equal to the expected value .IR val3 . .TP .B EFAULT .I uaddr2 did not point to a valid user-space address. .TP .B EINVAL .I uaddr2 does not point to a valid object\[em]that is, the address is not four-byte-aligned. .TP .B EINVAL The kernel detected an inconsistency between the user-space state at .I uaddr and the kernel state\[em]that is, it detected a waiter which waits in .BR FUTEX_LOCK_PI (2const) or .BR FUTEX_LOCK_PI2 (2const) on .IR uaddr . .SH STANDARDS Linux. .SH HISTORY Linux 2.6.7. .SH SEE ALSO .BR futex (2)