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