gcc: __atomic Builtins

1 
1 6.53 Built-in Functions for Memory Model Aware Atomic Operations
1 ================================================================
1 
1 The following built-in functions approximately match the requirements
1 for the C++11 memory model.  They are all identified by being prefixed
1 with '__atomic' and most are overloaded so that they work with multiple
1 types.
1 
1  These functions are intended to replace the legacy '__sync' builtins.
1 The main difference is that the memory order that is requested is a
1 parameter to the functions.  New code should always use the '__atomic'
1 builtins rather than the '__sync' builtins.
1 
1  Note that the '__atomic' builtins assume that programs will conform to
1 the C++11 memory model.  In particular, they assume that programs are
1 free of data races.  See the C++11 standard for detailed requirements.
1 
1  The '__atomic' builtins can be used with any integral scalar or pointer
1 type that is 1, 2, 4, or 8 bytes in length.  16-byte integral types are
1 also allowed if '__int128' (⇒__int128) is supported by the
1 architecture.
1 
1  The four non-arithmetic functions (load, store, exchange, and
1 compare_exchange) all have a generic version as well.  This generic
1 version works on any data type.  It uses the lock-free built-in function
1 if the specific data type size makes that possible; otherwise, an
1 external call is left to be resolved at run time.  This external call is
1 the same format with the addition of a 'size_t' parameter inserted as
1 the first parameter indicating the size of the object being pointed to.
1 All objects must be the same size.
1 
1  There are 6 different memory orders that can be specified.  These map
1 to the C++11 memory orders with the same names, see the C++11 standard
1 or the GCC wiki on atomic synchronization
1 (http://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync) for detailed
1 definitions.  Individual targets may also support additional memory
1 orders for use on specific architectures.  Refer to the target
1 documentation for details of these.
1 
1  An atomic operation can both constrain code motion and be mapped to
1 hardware instructions for synchronization between threads (e.g., a
1 fence).  To which extent this happens is controlled by the memory
1 orders, which are listed here in approximately ascending order of
1 strength.  The description of each memory order is only meant to roughly
1 illustrate the effects and is not a specification; see the C++11 memory
1 model for precise semantics.
1 
1 '__ATOMIC_RELAXED'
1      Implies no inter-thread ordering constraints.
1 '__ATOMIC_CONSUME'
1      This is currently implemented using the stronger '__ATOMIC_ACQUIRE'
1      memory order because of a deficiency in C++11's semantics for
1      'memory_order_consume'.
1 '__ATOMIC_ACQUIRE'
1      Creates an inter-thread happens-before constraint from the release
1      (or stronger) semantic store to this acquire load.  Can prevent
1      hoisting of code to before the operation.
1 '__ATOMIC_RELEASE'
1      Creates an inter-thread happens-before constraint to acquire (or
1      stronger) semantic loads that read from this release store.  Can
1      prevent sinking of code to after the operation.
1 '__ATOMIC_ACQ_REL'
1      Combines the effects of both '__ATOMIC_ACQUIRE' and
1      '__ATOMIC_RELEASE'.
1 '__ATOMIC_SEQ_CST'
1      Enforces total ordering with all other '__ATOMIC_SEQ_CST'
1      operations.
1 
1  Note that in the C++11 memory model, _fences_ (e.g.,
1 '__atomic_thread_fence') take effect in combination with other atomic
1 operations on specific memory locations (e.g., atomic loads); operations
1 on specific memory locations do not necessarily affect other operations
1 in the same way.
1 
1  Target architectures are encouraged to provide their own patterns for
1 each of the atomic built-in functions.  If no target is provided, the
1 original non-memory model set of '__sync' atomic built-in functions are
1 used, along with any required synchronization fences surrounding it in
1 order to achieve the proper behavior.  Execution in this case is subject
1 to the same restrictions as those built-in functions.
1 
1  If there is no pattern or mechanism to provide a lock-free instruction
1 sequence, a call is made to an external routine with the same parameters
1 to be resolved at run time.
1 
1  When implementing patterns for these built-in functions, the memory
1 order parameter can be ignored as long as the pattern implements the
1 most restrictive '__ATOMIC_SEQ_CST' memory order.  Any of the other
1 memory orders execute correctly with this memory order but they may not
1 execute as efficiently as they could with a more appropriate
1 implementation of the relaxed requirements.
1 
1  Note that the C++11 standard allows for the memory order parameter to
1 be determined at run time rather than at compile time.  These built-in
1 functions map any run-time value to '__ATOMIC_SEQ_CST' rather than
1 invoke a runtime library call or inline a switch statement.  This is
1 standard compliant, safe, and the simplest approach for now.
1 
1  The memory order parameter is a signed int, but only the lower 16 bits
1 are reserved for the memory order.  The remainder of the signed int is
1 reserved for target use and should be 0.  Use of the predefined atomic
1 values ensures proper usage.
1 
1  -- Built-in Function: TYPE __atomic_load_n (TYPE *ptr, int memorder)
1      This built-in function implements an atomic load operation.  It
1      returns the contents of '*PTR'.
1 
1      The valid memory order variants are '__ATOMIC_RELAXED',
1      '__ATOMIC_SEQ_CST', '__ATOMIC_ACQUIRE', and '__ATOMIC_CONSUME'.
1 
1  -- Built-in Function: void __atomic_load (TYPE *ptr, TYPE *ret, int
1           memorder)
1      This is the generic version of an atomic load.  It returns the
1      contents of '*PTR' in '*RET'.
1 
1  -- Built-in Function: void __atomic_store_n (TYPE *ptr, TYPE val, int
1           memorder)
1      This built-in function implements an atomic store operation.  It
1      writes 'VAL' into '*PTR'.
1 
1      The valid memory order variants are '__ATOMIC_RELAXED',
1      '__ATOMIC_SEQ_CST', and '__ATOMIC_RELEASE'.
1 
1  -- Built-in Function: void __atomic_store (TYPE *ptr, TYPE *val, int
1           memorder)
1      This is the generic version of an atomic store.  It stores the
1      value of '*VAL' into '*PTR'.
1 
1  -- Built-in Function: TYPE __atomic_exchange_n (TYPE *ptr, TYPE val,
1           int memorder)
1      This built-in function implements an atomic exchange operation.  It
1      writes VAL into '*PTR', and returns the previous contents of
1      '*PTR'.
1 
1      The valid memory order variants are '__ATOMIC_RELAXED',
1      '__ATOMIC_SEQ_CST', '__ATOMIC_ACQUIRE', '__ATOMIC_RELEASE', and
1      '__ATOMIC_ACQ_REL'.
1 
1  -- Built-in Function: void __atomic_exchange (TYPE *ptr, TYPE *val,
1           TYPE *ret, int memorder)
1      This is the generic version of an atomic exchange.  It stores the
1      contents of '*VAL' into '*PTR'.  The original value of '*PTR' is
1      copied into '*RET'.
1 
1  -- Built-in Function: bool __atomic_compare_exchange_n (TYPE *ptr, TYPE
1           *expected, TYPE desired, bool weak, int success_memorder, int
1           failure_memorder)
1      This built-in function implements an atomic compare and exchange
1      operation.  This compares the contents of '*PTR' with the contents
1      of '*EXPECTED'.  If equal, the operation is a _read-modify-write_
1      operation that writes DESIRED into '*PTR'.  If they are not equal,
1      the operation is a _read_ and the current contents of '*PTR' are
1      written into '*EXPECTED'.  WEAK is true for weak compare_exchange,
1      which may fail spuriously, and false for the strong variation,
1      which never fails spuriously.  Many targets only offer the strong
1      variation and ignore the parameter.  When in doubt, use the strong
1      variation.
1 
1      If DESIRED is written into '*PTR' then true is returned and memory
1      is affected according to the memory order specified by
1      SUCCESS_MEMORDER.  There are no restrictions on what memory order
1      can be used here.
1 
1      Otherwise, false is returned and memory is affected according to
1      FAILURE_MEMORDER.  This memory order cannot be '__ATOMIC_RELEASE'
1      nor '__ATOMIC_ACQ_REL'.  It also cannot be a stronger order than
1      that specified by SUCCESS_MEMORDER.
1 
1  -- Built-in Function: bool __atomic_compare_exchange (TYPE *ptr, TYPE
1           *expected, TYPE *desired, bool weak, int success_memorder, int
1           failure_memorder)
1      This built-in function implements the generic version of
1      '__atomic_compare_exchange'.  The function is virtually identical
1      to '__atomic_compare_exchange_n', except the desired value is also
1      a pointer.
1 
1  -- Built-in Function: TYPE __atomic_add_fetch (TYPE *ptr, TYPE val, int
1           memorder)
1  -- Built-in Function: TYPE __atomic_sub_fetch (TYPE *ptr, TYPE val, int
1           memorder)
1  -- Built-in Function: TYPE __atomic_and_fetch (TYPE *ptr, TYPE val, int
1           memorder)
1  -- Built-in Function: TYPE __atomic_xor_fetch (TYPE *ptr, TYPE val, int
1           memorder)
1  -- Built-in Function: TYPE __atomic_or_fetch (TYPE *ptr, TYPE val, int
1           memorder)
1  -- Built-in Function: TYPE __atomic_nand_fetch (TYPE *ptr, TYPE val,
1           int memorder)
1      These built-in functions perform the operation suggested by the
1      name, and return the result of the operation.  Operations on
1      pointer arguments are performed as if the operands were of the
1      'uintptr_t' type.  That is, they are not scaled by the size of the
1      type to which the pointer points.
1 
1           { *ptr OP= val; return *ptr; }
1 
1      The object pointed to by the first argument must be of integer or
1      pointer type.  It must not be a boolean type.  All memory orders
1      are valid.
1 
1  -- Built-in Function: TYPE __atomic_fetch_add (TYPE *ptr, TYPE val, int
1           memorder)
1  -- Built-in Function: TYPE __atomic_fetch_sub (TYPE *ptr, TYPE val, int
1           memorder)
1  -- Built-in Function: TYPE __atomic_fetch_and (TYPE *ptr, TYPE val, int
1           memorder)
1  -- Built-in Function: TYPE __atomic_fetch_xor (TYPE *ptr, TYPE val, int
1           memorder)
1  -- Built-in Function: TYPE __atomic_fetch_or (TYPE *ptr, TYPE val, int
1           memorder)
1  -- Built-in Function: TYPE __atomic_fetch_nand (TYPE *ptr, TYPE val,
1           int memorder)
1      These built-in functions perform the operation suggested by the
1      name, and return the value that had previously been in '*PTR'.
1      Operations on pointer arguments are performed as if the operands
1      were of the 'uintptr_t' type.  That is, they are not scaled by the
1      size of the type to which the pointer points.
1 
1           { tmp = *ptr; *ptr OP= val; return tmp; }
1 
1      The same constraints on arguments apply as for the corresponding
1      '__atomic_op_fetch' built-in functions.  All memory orders are
1      valid.
1 
1  -- Built-in Function: bool __atomic_test_and_set (void *ptr, int
1           memorder)
1 
1      This built-in function performs an atomic test-and-set operation on
1      the byte at '*PTR'.  The byte is set to some implementation defined
1      nonzero "set" value and the return value is 'true' if and only if
1      the previous contents were "set".  It should be only used for
1      operands of type 'bool' or 'char'.  For other types only part of
1      the value may be set.
1 
1      All memory orders are valid.
1 
1  -- Built-in Function: void __atomic_clear (bool *ptr, int memorder)
1 
1      This built-in function performs an atomic clear operation on
1      '*PTR'.  After the operation, '*PTR' contains 0.  It should be only
1      used for operands of type 'bool' or 'char' and in conjunction with
1      '__atomic_test_and_set'.  For other types it may only clear
1      partially.  If the type is not 'bool' prefer using
1      '__atomic_store'.
1 
1      The valid memory order variants are '__ATOMIC_RELAXED',
1      '__ATOMIC_SEQ_CST', and '__ATOMIC_RELEASE'.
1 
1  -- Built-in Function: void __atomic_thread_fence (int memorder)
1 
1      This built-in function acts as a synchronization fence between
1      threads based on the specified memory order.
1 
1      All memory orders are valid.
1 
1  -- Built-in Function: void __atomic_signal_fence (int memorder)
1 
1      This built-in function acts as a synchronization fence between a
1      thread and signal handlers based in the same thread.
1 
1      All memory orders are valid.
1 
1  -- Built-in Function: bool __atomic_always_lock_free (size_t size, void
1           *ptr)
1 
1      This built-in function returns true if objects of SIZE bytes always
1      generate lock-free atomic instructions for the target architecture.
1      SIZE must resolve to a compile-time constant and the result also
1      resolves to a compile-time constant.
1 
1      PTR is an optional pointer to the object that may be used to
1      determine alignment.  A value of 0 indicates typical alignment
1      should be used.  The compiler may also ignore this parameter.
1 
1           if (__atomic_always_lock_free (sizeof (long long), 0))
1 
1  -- Built-in Function: bool __atomic_is_lock_free (size_t size, void
1           *ptr)
1 
1      This built-in function returns true if objects of SIZE bytes always
1      generate lock-free atomic instructions for the target architecture.
1      If the built-in function is not known to be lock-free, a call is
1      made to a runtime routine named '__atomic_is_lock_free'.
1 
1      PTR is an optional pointer to the object that may be used to
1      determine alignment.  A value of 0 indicates typical alignment
1      should be used.  The compiler may also ignore this parameter.
1