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
36 .Nm atomic_compare_exchange_strong ,
37 .Nm atomic_compare_exchange_weak ,
38 .Nm atomic_fetch_add ,
39 .Nm atomic_fetch_and ,
41 .Nm atomic_fetch_sub ,
42 .Nm atomic_fetch_xor ,
43 .Nm atomic_is_lock_free
44 .Nd type-generic atomic operations
52 .Fn atomic_init "_Atomic(T) *object" "T value"
54 .Fn atomic_load "_Atomic(T) *object"
56 .Fn atomic_load_explicit "_Atomic(T) *object" "memory_order order"
58 .Fn atomic_store "_Atomic(T) *object" "T desired"
60 .Fn atomic_store_explicit "_Atomic(T) *object" "T desired" "memory_order order"
62 .Fn atomic_exchange "_Atomic(T) *object" "T desired"
64 .Fn atomic_exchange_explicit "_Atomic(T) *object" "T desired" "memory_order order"
66 .Fn atomic_compare_exchange_strong "_Atomic(T) *object" "T *expected" "T desired"
68 .Fn atomic_compare_exchange_strong_explicit "_Atomic(T) *object" "T *expected" "T desired" "memory_order success" "memory_order failure"
70 .Fn atomic_compare_exchange_weak "_Atomic(T) *object" "T *expected" "T desired"
72 .Fn atomic_compare_exchange_weak_explicit "_Atomic(T) *object" "T *expected" "T desired" "memory_order success" "memory_order failure"
74 .Fn atomic_fetch_add "_Atomic(T) *object" "T operand"
76 .Fn atomic_fetch_add_explicit "_Atomic(T) *object" "T operand" "memory_order order"
78 .Fn atomic_fetch_and "_Atomic(T) *object" "T operand"
80 .Fn atomic_fetch_and_explicit "_Atomic(T) *object" "T operand" "memory_order order"
82 .Fn atomic_fetch_or "_Atomic(T) *object" "T operand"
84 .Fn atomic_fetch_or_explicit "_Atomic(T) *object" "T operand" "memory_order order"
86 .Fn atomic_fetch_sub "_Atomic(T) *object" "T operand"
88 .Fn atomic_fetch_sub_explicit "_Atomic(T) *object" "T operand" "memory_order order"
90 .Fn atomic_fetch_xor "_Atomic(T) *object" "T operand"
92 .Fn atomic_fetch_xor_explicit "_Atomic(T) *object" "T operand" "memory_order order"
94 .Fn atomic_is_lock_free "const _Atomic(T) *object"
98 provides type-generic macros for atomic operations.
99 Atomic operations can be used by multithreaded programs to provide
100 shared variables between threads that in most cases may be modified
101 without acquiring locks.
103 Atomic variables are declared using the
106 These variables are not type-compatible with their non-atomic
108 Depending on the compiler used, atomic variables may be opaque and can
109 therefore only be influenced using the macros described.
113 macro initializes the atomic variable
117 Atomic variables can be initialized while being declared using
118 .Fn ATOMIC_VAR_INIT .
122 macro returns the value of atomic variable
126 macro sets the atomic variable
134 macro combines the behaviour of
138 It sets the atomic variable
142 and returns the original contents of the atomic variable.
145 .Fn atomic_compare_exchange_strong
148 value into atomic variable
150 only if the atomic variable is equal to its
153 Upon success, the macro returns
157 value is overwritten with the value of the atomic variable and
161 .Fn atomic_compare_exchange_weak
162 macro is identical to
163 .Fn atomic_compare_exchange_strong ,
164 but is allowed to fail even if atomic variable
176 and returns the original contents of the atomic variable.
182 operator to atomic variable
186 and stores the value into
188 while returning the original contents of the atomic variable.
194 operator to atomic variable
198 and stores the value into
200 while returning the original contents of the atomic variable.
204 macro subtracts the value
208 and returns the original contents of the atomic variable.
214 operator to atomic variable
218 and stores the value into
220 while returning the original contents of the atomic variable.
223 .Fn atomic_is_lock_free
224 macro returns whether atomic variable
226 uses locks when using atomic operations.
228 The atomic operations described previously are implemented in such a way
229 that they disallow both the compiler and the executing processor to
230 re-order any nearby memory operations across the atomic operation.
231 In certain cases this behaviour may cause suboptimal performance.
232 To mitigate this, every atomic operation has an
234 version that allows the re-ordering to be configured.
240 macros can have one of the following values.
241 .Bl -tag -width memory_order_relaxed
242 .It Dv memory_order_relaxed
243 No operation orders memory.
244 .It Dv memory_order_consume
245 Perform consume operation.
246 .It Dv memory_order_acquire
248 .It Dv memory_order_release
250 .It Dv memory_order_acq_rel
251 Acquire and release fence.
252 .It Dv memory_order_seq_cst
253 Sequentially consistent acquire and release fence.
256 The previously described macros are identical to the
261 .Dv memory_order_seq_cst .
263 These atomic operations are typically implemented by the compiler, as
264 they must be implemented type-generically and must often use special
265 hardware instructions.
266 As this interface has not been adopted by most compilers yet, the
268 header implements these macros on top of existing compiler intrinsics to
269 provide forward compatibility.
271 This means that certain aspects of the interface, such as support for
272 different barrier types may simply be ignored.
273 When using GCC, all atomic operations are executed as if they are using
274 .Dv memory_order_seq_cst .
276 Instead of using the atomic operations provided by this interface,
278 allows the atomic variables to be modified directly using built-in
280 This behaviour cannot be emulated for older compilers.
281 To prevent unintended non-atomic access to these variables, this header
282 file places the atomic variable in a structure when using an older
285 When using GCC on architectures on which it lacks support for built-in
286 atomic intrinsics, these macros may emit function calls to fallback
288 These fallback routines are only implemented for 32-bits and 64-bits
289 datatypes, if supported by the CPU.
294 These macros attempt to conform to
297 These macros appeared in
300 .An Ed Schouten Aq ed@FreeBSD.org ,
301 .An David Chisnall Aq theraven@FreeBSD.org