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