Provided by: manpages-dev_4.04-2_all bug

NAME

       futex - fast user-space locking

SYNOPSIS

       #include <linux/futex.h>
       #include <sys/time.h>

       int futex(int *uaddr, int futex_op, int val,
                 const struct timespec *timeout,   /* or: uint32_t val2 */
                 int *uaddr2, int val3);

       Note: There is no glibc wrapper for this system call; see NOTES.

DESCRIPTION

       The  futex()  system  call provides a method for waiting until a certain condition becomes
       true.  It is typically used as a  blocking  construct  in  the  context  of  shared-memory
       synchronization.   When  using futexes, the majority of the synchronization operations are
       performed in user space.  A user-space program employs the futex() system call  only  when
       it  is  likely that the program has to block for a longer time until the condition becomes
       true.  Other futex() operations can be used to wake any processes or threads waiting for a
       particular condition.

       A  futex  is a 32-bit value—referred to below as a futex word—whose address is supplied to
       the futex() system call.  (Futexes are 32 bits in size on all platforms, including  64-bit
       systems.)   All  futex  operations  are governed by this value.  In order to share a futex
       between processes, the futex is placed in a region of shared memory,  created  using  (for
       example)  mmap(2) or shmat(2).  (Thus, the futex word may have different virtual addresses
       in different processes, but these addresses all refer to the  same  location  in  physical
       memory.)  In a multithreaded program, it is sufficient to place the futex word in a global
       variable shared by all threads.

       When executing a futex operation that requests to block a thread, the  kernel  will  block
       only  if  the  futex  word  has  the value that the calling thread supplied (as one of the
       arguments of the futex() call) as the expected value of the futex word.   The  loading  of
       the  futex  word's  value,  the  comparison of that value with the expected value, and the
       actual blocking will happen atomically  and  will  be  totally  ordered  with  respect  to
       concurrent  operations performed by other threads on the same futex word.  Thus, the futex
       word is used to connect the synchronization in  user  space  with  the  implementation  of
       blocking  by  the  kernel.   Analogously  to an atomic compare-and-exchange operation that
       potentially changes shared memory, blocking via a futex  is  an  atomic  compare-and-block
       operation.

       One  use  of  futexes is for implementing locks.  The state of the lock (i.e., acquired or
       not acquired) can be represented as an atomically accessed flag in shared memory.  In  the
       uncontended  case,  a thread can access or modify the lock state with atomic instructions,
       for example atomically changing it from not acquired to acquired using an atomic  compare-
       and-exchange instruction.  (Such instructions are performed entirely in user mode, and the
       kernel maintains no information about the lock state.)  On the other hand, a thread may be
       unable  to  acquire  a lock because it is already acquired by another thread.  It then may
       pass the lock's flag as a futex word and the value representing the acquired state as  the
       expected value to a futex() wait operation.  This futex() operation will block if and only
       if the lock is still acquired (i.e., the  value  in  the  futex  word  still  matches  the
       "acquiired  state").   When releasing the lock, a thread has to first reset the lock state
       to not acquired and then execute a futex operation that wakes threads blocked on the  lock
       flag  used  as  a  futex word (this can be be further optimized to avoid unnecessary wake-
       ups).  See futex(7) for more detail on how to use futexes.

       Besides the basic wait and wake-up futex functionality, there are further futex operations
       aimed at supporting more complex use cases.

       Note  that  no  explicit  initialization  or  destruction is necessary to use futexes; the
       kernel maintains a futex (i.e., the kernel-internal implementation  artifact)  only  while
       operations  such as FUTEX_WAIT, described below, are being performed on a particular futex
       word.

   Arguments
       The uaddr argument points to the futex word.  On  all  platforms,  futexes  are  four-byte
       integers  that  must  be aligned on a four-byte boundary.  The operation to perform on the
       futex is specified in the futex_op argument; val is a  value  whose  meaning  and  purpose
       depends on futex_op.

       The  remaining  arguments (timeout, uaddr2, and val3) are required only for certain of the
       futex operations described below.  Where one of these arguments is  not  required,  it  is
       ignored.

       For several blocking operations, the timeout argument is a pointer to a timespec structure
       that specifies a timeout for the operation.  However,  notwithstanding the prototype shown
       above,  for some operations, the least significant four bytes are used as an integer whose
       meaning is determined by the operation.   For  these  operations,  the  kernel  casts  the
       timeout value first to unsigned long, then to uint32_t, and in the remainder of this page,
       this argument is referred to as val2 when interpreted in this fashion.

       Where it is required, the uaddr2 argument is a pointer to a  second  futex  word  that  is
       employed  by  the  operation.   The  interpretation  of  the final integer argument, val3,
       depends on the operation.

   Futex operations
       The futex_op argument consists of two parts: a command that specifies the operation to  be
       performed,  bit-wise  ORed  with  zero or or more options that modify the behaviour of the
       operation.  The options that may be included in futex_op are as follows:

       FUTEX_PRIVATE_FLAG (since Linux 2.6.22)
              This option bit can be employed with all futex operations.   It  tells  the  kernel
              that  the futex is process-private and not shared with another process (i.e., it is
              being used for synchronization only between threads of  the  same  process).   This
              allows the kernel to make some additional performance optimizations.

              As  a  convenience,  <linux/futex.h>  defines  a  set  of constants with the suffix
              _PRIVATE that are equivalents of all of the operations listed below, but  with  the
              FUTEX_PRIVATE_FLAG    ORed    into   the   constant   value.    Thus,   there   are
              FUTEX_WAIT_PRIVATE, FUTEX_WAKE_PRIVATE, and so on.

       FUTEX_CLOCK_REALTIME (since Linux 2.6.28)
              This  option  bit  can  be   employed   only   with   the   FUTEX_WAIT_BITSET   and
              FUTEX_WAIT_REQUEUE_PI operations.

              If  this  option  is  set,  the  kernel treats timeout as an absolute time based on
              CLOCK_REALTIME.

              If this option is not set, the kernel treats timeout as a relative  time,  measured
              against the CLOCK_MONOTONIC clock.

       The operation specified in futex_op is one of the following:

       FUTEX_WAIT (since Linux 2.6.0)
              This  operation  tests  that  the value at the futex word pointed to by the address
              uaddr still contains the expected value val, and if so, then sleeps waiting  for  a
              FUTEX_WAKE operation on the futex word.  The load of the value of the futex word is
              an atomic memory access (i.e., using atomic machine instructions of the  respective
              architecture).   This load, the comparison with the expected value, and starting to
              sleep are performed atomically and totally ordered  with  respect  to  other  futex
              operations on the same futex word.  If the thread starts to sleep, it is considered
              a waiter on this futex word.  If the futex value does not match val, then the  call
              fails immediately with the error EAGAIN.

              The  purpose of the comparison with the expected value is to prevent lost wake-ups.
              If another thread changed the value of the futex  word  after  the  calling  thread
              decided  to  block  based  on  the  prior value, and if the other thread executed a
              FUTEX_WAKE operation (or similar wake-up) after the value change  and  before  this
              FUTEX_WAIT  operation,  then  the  calling thread will observe the value change and
              will not start to sleep.

              If the timeout argument is non-NULL, its contents specify a  relative  timeout  for
              the  wait, measured according to the CLOCK_MONOTONIC clock.  (This interval will be
              rounded up to the system clock granularity, and is guaranteed not to expire early.)
              If timeout is NULL, the call blocks indefinitely.

              The arguments uaddr2 and val3 are ignored.

       FUTEX_WAKE (since Linux 2.6.0)
              This  operation  wakes  at  most  val of the waiters that are waiting (e.g., inside
              FUTEX_WAIT) on the futex  word  at  the  address  uaddr.   Most  commonly,  val  is
              specified  as  either 1 (wake up a single waiter) or INT_MAX (wake up all waiters).
              No guarantee is provided about which waiters are awoken  (e.g.,  a  waiter  with  a
              higher scheduling priority is not guaranteed to be awoken in preference to a waiter
              with a lower priority).

              The arguments timeout, uaddr2, and val3 are ignored.

       FUTEX_FD (from Linux 2.6.0 up to and including Linux 2.6.25)
              This operation creates a file descriptor that  is  associated  with  the  futex  at
              uaddr.  The caller must close the returned file descriptor after use.  When another
              process or thread performs a FUTEX_WAKE on the  futex  word,  the  file  descriptor
              indicates as being readable with select(2), poll(2), and epoll(7)

              The  file  descriptor  can  be used to obtain asynchronous notifications: if val is
              nonzero, then, when another process or thread executes  a  FUTEX_WAKE,  the  caller
              will receive the signal number that was passed in val.

              The arguments timeout, uaddr2 and val3 are ignored.

              Because it was inherently racy, FUTEX_FD has been removed from Linux 2.6.26 onward.

       FUTEX_REQUEUE (since Linux 2.6.0)
              This operation performs the same task as FUTEX_CMP_REQUEUE (see below), except that
              no check is made using the value in val3.  (The argument val3 is ignored.)

       FUTEX_CMP_REQUEUE (since Linux 2.6.7)
              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 or 1.  (Specifying INT_MAX is not
              useful, because  it  would  make  the  FUTEX_CMP_REQUEUE  operation  equivalent  to
              FUTEX_WAKE.)   The limit value specified via val2 is typically either 1 or INT_MAX.
              (Specifying  the  argument  as  0  is  not  useful,  because  it  would  make   the
              FUTEX_CMP_REQUEUE operation equivalent to FUTEX_WAIT.)

              The  FUTEX_CMP_REQUEUE  operation  was  added  as  a  replacement  for  the earlier
              FUTEX_REQUEUE.  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 and FUTEX_CMP_REQUEUE can be used  to  avoid  "thundering  herd"
              wake-ups  that  could occur when using FUTEX_WAKE 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, then all waiters waiting on B would be woken up,
              and they would 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.

       FUTEX_WAKE_OP (since Linux 2.6.14)
              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:

                  int oldval = *(int *) uaddr2;
                  *(int *) 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, bit-wise 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.

       FUTEX_WAIT_BITSET (since Linux 2.6.25)
              This operation is like FUTEX_WAIT except that val3 is used to provide a 32-bit mask
              to the kernel.  This bit mask is stored in the kernel-internal state of the waiter.
              See the description of FUTEX_WAKE_BITSET for further details.

              The FUTEX_WAIT_BITSET operation also interprets the  timeout  argument  differently
              from FUTEX_WAIT.  See the discussion of FUTEX_CLOCK_REALTIME, above.

              The uaddr2 argument is ignored.

       FUTEX_WAKE_BITSET (since Linux 2.6.25)
              This  operation  is the same as FUTEX_WAKE except that the val3 argument is used to
              provide a 32-bit bit mask to the kernel.  This bit mask is  used  to  select  which
              waiters  should be woken up.  The selection is done by a bit-wise AND of the "wake"
              bit mask (i.e., the value in val3) and the bit mask which is stored in the  kernel-
              internal   state   of   the   waiter  (the  "wait"  bit  mask  that  is  set  using
              FUTEX_WAIT_BITSET).  All of the waiters for which the result of the AND is  nonzero
              are woken up; the remaining waiters are left sleeping.

              The  effect  of FUTEX_WAIT_BITSET and FUTEX_WAKE_BITSET is to allow selective wake-
              ups among multiple waiters that are blocked on the same futex.  However, note that,
              depending  on the use case, employing this bit-mask multiplexing feature on a futex
              can be less efficient than simply using multiple futexes,  because  employing  bit-
              mask  multiplexing  requires  the kernel to check all waiters on a futex, including
              those that are not interested in being  woken  up  (i.e.,  they  do  not  have  the
              relevant bit set in their "wait" bit mask).

              The uaddr2 and timeout arguments are ignored.

              The  FUTEX_WAIT  and  FUTEX_WAKE  operations  correspond  to  FUTEX_WAIT_BITSET and
              FUTEX_WAKE_BITSET operations where the bit masks are all ones.

   Priority-inheritance futexes
       Linux supports priority-inheritance (PI) futexes in  order  to  handle  priority-inversion
       problems  that  can  be  encountered  with  normal futex locks.  Priority inversion is the
       problem that occurs when a high-priority task is blocked waiting to acquire a lock held by
       a low-priority task, while tasks at an intermediate priority continuously preempt the low-
       priority task from the CPU.  Consequently, the low-priority task makes no progress  toward
       releasing the lock, and the high-priority task remains blocked.

       Priority inheritance is a mechanism for dealing with the priority-inversion problem.  With
       this mechanism, when a high-priority task becomes blocked by a lock held by a low-priority
       task,  the  priority  of  the low-priority task is temporarily raised to that of the high-
       priority task, so that it is not preempted by any intermediate level tasks, and  can  thus
       make  progress  toward  releasing the lock.  To be effective, priority inheritance must be
       transitive, meaning that if a high-priority task blocks on a lock held by a lower-priority
       task  that  is itself blocked by a lock held by another intermediate-priority task (and so
       on, for chains of arbitrary length), then both of those tasks (or more generally,  all  of
       the  tasks  in  a  lock  chain)  have  their priorities raised to be the same as the high-
       priority task.

       From a user-space  perspective,  what  makes  a  futex  PI-aware  is  a  policy  agreement
       (described  below)  between  user  space and the kernel about the value of the futex word,
       coupled with the use of the PI-futex operations described below.  (Unlike the other  futex
       operations described above, the PI-futex operations are designed for the implementation of
       very specific IPC mechanisms.)

       The PI-futex operations described below differ from the other  futex  operations  in  that
       they impose policy on the use of the value of the futex word:

       *  If the lock is not acquired, the futex word's value shall be 0.

       *  If  the  lock  is  acquired,  the  futex  word's value shall be the thread ID (TID; see
          gettid(2)) of the owning thread.

       *  If the lock is  owned  and  there  are  threads  contending  for  the  lock,  then  the
          FUTEX_WAITERS  bit  shall  be set in the futex word's value; in other words, this value
          is:

              FUTEX_WAITERS | TID

          (Note that is invalid for a PI futex word to have no owner and FUTEX_WAITERS set.)

       With this policy in place, a user-space application can  acquire  an  unacquired  lock  or
       release  a  lock using atomic instructions executed in user mode (e.g., a compare-and-swap
       operation such as cmpxchg on the x86 architecture).  Acquiring a lock simply  consists  of
       using compare-and-swap to atomically set the futex word's value to the caller's TID if its
       previous value was 0.  Releasing a lock requires using compare-and-swap to set  the  futex
       word's value to 0 if the previous value was the expected TID.

       If  a  futex  is  already  acquired  (i.e.,  has a nonzero value), waiters must employ the
       FUTEX_LOCK_PI operation to acquire the lock.  If other threads are waiting for  the  lock,
       then  the  FUTEX_WAITERS  bit is set in the futex value; in this case, the lock owner must
       employ the FUTEX_UNLOCK_PI operation to release the lock.

       In the cases where callers are forced into the kernel (i.e., required to perform a futex()
       call), they then deal directly with a so-called RT-mutex, a kernel locking mechanism which
       implements the required priority-inheritance semantics.  After the RT-mutex  is  acquired,
       the futex value is updated accordingly, before the calling thread returns to user space.

       It  is  important  to  note  that  the  kernel will update the futex word's value prior to
       returning to user space.  (This prevents the possibility of the futex word's value  ending
       up  in  an invalid state, such as having an owner but the value being 0, or having waiters
       but not having the FUTEX_WAITERS bit set.)

       If a futex has an associated RT-mutex in the kernel (i.e., there are blocked waiters)  and
       the  owner of the futex/RT-mutex dies unexpectedly, then the kernel cleans up the RT-mutex
       and hands it over to the next waiter.  This in turn requires that the user-space value  is
       updated   accordingly.    To   indicate  that  this  is  required,  the  kernel  sets  the
       FUTEX_OWNER_DIED bit in the futex word along with the thread ID of the  new  owner.   User
       space  can  detect this situation via the presence of the FUTEX_OWNER_DIED bit and is then
       responsible for cleaning up the stale state left over by the dead owner.

       PI futexes are operated on by specifying one of the values listed below in futex_op.  Note
       that  the  PI  futex  operations must be used as paired operations and are subject to some
       additional requirements:

       *  FUTEX_LOCK_PI and FUTEX_TRYLOCK_PI pair with FUTEX_UNLOCK_PI.  FUTEX_UNLOCK_PI must  be
          called  only  on  a  futex owned by the calling thread, as defined by the value policy,
          otherwise the error EPERM results.

       *  FUTEX_WAIT_REQUEUE_PI pairs with FUTEX_CMP_REQUEUE_PI.  This must be performed  from  a
          non-PI  futex  to a distinct PI futex (or the error EINVAL results).  Additionally, val
          (the number of waiters to be woken) must be 1 (or the error EINVAL results).

       The PI futex operations are as follows:

       FUTEX_LOCK_PI (since Linux 2.6.18)
              This operation is used after an attempt to acquire the lock via an atomic user-mode
              instruction failed because the futex word has a nonzero value—specifically, because
              it contained the (PID-namespace-specific) TID of the lock owner.

              The operation checks the value of the futex word at  the  address  uaddr.   If  the
              value is 0, then the kernel tries to atomically set the futex value to the caller's
              TID.  If the futex  word's  value  is  nonzero,  the  kernel  atomically  sets  the
              FUTEX_WAITERS bit, which signals the futex owner that it cannot unlock the futex in
              user space atomically by setting the futex value to 0.  After that, the kernel:

              1. Tries to find the thread which is associated with the owner TID.

              2. Creates or reuses kernel state on behalf of the owner.  (If this  is  the  first
                 waiter,  there  is no kernel state for this futex, so kernel state is created by
                 locking the RT-mutex and the futex owner is made the owner of the RT-mutex.   If
                 there are existing waiters, then the existing state is reused.)

              3. Attaches  the  waiter to the futex (i.e., the waiter is enqueued on the RT-mutex
                 waiter list).

              If more than one waiter exists, the enqueueing  of  the  waiter  is  in  descending
              priority  order.   (For information on priority ordering, see the discussion of the
              SCHED_DEADLINE, SCHED_FIFO, and SCHED_RR scheduling  policies  in  sched(7).)   The
              owner  inherits either the waiter's CPU bandwidth (if the waiter is scheduled under
              the SCHED_DEADLINE policy) or the waiter's priority (if  the  waiter  is  scheduled
              under  the SCHED_RR or SCHED_FIFO policy).  This inheritance follows the lock chain
              in the case of nested locking and performs deadlock detection.

              The timeout argument provides a timeout for the lock attempt.  It is interpreted as
              an  absolute  time, measured against the CLOCK_REALTIME clock.  If timeout is NULL,
              the operation will block indefinitely.

              The uaddr2, val, and val3 arguments are ignored.

       FUTEX_TRYLOCK_PI (since Linux 2.6.18)
              This operation tries to acquire the lock at uaddr.  It is invoked when a user-space
              atomic acquire did not succeed because the futex word was not 0.

              Because  the  kernel  has  access  to  more  state  information  than  user  space,
              acquisition of the lock might succeed if performed by the kernel in cases where the
              futex  word  (i.e.,  the  state information accessible to use-space) contains stale
              state (FUTEX_WAITERS and/or FUTEX_OWNER_DIED).  This can happen when the  owner  of
              the futex died.  User space cannot handle this condition in a race-free manner, but
              the kernel can fix this up and acquire the futex.

              The uaddr2, val, timeout, and val3 arguments are ignored.

       FUTEX_UNLOCK_PI (since Linux 2.6.18)
              This operation wakes the top priority waiter that is waiting  in  FUTEX_LOCK_PI  on
              the futex address provided by the uaddr argument.

              This is called when the user-space value at uaddr cannot be changed atomically from
              a TID (of the owner) to 0.

              The uaddr2, val, timeout, and val3 arguments are ignored.

       FUTEX_CMP_REQUEUE_PI (since Linux 2.6.31)
              This operation is a PI-aware variant of  FUTEX_CMP_REQUEUE.   It  requeues  waiters
              that  are  blocked  via  FUTEX_WAIT_REQUEUE_PI  on uaddr from a non-PI source futex
              (uaddr) to a PI target futex (uaddr2).

              As with FUTEX_CMP_REQUEUE, this operation wakes up a maximum of  val  waiters  that
              are  waiting  on  the  futex  at  uaddr.  However, for FUTEX_CMP_REQUEUE_PI, val is
              required to be 1 (since the main  point  is  to  avoid  a  thundering  herd).   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 and val3 arguments serve the same purposes as for FUTEX_CMP_REQUEUE.

       FUTEX_WAIT_REQUEUE_PI (since Linux 2.6.31)
              Wait  on  a  non-PI  futex  at  uaddr  and   potentially   be   requeued   (via   a
              FUTEX_CMP_REQUEUE_PI  operation  in  another  task) onto a PI futex at uaddr2.  The
              wait operation on uaddr is the same as for FUTEX_WAIT.

              The waiter can be removed from the wait on uaddr without requeueing on uaddr2 via a
              FUTEX_WAKE  operation  in  another  task.   In this case, the FUTEX_WAIT_REQUEUE_PI
              operation fails with the error EAGAIN.

              If timeout is not NULL, it specifies a timeout for the wait operation; this timeout
              is  interpreted  as  outlined  above in the description of the FUTEX_CLOCK_REALTIME
              option.  If timeout is NULL, the operation can block indefinitely.

              The val3 argument is ignored.

              The FUTEX_WAIT_REQUEUE_PI and FUTEX_CMP_REQUEUE_PI were added to support  a  fairly
              specific  use  case: support for priority-inheritance-aware POSIX threads condition
              variables.  The idea is that these operations should always be paired, in order  to
              ensure   that   user   space   and  the  kernel  remain  in  sync.   Thus,  in  the
              FUTEX_WAIT_REQUEUE_PI  operation,  the  user-space  application  pre-specifies  the
              target of the requeue that takes place in the FUTEX_CMP_REQUEUE_PI operation.

RETURN VALUE

       In  the  event  of  an  error  (and assuming that futex() was invoked via syscall(2)), all
       operations return -1 and set errno to indicate the cause of the error.

       The return value on success depends on the operation, as described in the following list:

       FUTEX_WAIT
              Returns 0 if the caller was woken up.  Note that a wake-up can also  be  caused  by
              common futex usage patterns in unrelated code that happened to have previously used
              the futex word's memory location  (e.g.,  typical  futex-based  implementations  of
              Pthreads  mutexes can cause this under some conditions).  Therefore, callers should
              always conservatively assume that a return value of 0 can mean a spurious  wake-up,
              and  use  the  futex  word's value (i.e., the user-space synchronization scheme) to
              decide whether to continue to block or not.

       FUTEX_WAKE
              Returns the number of waiters that were woken up.

       FUTEX_FD
              Returns the new file descriptor associated with the futex.

       FUTEX_REQUEUE
              Returns the number of waiters that were woken up.

       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.

       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.

       FUTEX_WAIT_BITSET
              Returns  0  if  the  caller was woken up.  See FUTEX_WAIT for how to interpret this
              correctly in practice.

       FUTEX_WAKE_BITSET
              Returns the number of waiters that were woken up.

       FUTEX_LOCK_PI
              Returns 0 if the futex was successfully locked.

       FUTEX_TRYLOCK_PI
              Returns 0 if the futex was successfully locked.

       FUTEX_UNLOCK_PI
              Returns 0 if the futex was successfully unlocked.

       FUTEX_CMP_REQUEUE_PI
              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 difference is
              the number of waiters requeued to the futex for the futex word at uaddr2.

       FUTEX_WAIT_REQUEUE_PI
              Returns 0 if the caller was successfully requeued to the futex for the  futex  word
              at uaddr2.

ERRORS

       EACCES No read access to the memory of a futex word.

       EAGAIN (FUTEX_WAIT,  FUTEX_WAIT_BITSET,  FUTEX_WAIT_REQUEUE_PI)  The  value  pointed to by
              uaddr was not equal to the expected value val at the time of the call.

              Note: on Linux, the symbolic names EAGAIN and EWOULDBLOCK (both of which appear  in
              different parts of the kernel futex code) have the same value.

       EAGAIN (FUTEX_CMP_REQUEUE,  FUTEX_CMP_REQUEUE_PI)  The  value  pointed  to by uaddr is not
              equal to the expected value val3.

       EAGAIN (FUTEX_LOCK_PI, FUTEX_TRYLOCK_PI, FUTEX_CMP_REQUEUE_PI) The futex owner  thread  ID
              of  uaddr  (for  FUTEX_CMP_REQUEUE_PI:  uaddr2)  is  about to exit, but has not yet
              handled the internal state cleanup.  Try again.

       EDEADLK
              (FUTEX_LOCK_PI, FUTEX_TRYLOCK_PI, FUTEX_CMP_REQUEUE_PI) The futex word at uaddr  is
              already locked by the caller.

       EDEADLK
              (FUTEX_CMP_REQUEUE_PI) While requeueing a waiter to the PI futex for the futex word
              at uaddr2, the kernel detected a deadlock.

       EFAULT A required pointer argument (i.e., uaddr, uaddr2, or timeout) did not  point  to  a
              valid user-space address.

       EINTR  A  FUTEX_WAIT  or  FUTEX_WAIT_BITSET  operation  was  interrupted  by a signal (see
              signal(7)).  In kernels before Linux 2.6.22, this error could also be returned  for
              on a spurious wakeup; since Linux 2.6.22, this no longer happens.

       EINVAL The  operation in futex_op is one of those that employs a timeout, but the supplied
              timeout argument was invalid (tv_sec was less than zero, or tv_nsec  was  not  less
              than 1,000,000,000).

       EINVAL The  operation  specified in futex_op employs one or both of the pointers uaddr and
              uaddr2, but one of these does not point to a valid object—that is, the  address  is
              not four-byte-aligned.

       EINVAL (FUTEX_WAIT_BITSET, FUTEX_WAKE_BITSET) The bit mask supplied in val3 is zero.

       EINVAL (FUTEX_CMP_REQUEUE_PI) uaddr equals uaddr2 (i.e., an attempt was made to requeue to
              the same futex).

       EINVAL (FUTEX_FD) The signal number supplied in val is invalid.

       EINVAL (FUTEX_WAKE, FUTEX_WAKE_OP,  FUTEX_WAKE_BITSET,  FUTEX_REQUEUE,  FUTEX_CMP_REQUEUE)
              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 on uaddr.

       EINVAL (FUTEX_LOCK_PI,  FUTEX_TRYLOCK_PI,  FUTEX_UNLOCK_PI)   The   kernel   detected   an
              inconsistency  between  the  user-space  state at uaddr and the kernel state.  This
              indicates either state corruption or that the kernel found a waiter on uaddr  which
              is waiting via FUTEX_WAIT or FUTEX_WAIT_BITSET.

       EINVAL (FUTEX_CMP_REQUEUE_PI)  The kernel detected an inconsistency between the user-space
              state at uaddr2 and the kernel state; that is, the kernel detected a  waiter  which
              waits via FUTEX_WAIT or FUTEX_WAIT_BITSET on uaddr2.

       EINVAL (FUTEX_CMP_REQUEUE_PI)  The kernel detected an inconsistency between the user-space
              state at uaddr and the kernel state; that is, the kernel detected  a  waiter  which
              waits via FUTEX_WAIT or FUTEX_WAIT_BITESET on uaddr.

       EINVAL (FUTEX_CMP_REQUEUE_PI)  The kernel detected an inconsistency between the user-space
              state at uaddr and the kernel state; that is, the kernel detected  a  waiter  which
              waits on uaddr via FUTEX_LOCK_PI (instead of FUTEX_WAIT_REQUEUE_PI).

       EINVAL (FUTEX_CMP_REQUEUE_PI)  An  attempt  was  made to requeue a waiter to a futex other
              than that specified by the matching FUTEX_WAIT_REQUEUE_PI call for that waiter.

       EINVAL (FUTEX_CMP_REQUEUE_PI) The val argument is not 1.

       EINVAL Invalid argument.

       ENOMEM (FUTEX_LOCK_PI,  FUTEX_TRYLOCK_PI,  FUTEX_CMP_REQUEUE_PI)  The  kernel  could   not
              allocate memory to hold state information.

       ENFILE (FUTEX_FD)  The  system-wide  limit  on  the  total  number  of open files has been
              reached.

       ENOSYS Invalid operation specified in futex_op.

       ENOSYS The FUTEX_CLOCK_REALTIME option was specified in  futex_op,  but  the  accompanying
              operation was neither FUTEX_WAIT_BITSET nor FUTEX_WAIT_REQUEUE_PI.

       ENOSYS (FUTEX_LOCK_PI,     FUTEX_TRYLOCK_PI,     FUTEX_UNLOCK_PI,    FUTEX_CMP_REQUEUE_PI,
              FUTEX_WAIT_REQUEUE_PI) A run-time  check  determined  that  the  operation  is  not
              available.   The  PI-futex  operations are not implemented on all architectures and
              are not supported on some CPU variants.

       EPERM  (FUTEX_LOCK_PI, FUTEX_TRYLOCK_PI, FUTEX_CMP_REQUEUE_PI) The caller is  not  allowed
              to  attach  itself  to  the  futex at uaddr (for FUTEX_CMP_REQUEUE_PI: the futex at
              uaddr2).  (This may be caused by a state corruption in user space.)

       EPERM  (FUTEX_UNLOCK_PI) The caller does not own the lock represented by the futex word.

       ESRCH  (FUTEX_LOCK_PI, FUTEX_TRYLOCK_PI, FUTEX_CMP_REQUEUE_PI) The thread ID in the  futex
              word at uaddr does not exist.

       ESRCH  (FUTEX_CMP_REQUEUE_PI) The thread ID in the futex word at uaddr2 does not exist.

       ETIMEDOUT
              The  operation  in  futex_op  employed  the  timeout  specified in timeout, and the
              timeout expired before the operation completed.

VERSIONS

       Futexes were first made available in a stable kernel release with Linux 2.6.0.

       Initial futex support was merged in Linux 2.5.7 but with different semantics from what was
       described  above.   A  four-argument system call with the semantics described in this page
       was introduced in Linux 2.5.40.  A fifth argument was added in Linux 2.5.70, and  a  sixth
       argument was added in Linux 2.6.7.

CONFORMING TO

       This system call is Linux-specific.

NOTES

       Glibc does not provide a wrapper for this system call; call it using syscall(2).

       Several higher-level programming abstractions are implemented via futexes, including POSIX
       semaphores and  various  POSIX  threads  synchronization  mechanisms  (mutexes,  condition
       variables, read-write locks, and barriers).

EXAMPLE

       The  program  below  demonstrates use of futexes in a program where a parent process and a
       child process use a  pair  of  futexes  located  inside  a  shared  anonymous  mapping  to
       synchronize  access  to  a  shared  resource:  the terminal.  The two processes each write
       nloops (a command-line argument that defaults to 5 if omitted) messages  to  the  terminal
       and  employ  a  synchronization  protocol  that  ensures  that  they  alternate in writing
       messages.  Upon running this program we see output such as the following:

           $ ./futex_demo
           Parent (18534) 0
           Child  (18535) 0
           Parent (18534) 1
           Child  (18535) 1
           Parent (18534) 2
           Child  (18535) 2
           Parent (18534) 3
           Child  (18535) 3
           Parent (18534) 4
           Child  (18535) 4

   Program source

       /* futex_demo.c

          Usage: futex_demo [nloops]
                           (Default: 5)

          Demonstrate the use of futexes in a program where parent and child
          use a pair of futexes located inside a shared anonymous mapping to
          synchronize access to a shared resource: the terminal. The two
          processes each write 'num-loops' messages to the terminal and employ
          a synchronization protocol that ensures that they alternate in
          writing messages.
       */
       #define _GNU_SOURCE
       #include <stdio.h>
       #include <errno.h>
       #include <stdlib.h>
       #include <unistd.h>
       #include <sys/wait.h>
       #include <sys/mman.h>
       #include <sys/syscall.h>
       #include <linux/futex.h>
       #include <sys/time.h>

       #define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \
                               } while (0)

       static int *futex1, *futex2, *iaddr;

       static int
       futex(int *uaddr, int futex_op, int val,
             const struct timespec *timeout, int *uaddr2, int val3)
       {
           return syscall(SYS_futex, uaddr, futex_op, val,
                          timeout, uaddr, val3);
       }

       /* Acquire the futex pointed to by 'futexp': wait for its value to
          become 1, and then set the value to 0. */

       static void
       fwait(int *futexp)
       {
           int s;

           /* __sync_bool_compare_and_swap(ptr, oldval, newval) is a gcc
              built-in function.  It atomically performs the equivalent of:

                  if (*ptr == oldval)
                      *ptr = newval;

              It returns true if the test yielded true and *ptr was updated.
              The alternative here would be to employ the equivalent atomic
              machine-language instructions.  For further information, see
              the GCC Manual. */

           while (1) {

               /* Is the futex available? */

               if (__sync_bool_compare_and_swap(futexp, 1, 0))
                   break;      /* Yes */

               /* Futex is not available; wait */

               s = futex(futexp, FUTEX_WAIT, 0, NULL, NULL, 0);
               if (s == -1 && errno != EAGAIN)
                   errExit("futex-FUTEX_WAIT");
           }
       }

       /* Release the futex pointed to by 'futexp': if the futex currently
          has the value 0, set its value to 1 and the wake any futex waiters,
          so that if the peer is blocked in fpost(), it can proceed. */

       static void
       fpost(int *futexp)
       {
           int s;

           /* __sync_bool_compare_and_swap() was described in comments above */

           if (__sync_bool_compare_and_swap(futexp, 0, 1)) {

               s = futex(futexp, FUTEX_WAKE, 1, NULL, NULL, 0);
               if (s  == -1)
                   errExit("futex-FUTEX_WAKE");
           }
       }

       int
       main(int argc, char *argv[])
       {
           pid_t childPid;
           int j, nloops;

           setbuf(stdout, NULL);

           nloops = (argc > 1) ? atoi(argv[1]) : 5;

           /* Create a shared anonymous mapping that will hold the futexes.
              Since the futexes are being shared between processes, we
              subsequently use the "shared" futex operations (i.e., not the
              ones suffixed "_PRIVATE") */

           iaddr = mmap(NULL, sizeof(int) * 2, PROT_READ | PROT_WRITE,
                       MAP_ANONYMOUS | MAP_SHARED, -1, 0);
           if (iaddr == MAP_FAILED)
               errExit("mmap");

           futex1 = &iaddr[0];
           futex2 = &iaddr[1];

           *futex1 = 0;        /* State: unavailable */
           *futex2 = 1;        /* State: available */

           /* Create a child process that inherits the shared anonymous
              mapping */

           childPid = fork();
           if (childPid == -1)
               errExit("fork");

           if (childPid == 0) {        /* Child */
               for (j = 0; j < nloops; j++) {
                   fwait(futex1);
                   printf("Child  (%ld) %d\n", (long) getpid(), j);
                   fpost(futex2);
               }

               exit(EXIT_SUCCESS);
           }

           /* Parent falls through to here */

           for (j = 0; j < nloops; j++) {
               fwait(futex2);
               printf("Parent (%ld) %d\n", (long) getpid(), j);
               fpost(futex1);
           }

           wait(NULL);

           exit(EXIT_SUCCESS);
       }

SEE ALSO

       get_robust_list(2), restart_syscall(2), pthread_mutexattr_getprotocol(3), futex(7),
       sched(7)

       The following kernel source files:

       * Documentation/pi-futex.txt

       * Documentation/futex-requeue-pi.txt

       * Documentation/locking/rt-mutex.txt

       * Documentation/locking/rt-mutex-design.txt

       * Documentation/robust-futex-ABI.txt

       Franke, H., Russell, R., and Kirwood, M., 2002.  Fuss, Futexes and Furwocks: Fast
       Userlevel Locking in Linux (from proceedings of the Ottawa Linux Symposium 2002),
       ⟨http://kernel.org/doc/ols/2002/ols2002-pages-479-495.pdf⟩

       Hart, D., 2009. A futex overview and update, ⟨http://lwn.net/Articles/360699/⟩

       Hart, D. and Guniguntala, D., 2009.  Requeue-PI: Making Glibc Condvars PI-Aware (from
       proceedings of the 2009 Real-Time Linux Workshop),
       ⟨http://lwn.net/images/conf/rtlws11/papers/proc/p10.pdf⟩

       Drepper, U., 2011. Futexes Are Tricky, ⟨http://www.akkadia.org/drepper/futex.pdf⟩

       Futex example library, futex-*.tar.bz2 at
       ⟨ftp://ftp.kernel.org/pub/linux/kernel/people/rusty/

COLOPHON

       This page is part of release 4.04 of the Linux man-pages project.  A description of the
       project, information about reporting bugs, and the latest version of this page, can be
       found at http://www.kernel.org/doc/man-pages/.