xref: /freebsd/share/man/man3/ATOMIC_VAR_INIT.3 (revision 98e0ffaefb0f241cda3a72395d3be04192ae0d47)
1.\" Copyright (c) 2011 Ed Schouten <ed@FreeBSD.org>
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
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.
12.\"
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
23.\" SUCH DAMAGE.
24.\"
25.\" $FreeBSD$
26.\"
27.Dd December 27, 2011
28.Dt ATOMIC_VAR_INIT 3
29.Os
30.Sh NAME
31.Nm ATOMIC_VAR_INIT ,
32.Nm atomic_init ,
33.Nm atomic_load ,
34.Nm atomic_store ,
35.Nm atomic_exchange ,
36.Nm atomic_compare_exchange_strong ,
37.Nm atomic_compare_exchange_weak ,
38.Nm atomic_fetch_add ,
39.Nm atomic_fetch_and ,
40.Nm atomic_fetch_or ,
41.Nm atomic_fetch_sub ,
42.Nm atomic_fetch_xor ,
43.Nm atomic_is_lock_free
44.Nd type-generic atomic operations
45.Sh SYNOPSIS
46.In stdatomic.h
47.Pp
48_Atomic(T)
49.Fa v
50= ATOMIC_VAR_INIT(c);
51.Ft void
52.Fn atomic_init "_Atomic(T) *object" "T value"
53.Ft T
54.Fn atomic_load "_Atomic(T) *object"
55.Ft T
56.Fn atomic_load_explicit "_Atomic(T) *object" "memory_order order"
57.Ft void
58.Fn atomic_store "_Atomic(T) *object" "T desired"
59.Ft void
60.Fn atomic_store_explicit "_Atomic(T) *object" "T desired" "memory_order order"
61.Ft T
62.Fn atomic_exchange "_Atomic(T) *object" "T desired"
63.Ft T
64.Fn atomic_exchange_explicit "_Atomic(T) *object" "T desired" "memory_order order"
65.Ft _Bool
66.Fn atomic_compare_exchange_strong "_Atomic(T) *object" "T *expected" "T desired"
67.Ft _Bool
68.Fn atomic_compare_exchange_strong_explicit "_Atomic(T) *object" "T *expected" "T desired" "memory_order success" "memory_order failure"
69.Ft _Bool
70.Fn atomic_compare_exchange_weak "_Atomic(T) *object" "T *expected" "T desired"
71.Ft _Bool
72.Fn atomic_compare_exchange_weak_explicit "_Atomic(T) *object" "T *expected" "T desired" "memory_order success" "memory_order failure"
73.Ft T
74.Fn atomic_fetch_add "_Atomic(T) *object" "T operand"
75.Ft T
76.Fn atomic_fetch_add_explicit "_Atomic(T) *object" "T operand" "memory_order order"
77.Ft T
78.Fn atomic_fetch_and "_Atomic(T) *object" "T operand"
79.Ft T
80.Fn atomic_fetch_and_explicit "_Atomic(T) *object" "T operand" "memory_order order"
81.Ft T
82.Fn atomic_fetch_or "_Atomic(T) *object" "T operand"
83.Ft T
84.Fn atomic_fetch_or_explicit "_Atomic(T) *object" "T operand" "memory_order order"
85.Ft T
86.Fn atomic_fetch_sub "_Atomic(T) *object" "T operand"
87.Ft T
88.Fn atomic_fetch_sub_explicit "_Atomic(T) *object" "T operand" "memory_order order"
89.Ft T
90.Fn atomic_fetch_xor "_Atomic(T) *object" "T operand"
91.Ft T
92.Fn atomic_fetch_xor_explicit "_Atomic(T) *object" "T operand" "memory_order order"
93.Ft _Bool
94.Fn atomic_is_lock_free "const _Atomic(T) *object"
95.Sh DESCRIPTION
96The header
97.In stdatomic.h
98provides type-generic macros for atomic operations.
99Atomic operations can be used by multithreaded programs to provide
100shared variables between threads that in most cases may be modified
101without acquiring locks.
102.Pp
103Atomic variables are declared using the
104.Fn _Atomic
105type specifier.
106These variables are not type-compatible with their non-atomic
107counterparts.
108Depending on the compiler used, atomic variables may be opaque and can
109therefore only be influenced using the macros described.
110.Pp
111The
112.Fn atomic_init
113macro initializes the atomic variable
114.Fa object
115with a
116.Fa value .
117Atomic variables can be initialized while being declared using
118.Fn ATOMIC_VAR_INIT .
119.Pp
120The
121.Fn atomic_load
122macro returns the value of atomic variable
123.Fa object .
124The
125.Fn atomic_store
126macro sets the atomic variable
127.Fa object
128to its
129.Fa desired
130value.
131.Pp
132The
133.Fn atomic_exchange
134macro combines the behaviour of
135.Fn atomic_load
136and
137.Fn atomic_store .
138It sets the atomic variable
139.Fa object
140to its desired
141.Fa value
142and returns the original contents of the atomic variable.
143.Pp
144The
145.Fn atomic_compare_exchange_strong
146macro stores a
147.Fa desired
148value into atomic variable
149.Fa object ,
150only if the atomic variable is equal to its
151.Fa expected
152value.
153Upon success, the macro returns
154.Dv true .
155Upon failure, the
156.Fa desired
157value is overwritten with the value of the atomic variable and
158.Dv false
159is returned.
160The
161.Fn atomic_compare_exchange_weak
162macro is identical to
163.Fn atomic_compare_exchange_strong ,
164but is allowed to fail even if atomic variable
165.Fa object
166is equal to its
167.Fa expected
168value.
169.Pp
170The
171.Fn atomic_fetch_add
172macro adds the value
173.Fa operand
174to atomic variable
175.Fa object
176and returns the original contents of the atomic variable.
177.Pp
178The
179.Fn atomic_fetch_and
180macro applies the
181.Em and
182operator to atomic variable
183.Fa object
184and
185.Fa operand
186and stores the value into
187.Fa object ,
188while returning the original contents of the atomic variable.
189.Pp
190The
191.Fn atomic_fetch_or
192macro applies the
193.Em or
194operator to atomic variable
195.Fa object
196and
197.Fa operand
198and stores the value into
199.Fa object ,
200while returning the original contents of the atomic variable.
201.Pp
202The
203.Fn atomic_fetch_sub
204macro subtracts the value
205.Fa operand
206from atomic variable
207.Fa object
208and returns the original contents of the atomic variable.
209.Pp
210The
211.Fn atomic_fetch_xor
212macro applies the
213.Em xor
214operator to atomic variable
215.Fa object
216and
217.Fa operand
218and stores the value into
219.Fa object ,
220while returning the original contents of the atomic variable.
221.Pp
222The
223.Fn atomic_is_lock_free
224macro returns whether atomic variable
225.Fa object
226uses locks when using atomic operations.
227.Sh BARRIERS
228The atomic operations described previously are implemented in such a way
229that they disallow both the compiler and the executing processor to
230re-order any nearby memory operations across the atomic operation.
231In certain cases this behaviour may cause suboptimal performance.
232To mitigate this, every atomic operation has an
233.Fn _explicit
234version that allows the re-ordering to be configured.
235.Pp
236The
237.Fa order
238parameter of these
239.Fn _explicit
240macros can have one of the following values.
241.Bl -tag -width memory_order_relaxed
242.It Dv memory_order_relaxed
243No operation orders memory.
244.It Dv memory_order_consume
245Perform consume operation.
246.It Dv memory_order_acquire
247Acquire fence.
248.It Dv memory_order_release
249Release fence.
250.It Dv memory_order_acq_rel
251Acquire and release fence.
252.It Dv memory_order_seq_cst
253Sequentially consistent acquire and release fence.
254.El
255.Pp
256The previously described macros are identical to the
257.Fn _explicit
258macros, when
259.Fa order
260is
261.Dv memory_order_seq_cst .
262.Sh COMPILER SUPPORT
263These atomic operations are typically implemented by the compiler, as
264they must be implemented type-generically and must often use special
265hardware instructions.
266As this interface has not been adopted by most compilers yet, the
267.In stdatomic.h
268header implements these macros on top of existing compiler intrinsics to
269provide forward compatibility.
270.Pp
271This means that certain aspects of the interface, such as support for
272different barrier types may simply be ignored.
273When using GCC, all atomic operations are executed as if they are using
274.Dv memory_order_seq_cst .
275.Pp
276Instead of using the atomic operations provided by this interface,
277.St -isoC-2011
278allows the atomic variables to be modified directly using built-in
279language operators.
280This behaviour cannot be emulated for older compilers.
281To prevent unintended non-atomic access to these variables, this header
282file places the atomic variable in a structure when using an older
283compiler.
284.Pp
285When using GCC on architectures on which it lacks support for built-in
286atomic intrinsics, these macros may emit function calls to fallback
287routines.
288These fallback routines are only implemented for 32-bits and 64-bits
289datatypes, if supported by the CPU.
290.Sh SEE ALSO
291.Xr pthread 3 ,
292.Xr atomic 9
293.Sh STANDARDS
294These macros attempt to conform to
295.St -isoC-2011 .
296.Sh HISTORY
297These macros appeared in
298.Fx 10.0 .
299.Sh AUTHORS
300.An \&Ed Schouten Aq Mt ed@FreeBSD.org
301.An David Chisnall Aq Mt theraven@FreeBSD.org
302