# FUTEX_CMP_REQUEUE

## 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).)  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).)
    
           The **FUTEX_CMP_REQUEUE** operation was added as a replacement for the
           earlier FUTEX_REQUEUE(2const).  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) and **FUTEX_CMP_REQUEUE** can be used to
           avoid "thundering herd" wake-ups that could occur when using
           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:
    
               lock(A)
               while (!check_value(V)) {
                   unlock(A);
                   block_on(B);
                   lock(A);
               };
               unlock(A);
    
           If a waker thread used 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.
    


## 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).
    
           **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) or
                  FUTEX_LOCK_PI2(2const) on _uaddr_.
    


## STANDARDS



           Linux.
    


* * *