# FUTEX_WAKE_OP

## 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), 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).
    
           **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.
    


* * *