This patch is simply the documentation for extend.texi which adds a
section about the new memory model __sync_mem routines. I've supplied
the .info output since its easier to read, followed by the patch
OK for the branch?
Andrew
6.52 Built-in functions for memory model aware atomic operations.
=================================================================
The following builtins approximately match the requirements for
C++1x memory model. Many are similar to the "__sync" prefixed builtins,
but all also have a memory model parameter. These are all identified
by being prefixed with "__sync_mem", and most are overloaded such that
they work with multiple types.
GCC will allow any integral scalar or pointer type that is 1, 2,
4, or 8 bytes in length. 16 bytes integral types are also allowed if
__int128_t is supported by the architecture.
Target architectures are encouraged to provide their own patterns
for each of these builtins. If no target is provided, the original
non-memory model set of "__sync" atomic builtins will be utilized,
along with any required synchronization fences surrounding it in order
to achieve the proper behaviour. Execution in this case is subject to
the same restrictions as those builtins.
There are 6 different memory models which can be specified. These
map to the same names in the C++1x standard. Refer there or to the GCC
wiki on atomics for more detailed definitions. These memory models
integrate both barriers to code motion as well as synchronization
requirements with other threads. These are listed in approximately
ascending order of strength.
`__SYNC_MEM_RELAXED'
No barrier or synchronization.
`__SYNC_MEM_CONSUME'
Data dependency only for both barrier and synchronization
with another thread.
`__SYNC_MEM_ACQUIRE'
Barrier to hoisting of code and synchronizes with stores from
another thread.
`__SYNC_MEM_RELEASE'
Barrier to sinking of code and synchronizes with loads from
another thread.
`__SYNC_MEM_ACQ_REL'
Full barrier in both directions and synchronizes with loads
and stores in another thread.
`__SYNC_MEM_SEQ_CST'
Full barrier in both directions and synchronizes all loads
and stores in all threads.
When implementing patterns for these builtins, the memory model
parameter can be ignored as long as the pattern implements the most
restrictive __SYNC_MEM_SEQ_CST model. Any of the other memory models
will execute correctly with this memory model but they may not execute
as efficiently as they could with a more appropriate implemention of
the relaxed requirements.
`TYPE __sync_mem_load (TYPE *ptr, int memmodel)'
This builtin implements an atomic load operation. It returns the
contents of `*PTR'.
The valid memory model variants are __SYNC_MEM_RELAXED,
__SYNC_MEM_SEQ_CST, __SYNC_MEM_ACQUIRE, and __SYNC_MEM_CONSUME.
`void __sync_mem_store (TYPE *ptr, TYPE val, int memmodel)'
This builtin implements an atomic store operation. It writes `VAL'
into `*PTR'.
The valid memory model variants are __SYNC_MEM_RELAXED,
__SYNC_MEM_SEQ_CST, and __SYNC_MEM_RELEASE.
`TYPE __sync_mem_exchange (TYPE *ptr, TYPE val, int memmodel)'
This builtin implements an atomic exchange operation. It writes
VAL into `*PTR', and returns the previous contents of `*PTR'.
The valid memory model variants are __SYNC_MEM_RELAXED,
__SYNC_MEM_SEQ_CST, __SYNC_MEM_ACQUIRE, __SYNC_MEM_RELEASE, and
__SYNC_MEM_ACQ_REL.
`bool __sync_mem_compare_exchange (TYPE *ptr, TYPE *expected, TYPE desired, int
success_memmodel, int failure_memmodel)'
This builtin implements an atomic compare_exchange operation.
This compares the contents of `*PTR' with the contents of
`*EXPECTED' and if equal, writes DESIRED into `*PTR'. If they are
not equal, the current contents of `*PTR' is written into
`*EXPECTED'.
True is returned if `*DESIRED' is written into `*PTR' and the
execution is considered to conform to the memory model specified by
SUCCESS_MEMMODEL. There are no restrictions on what memory model
can be used here.
False is returned otherwise, and the execution is considered to
conform to FAILURE_MEMMODEL. This memory model cannot be
__SYNC_MEM_RELEASE nor __SYNC_MEM_ACQ_REL. It also cannot be a
stronger model than that specified by SUCCESS_MEMMODEL.
`TYPE __sync_mem_fetch_add (TYPE *ptr, TYPE val, int memmodel)'
`TYPE __sync_mem_fetch_sub (TYPE *ptr, TYPE val, int memmodel)'
`TYPE __sync_mem_fetch_and (TYPE *ptr, TYPE val, int memmodel)'
`TYPE __sync_mem_fetch_xor (TYPE *ptr, TYPE val, int memmodel)'
`TYPE __sync_mem_fetch_or (TYPE *ptr, TYPE val, int memmodel)'
These builtins perform the operation suggested by the name, and
return the value that had previously been in *ptr . That is,
{ tmp = *ptr; *ptr OP= val; return tmp; }
All memory models are valid.
`bool __sync_mem_flag_test_and_set (char *ptr, int memmodel)'
This builtin performs a test and set operation. The contents of
`*PTR' will be set to true, and the previous value returned.
All memory orders are valid.
`void __sync_mem_flag_clear (char *ptr, int memmodel)'
This builtin performs a clear operation. The contents of `*PTR'
will be set to false.
The memory order cannot be __SYNC_MEM_ACQUIRE or
__SYNC_MEM_ACQ_REL.
`void __sync_mem_thread_fence (int memmodel)'
This builtin acts as a synchronization fence between threads based
on the specified memory model.
All memory orders are valid.
`void __sync_mem_signal_fence (int memmodel)'
This builtin acts as a synchronization fence between a thread and
signal handlers based in the same thread.
All memory orders are valid.
* doc/extend.texi (__sync_mem_*) : Document all the atomic builtin
functions which deal with memory models.
Index: extend.texi
===================================================================
*** extend.texi (revision 175331)
--- extend.texi (working copy)
*************** This means that all previous memory stor
*** 6729,6750 ****
previous memory loads have been satisfied, but following memory reads
are not prevented from being speculated to before the barrier.
! @item @var{type} __sync_mem_exchange (@var{type} *ptr, @var{type} value, int
memmodel, ...)
@findex __sync_mem_exchange
! This builtin implements an atomic exchange operation within the
! constraints of a memory model. It writes @var{value} into
! @code{*@var{ptr}}, and returns the previous contents of
! @code{*@var{ptr}}.
! The valid memory model variants for this builtin are
__SYNC_MEM_RELAXED, __SYNC_MEM_SEQ_CST, __SYNC_MEM_ACQUIRE,
! __SYNC_MEM_RELEASE, and __SYNC_MEM_ACQ_REL. The target pattern is responsible
! for issuing the different synchronization instructions. It should default to
! the more restrictive memory model, the sequentially consistent model. If
! nothing is implemented for the target, the compiler will implement it by
! calling the __sync_lock_test_and_set builtin. If the memory model is more
! restrictive than memory_order_acquire, a memory barrier is emitted before
! the instruction.
@end table
--- 6729,6871 ----
previous memory loads have been satisfied, but following memory reads
are not prevented from being speculated to before the barrier.
! @section Built-in functions for memory model aware atomic operations.
!
! The following builtins approximately match the requirements for
! C++1x memory model. Many are similar to the ``__sync'' prefixed builtins, but
! all also have a memory model parameter. These are all identified by being
! prefixed with ``__sync_mem'', and most are overloaded such that they work
! with multiple types.
!
! GCC will allow any integral scalar or pointer type that is 1, 2, 4, or 8 bytes
! in length. 16 bytes integral types are also allowed if __int128_t is supported
! by the architecture.
!
! Target architectures are encouraged to provide their own patterns for each of
! these builtins. If no target is provided, the original non-memory model
! set of ``__sync'' atomic builtins will be utilized, along with any required
! synchronization fences surrounding it in order to achieve the proper
behaviour.
! Execution in this case is subject to the same restrictions as those builtins.
!
! There are 6 different memory models which can be specified. These map to the
! same names in the C++1x standard. Refer there or to the GCC wiki on atomics
for
! more detailed definitions. These memory models integrate both barriers to
! code motion as well as synchronization requirements with other threads. These
! are listed in approximately ascending order of strength.
!
! @table @code
! @item __SYNC_MEM_RELAXED
! No barrier or synchronization.
! @item __SYNC_MEM_CONSUME
! Data dependency only for both barrier and synchronization with another thread.
! @item __SYNC_MEM_ACQUIRE
! Barrier to hoisting of code and synchronizes with stores from another thread.
! @item __SYNC_MEM_RELEASE
! Barrier to sinking of code and synchronizes with loads from another thread.
! @item __SYNC_MEM_ACQ_REL
! Full barrier in both directions and synchronizes with loads and stores in
! another thread.
! @item __SYNC_MEM_SEQ_CST
! Full barrier in both directions and synchronizes all loads and stores in all
! threads.
! @end table
!
! When implementing patterns for these builtins, the memory model parameter can
! be ignored as long as the pattern implements the most restrictive
__SYNC_MEM_SEQ_CST model. Any of the other memory models will execute correctly
with this
! memory model but they may not execute as efficiently as they could with a more
! appropriate implemention of the relaxed requirements.
!
! @item @var{type} __sync_mem_load (@var{type} *ptr, int memmodel)
! @findex __sync_mem_load
! This builtin implements an atomic load operation. It returns the contents
! of @code{*@var{ptr}}.
!
! The valid memory model variants are
! __SYNC_MEM_RELAXED, __SYNC_MEM_SEQ_CST, __SYNC_MEM_ACQUIRE, and
! __SYNC_MEM_CONSUME.
!
! @item void __sync_mem_store (@var{type} *ptr, @var{type} val, int memmodel)
! @findex __sync_mem_load
! This builtin implements an atomic store operation. It writes @code{@var{val}}
! into @code{*@var{ptr}}.
!
! The valid memory model variants are
! __SYNC_MEM_RELAXED, __SYNC_MEM_SEQ_CST, and __SYNC_MEM_RELEASE.
!
! @item @var{type} __sync_mem_exchange (@var{type} *ptr, @var{type} val, int
memmodel)
@findex __sync_mem_exchange
! This builtin implements an atomic exchange operation. It writes @var{val}
! into @code{*@var{ptr}}, and returns the previous contents of
@code{*@var{ptr}}.
! The valid memory model variants are
__SYNC_MEM_RELAXED, __SYNC_MEM_SEQ_CST, __SYNC_MEM_ACQUIRE,
! __SYNC_MEM_RELEASE, and __SYNC_MEM_ACQ_REL.
!
! @item bool __sync_mem_compare_exchange (@var{type} *ptr, @var{type}
*expected, @var{type} desired, int success_memmodel, int failure_memmodel)
! @findex __sync_mem_compare_exchange
! This builtin implements an atomic compare_exchange operation. This compares
the
! contents of @code{*@var{ptr}} with the contents of @code{*@var{expected}} and
if
! equal, writes @var{desired} into @code{*@var{ptr}}. If they are not equal,
the
! current contents of @code{*@var{ptr}} is written into @code{*@var{expected}}.
!
! True is returned if @code{*@var{desired}} is written into @code{*@var{ptr}}
and
! the execution is considered to conform to the memory model specified by
! @var{success_memmodel}. There are no restrictions on what memory model can be
! used here.
!
! False is returned otherwise, and the execution is considered to conform to
! @var{failure_memmodel}. This memory model cannot be __SYNC_MEM_RELEASE nor
! __SYNC_MEM_ACQ_REL. It also cannot be a stronger model than that specified
! by @var{success_memmodel}.
!
! @item @var{type} __sync_mem_fetch_add (@var{type} *ptr, @var{type} val, int
memmodel)
! @itemx @var{type} __sync_mem_fetch_sub (@var{type} *ptr, @var{type} val, int
memmodel)
! @itemx @var{type} __sync_mem_fetch_and (@var{type} *ptr, @var{type} val, int
memmodel)
! @itemx @var{type} __sync_mem_fetch_xor (@var{type} *ptr, @var{type} val, int
memmodel)
! @itemx @var{type} __sync_mem_fetch_or (@var{type} *ptr, @var{type} val, int
memmodel)
! @findex __sync_mem_fetch_add
! @findex __sync_mem_fetch_sub
! @findex __sync_mem_fetch_and
! @findex __sync_mem_fetch_xor
! @findex __sync_mem_fetch_or
! These builtins perform the operation suggested by the name, and return the
value
! that had previously been in *ptr . That is,
!
! @smallexample
! @{ tmp = *ptr; *ptr @var{op}= val; return tmp; @}
! @end smallexample
!
! All memory models are valid.
!
! @item bool __sync_mem_flag_test_and_set (char *ptr, int memmodel)
! @findex __sync_mem_flag_test_and_set
!
! This builtin performs a test and set operation. The contents of
@code{*@var{ptr}} will be set to true, and the previous value returned.
!
! All memory orders are valid.
!
! @item void __sync_mem_flag_clear (char *ptr, int memmodel)
! @findex __sync_mem_flag_clear
!
! This builtin performs a clear operation. The contents of @code{*@var{ptr}}
will be set to false.
!
! The memory order cannot be __SYNC_MEM_ACQUIRE or __SYNC_MEM_ACQ_REL.
!
! @item void __sync_mem_thread_fence (int memmodel)
! @findex __sync_mem_thread_fence
!
! This builtin acts as a synchronization fence between threads based on the
! specified memory model.
!
! All memory orders are valid.
!
! @item void __sync_mem_signal_fence (int memmodel)
! @findex __sync_mem_signal_fence
!
! This builtin acts as a synchronization fence between a thread and signal
! handlers based in the same thread.
!
! All memory orders are valid.
@end table