1 .\" Copyright (c) 2011 Ed Schouten <ed@FreeBSD.org>
2 .\" All rights reserved.
4 .\" Redistribution and use in source and binary forms, with or without
5 .\" modification, are permitted provided that the following conditions
7 .\" 1. Redistributions of source code must retain the above copyright
8 .\" notice, this list of conditions and the following disclaimer.
9 .\" 2. Redistributions in binary form must reproduce the above copyright
10 .\" notice, this list of conditions and the following disclaimer in the
11 .\" documentation and/or other materials provided with the distribution.
13 .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 .Nm atomic_compare_exchange_strong ,
35 .Nm atomic_compare_exchange_weak ,
36 .Nm atomic_fetch_add ,
37 .Nm atomic_fetch_and ,
39 .Nm atomic_fetch_sub ,
40 .Nm atomic_fetch_xor ,
41 .Nm atomic_is_lock_free
42 .Nd type-generic atomic operations
50 .Fn atomic_init "_Atomic(T) *object" "T value"
52 .Fn atomic_load "_Atomic(T) *object"
54 .Fn atomic_load_explicit "_Atomic(T) *object" "memory_order order"
56 .Fn atomic_store "_Atomic(T) *object" "T desired"
58 .Fn atomic_store_explicit "_Atomic(T) *object" "T desired" "memory_order order"
60 .Fn atomic_exchange "_Atomic(T) *object" "T desired"
62 .Fn atomic_exchange_explicit "_Atomic(T) *object" "T desired" "memory_order order"
64 .Fn atomic_compare_exchange_strong "_Atomic(T) *object" "T *expected" "T desired"
66 .Fn atomic_compare_exchange_strong_explicit "_Atomic(T) *object" "T *expected" "T desired" "memory_order success" "memory_order failure"
68 .Fn atomic_compare_exchange_weak "_Atomic(T) *object" "T *expected" "T desired"
70 .Fn atomic_compare_exchange_weak_explicit "_Atomic(T) *object" "T *expected" "T desired" "memory_order success" "memory_order failure"
72 .Fn atomic_fetch_add "_Atomic(T) *object" "T operand"
74 .Fn atomic_fetch_add_explicit "_Atomic(T) *object" "T operand" "memory_order order"
76 .Fn atomic_fetch_and "_Atomic(T) *object" "T operand"
78 .Fn atomic_fetch_and_explicit "_Atomic(T) *object" "T operand" "memory_order order"
80 .Fn atomic_fetch_or "_Atomic(T) *object" "T operand"
82 .Fn atomic_fetch_or_explicit "_Atomic(T) *object" "T operand" "memory_order order"
84 .Fn atomic_fetch_sub "_Atomic(T) *object" "T operand"
86 .Fn atomic_fetch_sub_explicit "_Atomic(T) *object" "T operand" "memory_order order"
88 .Fn atomic_fetch_xor "_Atomic(T) *object" "T operand"
90 .Fn atomic_fetch_xor_explicit "_Atomic(T) *object" "T operand" "memory_order order"
92 .Fn atomic_is_lock_free "const _Atomic(T) *object"
96 provides type-generic macros for atomic operations.
97 Atomic operations can be used by multithreaded programs to provide
98 shared variables between threads that in most cases may be modified
99 without acquiring locks.
101 Atomic variables are declared using the
104 These variables are not type-compatible with their non-atomic
106 Depending on the compiler used, atomic variables may be opaque and can
107 therefore only be influenced using the macros described.
111 macro initializes the atomic variable
115 Atomic variables can be initialized while being declared using
116 .Fn ATOMIC_VAR_INIT .
120 macro returns the value of atomic variable
124 macro sets the atomic variable
132 macro combines the behaviour of
136 It sets the atomic variable
140 and returns the original contents of the atomic variable.
143 .Fn atomic_compare_exchange_strong
146 value into atomic variable
148 only if the atomic variable is equal to its
151 Upon success, the macro returns
155 value is overwritten with the value of the atomic variable and
159 .Fn atomic_compare_exchange_weak
160 macro is identical to
161 .Fn atomic_compare_exchange_strong ,
162 but is allowed to fail even if atomic variable
174 and returns the original contents of the atomic variable.
180 operator to atomic variable
184 and stores the value into
186 while returning the original contents of the atomic variable.
192 operator to atomic variable
196 and stores the value into
198 while returning the original contents of the atomic variable.
202 macro subtracts the value
206 and returns the original contents of the atomic variable.
212 operator to atomic variable
216 and stores the value into
218 while returning the original contents of the atomic variable.
221 .Fn atomic_is_lock_free
222 macro returns whether atomic variable
224 uses locks when using atomic operations.
226 The atomic operations described previously are implemented in such a way
227 that they disallow both the compiler and the executing processor to
228 re-order any nearby memory operations across the atomic operation.
229 In certain cases this behaviour may cause suboptimal performance.
230 To mitigate this, every atomic operation has an
232 version that allows the re-ordering to be configured.
238 macros can have one of the following values.
239 .Bl -tag -width memory_order_relaxed
240 .It Dv memory_order_relaxed
241 No operation orders memory.
242 .It Dv memory_order_consume
243 Perform consume operation.
244 .It Dv memory_order_acquire
246 .It Dv memory_order_release
248 .It Dv memory_order_acq_rel
249 Acquire and release fence.
250 .It Dv memory_order_seq_cst
251 Sequentially consistent acquire and release fence.
254 The previously described macros are identical to the
259 .Dv memory_order_seq_cst .
261 These atomic operations are typically implemented by the compiler, as
262 they must be implemented type-generically and must often use special
263 hardware instructions.
264 As this interface has not been adopted by most compilers yet, the
266 header implements these macros on top of existing compiler intrinsics to
267 provide forward compatibility.
269 This means that certain aspects of the interface, such as support for
270 different barrier types may simply be ignored.
271 When using GCC, all atomic operations are executed as if they are using
272 .Dv memory_order_seq_cst .
274 Instead of using the atomic operations provided by this interface,
276 allows the atomic variables to be modified directly using built-in
278 This behaviour cannot be emulated for older compilers.
279 To prevent unintended non-atomic access to these variables, this header
280 file places the atomic variable in a structure when using an older
283 When using GCC on architectures on which it lacks support for built-in
284 atomic intrinsics, these macros may emit function calls to fallback
286 These fallback routines are only implemented for 32-bits and 64-bits
287 datatypes, if supported by the CPU.
292 These macros attempt to conform to
295 These macros appeared in
298 .An \&Ed Schouten Aq Mt ed@FreeBSD.org
299 .An David Chisnall Aq Mt theraven@FreeBSD.org