gcc: __sync Builtins
1
1 6.52 Legacy '__sync' Built-in Functions for Atomic Memory Access
1 ================================================================
1
1 The following built-in functions are intended to be compatible with
1 those described in the 'Intel Itanium Processor-specific Application
1 Binary Interface', section 7.4. As such, they depart from normal GCC
1 practice by not using the '__builtin_' prefix and also by being
1 overloaded so that they work on multiple types.
1
1 The definition given in the Intel documentation allows only for the use
1 of the types 'int', 'long', 'long long' or their unsigned counterparts.
1 GCC allows any scalar type that is 1, 2, 4 or 8 bytes in size other than
1 the C type '_Bool' or the C++ type 'bool'. Operations on pointer
1 arguments are performed as if the operands were of the 'uintptr_t' type.
1 That is, they are not scaled by the size of the type to which the
1 pointer points.
1
1 These functions are implemented in terms of the '__atomic' builtins
1 (⇒__atomic Builtins). They should not be used for new code which
1 should use the '__atomic' builtins instead.
1
1 Not all operations are supported by all target processors. If a
1 particular operation cannot be implemented on the target processor, a
1 warning is generated and a call to an external function is generated.
1 The external function carries the same name as the built-in version,
1 with an additional suffix '_N' where N is the size of the data type.
1
1 In most cases, these built-in functions are considered a "full
1 barrier". That is, no memory operand is moved across the operation,
1 either forward or backward. Further, instructions are issued as
1 necessary to prevent the processor from speculating loads across the
1 operation and from queuing stores after the operation.
1
1 All of the routines are described in the Intel documentation to take
1 "an optional list of variables protected by the memory barrier". It's
1 not clear what is meant by that; it could mean that _only_ the listed
1 variables are protected, or it could mean a list of additional variables
1 to be protected. The list is ignored by GCC which treats it as empty.
1 GCC interprets an empty list as meaning that all globally accessible
1 variables should be protected.
1
1 'TYPE __sync_fetch_and_add (TYPE *ptr, TYPE value, ...)'
1 'TYPE __sync_fetch_and_sub (TYPE *ptr, TYPE value, ...)'
1 'TYPE __sync_fetch_and_or (TYPE *ptr, TYPE value, ...)'
1 'TYPE __sync_fetch_and_and (TYPE *ptr, TYPE value, ...)'
1 'TYPE __sync_fetch_and_xor (TYPE *ptr, TYPE value, ...)'
1 'TYPE __sync_fetch_and_nand (TYPE *ptr, TYPE value, ...)'
1 These built-in functions perform the operation suggested by the
1 name, and returns the value that had previously been in memory.
1 That is, operations on integer operands have the following
1 semantics. Operations on pointer arguments are performed as if the
1 operands were of the 'uintptr_t' type. That is, they are not
1 scaled by the size of the type to which the pointer points.
1
1 { tmp = *ptr; *ptr OP= value; return tmp; }
1 { tmp = *ptr; *ptr = ~(tmp & value); return tmp; } // nand
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.
1
1 _Note:_ GCC 4.4 and later implement '__sync_fetch_and_nand' as
1 '*ptr = ~(tmp & value)' instead of '*ptr = ~tmp & value'.
1
1 'TYPE __sync_add_and_fetch (TYPE *ptr, TYPE value, ...)'
1 'TYPE __sync_sub_and_fetch (TYPE *ptr, TYPE value, ...)'
1 'TYPE __sync_or_and_fetch (TYPE *ptr, TYPE value, ...)'
1 'TYPE __sync_and_and_fetch (TYPE *ptr, TYPE value, ...)'
1 'TYPE __sync_xor_and_fetch (TYPE *ptr, TYPE value, ...)'
1 'TYPE __sync_nand_and_fetch (TYPE *ptr, TYPE value, ...)'
1 These built-in functions perform the operation suggested by the
1 name, and return the new value. That is, operations on integer
1 operands have the following semantics. Operations on pointer
1 operands are performed as if the operand's type were 'uintptr_t'.
1
1 { *ptr OP= value; return *ptr; }
1 { *ptr = ~(*ptr & value); return *ptr; } // nand
1
1 The same constraints on arguments apply as for the corresponding
1 '__sync_op_and_fetch' built-in functions.
1
1 _Note:_ GCC 4.4 and later implement '__sync_nand_and_fetch' as
1 '*ptr = ~(*ptr & value)' instead of '*ptr = ~*ptr & value'.
1
1 'bool __sync_bool_compare_and_swap (TYPE *ptr, TYPE oldval, TYPE newval, ...)'
1 'TYPE __sync_val_compare_and_swap (TYPE *ptr, TYPE oldval, TYPE newval, ...)'
1 These built-in functions perform an atomic compare and swap. That
1 is, if the current value of '*PTR' is OLDVAL, then write NEWVAL
1 into '*PTR'.
1
1 The "bool" version returns true if the comparison is successful and
1 NEWVAL is written. The "val" version returns the contents of
1 '*PTR' before the operation.
1
1 '__sync_synchronize (...)'
1 This built-in function issues a full memory barrier.
1
1 'TYPE __sync_lock_test_and_set (TYPE *ptr, TYPE value, ...)'
1 This built-in function, as described by Intel, is not a traditional
1 test-and-set operation, but rather an atomic exchange operation.
1 It writes VALUE into '*PTR', and returns the previous contents of
1 '*PTR'.
1
1 Many targets have only minimal support for such locks, and do not
1 support a full exchange operation. In this case, a target may
1 support reduced functionality here by which the _only_ valid value
1 to store is the immediate constant 1. The exact value actually
1 stored in '*PTR' is implementation defined.
1
1 This built-in function is not a full barrier, but rather an
1 "acquire barrier". This means that references after the operation
1 cannot move to (or be speculated to) before the operation, but
1 previous memory stores may not be globally visible yet, and
1 previous memory loads may not yet be satisfied.
1
1 'void __sync_lock_release (TYPE *ptr, ...)'
1 This built-in function releases the lock acquired by
1 '__sync_lock_test_and_set'. Normally this means writing the
1 constant 0 to '*PTR'.
1
1 This built-in function is not a full barrier, but rather a "release
1 barrier". This means that all previous memory stores are globally
1 visible, and all previous memory loads have been satisfied, but
1 following memory reads are not prevented from being speculated to
1 before the barrier.
1