Movatterモバイル変換


[0]ホーム

URL:


Next: ,Previous: Offsetof,Up: C Extensions


5.47 Built-in functions for atomic memory access

The following builtins are intended to be compatible with those describedin theIntel Itanium Processor-specific Application Binary Interface,section 7.4. As such, they depart from the normal GCC practice of usingthe “__builtin_” prefix, and further that they are overloaded such thatthey work on multiple types.

The definition given in the Intel documentation allows only for the use ofthe typesint,long,long long as well as their unsignedcounterparts. GCC will allow any integral scalar or pointer type that is1, 2, 4 or 8 bytes in length.

Not all operations are supported by all target processors. If a particularoperation cannot be implemented on the target processor, a warning will begenerated and a call an external function will be generated. The externalfunction will carry the same name as the builtin, with an additional suffix`_n' wheren is the size of the data type.

In most cases, these builtins are considered afull barrier. That is,no memory operand will be moved across the operation, either forward orbackward. Further, instructions will be issued as necessary to prevent theprocessor from speculating loads across the operation and from queuing storesafter the operation.

All of the routines are are described in the Intel documentation to take“an optional list of variables protected by the memory barrier”. It'snot clear what is meant by that; it could mean thatonly thefollowing variables are protected, or it could mean that these variablesshould in addition be protected. At present GCC ignores this list andprotects all variables which are globally accessible. If in the futurewe make some use of this list, an empty list will continue to mean allglobally accessible variables.

type __sync_fetch_and_add (type *ptr,type value, ...)
type __sync_fetch_and_sub (type *ptr,type value, ...)
type __sync_fetch_and_or (type *ptr,type value, ...)
type __sync_fetch_and_and (type *ptr,type value, ...)
type __sync_fetch_and_xor (type *ptr,type value, ...)
type __sync_fetch_and_nand (type *ptr,type value, ...)
These builtins perform the operation suggested by the name, andreturns the value that had previously been in memory. That is,
          { tmp = *ptr; *ptrop= value; return tmp; }          { tmp = *ptr; *ptr = ~tmp & value; return tmp; }   // nand

type __sync_add_and_fetch (type *ptr,type value, ...)
type __sync_sub_and_fetch (type *ptr,type value, ...)
type __sync_or_and_fetch (type *ptr,type value, ...)
type __sync_and_and_fetch (type *ptr,type value, ...)
type __sync_xor_and_fetch (type *ptr,type value, ...)
type __sync_nand_and_fetch (type *ptr,type value, ...)
These builtins perform the operation suggested by the name, andreturn the new value. That is,
          { *ptrop= value; return *ptr; }          { *ptr = ~*ptr & value; return *ptr; }   // nand

bool __sync_bool_compare_and_swap (type *ptr,type oldvaltype newval, ...)
type __sync_val_compare_and_swap (type *ptr,type oldvaltype newval, ...)
These builtins perform an atomic compare and swap. That is, if the currentvalue of*ptr isoldval, then writenewval into*ptr.

The “bool” version returns true if the comparison is successful andnewval was written. The “val” version returns the contentsof*ptr before the operation.

__sync_synchronize (...)
This builtin issues a full memory barrier.
type __sync_lock_test_and_set (type *ptr,type value, ...)
This builtin, as described by Intel, is not a traditional test-and-setoperation, but rather an atomic exchange operation. It writesvalueinto*ptr, and returns the previous contents of*ptr.

Many targets have only minimal support for such locks, and do not supporta full exchange operation. In this case, a target may support reducedfunctionality here by which theonly valid value to store is theimmediate constant 1. The exact value actually stored in*ptris implementation defined.

This builtin is not a full barrier, but rather anacquire barrier. This means that references after the builtin cannot move to (or bespeculated to) before the builtin, but previous memory stores may notbe globally visible yet, and previous memory loads may not yet besatisfied.

void __sync_lock_release (type *ptr, ...)
This builtin releases the lock acquired by__sync_lock_test_and_set. Normally this means writing the constant 0 to*ptr.

This builtin is not a full barrier, but rather arelease barrier. This means that all previous memory stores are globally visible, and allprevious memory loads have been satisfied, but following memory readsare not prevented from being speculated to before the barrier.


[8]ページ先頭

©2009-2025 Movatter.jp