xref: /freebsd/share/man/man9/atomic.9 (revision 68278ec60f11c444e3ada9f337d9d76f791bc7e7)
1d265f300SJohn Baldwin.\" Copyright (c) 2000-2001 John H. Baldwin <jhb@FreeBSD.org>
2eaca6183SJohn Baldwin.\" All rights reserved.
3eaca6183SJohn Baldwin.\"
4eaca6183SJohn Baldwin.\" Redistribution and use in source and binary forms, with or without
5eaca6183SJohn Baldwin.\" modification, are permitted provided that the following conditions
6eaca6183SJohn Baldwin.\" are met:
7eaca6183SJohn Baldwin.\" 1. Redistributions of source code must retain the above copyright
8eaca6183SJohn Baldwin.\"    notice, this list of conditions and the following disclaimer.
9eaca6183SJohn Baldwin.\" 2. Redistributions in binary form must reproduce the above copyright
10eaca6183SJohn Baldwin.\"    notice, this list of conditions and the following disclaimer in the
11eaca6183SJohn Baldwin.\"    documentation and/or other materials provided with the distribution.
12eaca6183SJohn Baldwin.\"
13eaca6183SJohn Baldwin.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
14eaca6183SJohn Baldwin.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15eaca6183SJohn Baldwin.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16eaca6183SJohn Baldwin.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
17eaca6183SJohn Baldwin.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18eaca6183SJohn Baldwin.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19eaca6183SJohn Baldwin.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20eaca6183SJohn Baldwin.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21eaca6183SJohn Baldwin.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22eaca6183SJohn Baldwin.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23eaca6183SJohn Baldwin.\"
24eaca6183SJohn Baldwin.\" $FreeBSD$
25eaca6183SJohn Baldwin.\"
26c0b995bbSMateusz Guzik.Dd Jan 3, 2017
27eaca6183SJohn Baldwin.Dt ATOMIC 9
28aa12cea2SUlrich Spörlein.Os
29eaca6183SJohn Baldwin.Sh NAME
30eaca6183SJohn Baldwin.Nm atomic_add ,
31eaca6183SJohn Baldwin.Nm atomic_clear ,
32eaca6183SJohn Baldwin.Nm atomic_cmpset ,
33c0b995bbSMateusz Guzik.Nm atomic_fcmpset ,
344ea211a4SJohn Baldwin.Nm atomic_fetchadd ,
35eaca6183SJohn Baldwin.Nm atomic_load ,
36eaca6183SJohn Baldwin.Nm atomic_readandclear ,
37eaca6183SJohn Baldwin.Nm atomic_set ,
38eaca6183SJohn Baldwin.Nm atomic_subtract ,
39eaca6183SJohn Baldwin.Nm atomic_store
40eaca6183SJohn Baldwin.Nd atomic operations
41eaca6183SJohn Baldwin.Sh SYNOPSIS
4232eef9aeSRuslan Ermilov.In sys/types.h
4332eef9aeSRuslan Ermilov.In machine/atomic.h
44eaca6183SJohn Baldwin.Ft void
45c6a51f1cSRuslan Ermilov.Fn atomic_add_[acq_|rel_]<type> "volatile <type> *p" "<type> v"
46eaca6183SJohn Baldwin.Ft void
47c6a51f1cSRuslan Ermilov.Fn atomic_clear_[acq_|rel_]<type> "volatile <type> *p" "<type> v"
48eaca6183SJohn Baldwin.Ft int
49c6a51f1cSRuslan Ermilov.Fo atomic_cmpset_[acq_|rel_]<type>
50c6a51f1cSRuslan Ermilov.Fa "volatile <type> *dst"
51c6a51f1cSRuslan Ermilov.Fa "<type> old"
52c6a51f1cSRuslan Ermilov.Fa "<type> new"
53eaca6183SJohn Baldwin.Fc
54c0b995bbSMateusz Guzik.Ft int
55c0b995bbSMateusz Guzik.Fo atomic_fcmpset_[acq_|rel_]<type>
56c0b995bbSMateusz Guzik.Fa "volatile <type> *dst"
57c0b995bbSMateusz Guzik.Fa "<type> *old"
58c0b995bbSMateusz Guzik.Fa "<type> new"
59c0b995bbSMateusz Guzik.Fc
60c6a51f1cSRuslan Ermilov.Ft <type>
614ea211a4SJohn Baldwin.Fn atomic_fetchadd_<type> "volatile <type> *p" "<type> v"
624ea211a4SJohn Baldwin.Ft <type>
63c6a51f1cSRuslan Ermilov.Fn atomic_load_acq_<type> "volatile <type> *p"
64c6a51f1cSRuslan Ermilov.Ft <type>
65c6a51f1cSRuslan Ermilov.Fn atomic_readandclear_<type> "volatile <type> *p"
66eaca6183SJohn Baldwin.Ft void
67c6a51f1cSRuslan Ermilov.Fn atomic_set_[acq_|rel_]<type> "volatile <type> *p" "<type> v"
68eaca6183SJohn Baldwin.Ft void
69c6a51f1cSRuslan Ermilov.Fn atomic_subtract_[acq_|rel_]<type> "volatile <type> *p" "<type> v"
70eaca6183SJohn Baldwin.Ft void
71c6a51f1cSRuslan Ermilov.Fn atomic_store_rel_<type> "volatile <type> *p" "<type> v"
728a1ee2d3SJung-uk Kim.Ft <type>
738a1ee2d3SJung-uk Kim.Fn atomic_swap_<type> "volatile <type> *p" "<type> v"
748a1ee2d3SJung-uk Kim.Ft int
75dfdc9a05SSepherosa Ziehau.Fn atomic_testandclear_<type> "volatile <type> *p" "u_int v"
76dfdc9a05SSepherosa Ziehau.Ft int
778a1ee2d3SJung-uk Kim.Fn atomic_testandset_<type> "volatile <type> *p" "u_int v"
78eaca6183SJohn Baldwin.Sh DESCRIPTION
79a61bd957SAlan CoxEach of the atomic operations is guaranteed to be atomic across multiple
80cff0a327SAlan Coxthreads and in the presence of interrupts.
81eaca6183SJohn BaldwinThey can be used to implement reference counts or as building blocks for more
82eaca6183SJohn Baldwinadvanced synchronization primitives such as mutexes.
83eaca6183SJohn Baldwin.Ss Types
842be6c09fSRuslan ErmilovEach atomic operation operates on a specific
850640e9e0SHiten Pandya.Fa type .
86eaca6183SJohn BaldwinThe type to use is indicated in the function name.
87eaca6183SJohn BaldwinThe available types that can be used are:
882be6c09fSRuslan Ermilov.Pp
892be6c09fSRuslan Ermilov.Bl -tag -offset indent -width short -compact
902be6c09fSRuslan Ermilov.It Li int
91eaca6183SJohn Baldwinunsigned integer
922be6c09fSRuslan Ermilov.It Li long
93eaca6183SJohn Baldwinunsigned long integer
942be6c09fSRuslan Ermilov.It Li ptr
95eaca6183SJohn Baldwinunsigned integer the size of a pointer
962be6c09fSRuslan Ermilov.It Li 32
97eaca6183SJohn Baldwinunsigned 32-bit integer
982be6c09fSRuslan Ermilov.It Li 64
99eaca6183SJohn Baldwinunsigned 64-bit integer
100eaca6183SJohn Baldwin.El
101eaca6183SJohn Baldwin.Pp
102eaca6183SJohn BaldwinFor example, the function to atomically add two integers is called
103eaca6183SJohn Baldwin.Fn atomic_add_int .
104c645e17aSJake Burkholder.Pp
1052be6c09fSRuslan ErmilovCertain architectures also provide operations for types smaller than
1062be6c09fSRuslan Ermilov.Dq Li int .
1072be6c09fSRuslan Ermilov.Pp
1082be6c09fSRuslan Ermilov.Bl -tag -offset indent -width short -compact
1092be6c09fSRuslan Ermilov.It Li char
110c645e17aSJake Burkholderunsigned character
1112be6c09fSRuslan Ermilov.It Li short
112c645e17aSJake Burkholderunsigned short integer
1132be6c09fSRuslan Ermilov.It Li 8
114c645e17aSJake Burkholderunsigned 8-bit integer
1152be6c09fSRuslan Ermilov.It Li 16
116c645e17aSJake Burkholderunsigned 16-bit integer
117c645e17aSJake Burkholder.El
118c645e17aSJake Burkholder.Pp
119c645e17aSJake BurkholderThese must not be used in MI code because the instructions to implement them
120cff0a327SAlan Coxefficiently might not be available.
121cff0a327SAlan Cox.Ss Acquire and Release Operations
122cff0a327SAlan CoxBy default, a thread's accesses to different memory locations might not be
123cff0a327SAlan Coxperformed in
124cff0a327SAlan Cox.Em program order ,
125cff0a327SAlan Coxthat is, the order in which the accesses appear in the source code.
126cff0a327SAlan CoxTo optimize the program's execution, both the compiler and processor might
127cff0a327SAlan Coxreorder the thread's accesses.
128cff0a327SAlan CoxHowever, both ensure that their reordering of the accesses is not visible to
129cff0a327SAlan Coxthe thread.
130cff0a327SAlan CoxOtherwise, the traditional memory model that is expected by single-threaded
131cff0a327SAlan Coxprograms would be violated.
132cff0a327SAlan CoxNonetheless, other threads in a multithreaded program, such as the
133cff0a327SAlan Cox.Fx
134cff0a327SAlan Coxkernel, might observe the reordering.
135cff0a327SAlan CoxMoreover, in some cases, such as the implementation of synchronization between
136cff0a327SAlan Coxthreads, arbitrary reordering might result in the incorrect execution of the
137cff0a327SAlan Coxprogram.
138cff0a327SAlan CoxTo constrain the reordering that both the compiler and processor might perform
139cff0a327SAlan Coxon a thread's accesses, the thread should use atomic operations with
14077054356SKonstantin Belousov.Em acquire
141cff0a327SAlan Coxand
142cff0a327SAlan Cox.Em release
143cff0a327SAlan Coxsemantics.
144cff0a327SAlan Cox.Pp
145cff0a327SAlan CoxMost of the atomic operations on memory have three variants.
146cff0a327SAlan CoxThe first variant performs the operation without imposing any ordering
147cff0a327SAlan Coxconstraints on memory accesses to other locations.
148cff0a327SAlan CoxThe second variant has acquire semantics, and the third variant has release
149cff0a327SAlan Coxsemantics.
150cff0a327SAlan CoxIn effect, operations with acquire and release semantics establish one-way
151cff0a327SAlan Coxbarriers to reordering.
152cff0a327SAlan Cox.Pp
153cff0a327SAlan CoxWhen an atomic operation has acquire semantics, the effects of the operation
154cff0a327SAlan Coxmust have completed before any subsequent load or store (by program order) is
155cff0a327SAlan Coxperformed.
156cff0a327SAlan CoxConversely, acquire semantics do not require that prior loads or stores have
157cff0a327SAlan Coxcompleted before the atomic operation is performed.
158cff0a327SAlan CoxTo denote acquire semantics, the suffix
1592be6c09fSRuslan Ermilov.Dq Li _acq
160eaca6183SJohn Baldwinis inserted into the function name immediately prior to the
1610640e9e0SHiten Pandya.Dq Li _ Ns Aq Fa type
162eaca6183SJohn Baldwinsuffix.
163cff0a327SAlan CoxFor example, to subtract two integers ensuring that subsequent loads and
164cff0a327SAlan Coxstores happen after the subtraction is performed, use
165eaca6183SJohn Baldwin.Fn atomic_subtract_acq_int .
166eaca6183SJohn Baldwin.Pp
167cff0a327SAlan CoxWhen an atomic operation has release semantics, the effects of all prior
168cff0a327SAlan Coxloads or stores (by program order) must have completed before the operation
169cff0a327SAlan Coxis performed.
170cff0a327SAlan CoxConversely, release semantics do not require that the effects of the
171cff0a327SAlan Coxatomic operation must have completed before any subsequent load or store is
172cff0a327SAlan Coxperformed.
173cff0a327SAlan CoxTo denote release semantics, the suffix
1742be6c09fSRuslan Ermilov.Dq Li _rel
175eaca6183SJohn Baldwinis inserted into the function name immediately prior to the
1760640e9e0SHiten Pandya.Dq Li _ Ns Aq Fa type
177eaca6183SJohn Baldwinsuffix.
178cff0a327SAlan CoxFor example, to add two long integers ensuring that all prior loads and
179cff0a327SAlan Coxstores happen before the addition, use
180eaca6183SJohn Baldwin.Fn atomic_add_rel_long .
181eaca6183SJohn Baldwin.Pp
182cff0a327SAlan CoxThe one-way barriers provided by acquire and release operations allow the
183cff0a327SAlan Coximplementations of common synchronization primitives to express their
184cff0a327SAlan Coxordering requirements without also imposing unnecessary ordering.
185cff0a327SAlan CoxFor example, for a critical section guarded by a mutex, an acquire operation
186cff0a327SAlan Coxwhen the mutex is locked and a release operation when the mutex is unlocked
187cff0a327SAlan Coxwill prevent any loads or stores from moving outside of the critical
188cff0a327SAlan Coxsection.
189cff0a327SAlan CoxHowever, they will not prevent the compiler or processor from moving loads
190cff0a327SAlan Coxor stores into the critical section, which does not violate the semantics of
191cff0a327SAlan Coxa mutex.
192eaca6183SJohn Baldwin.Ss Multiple Processors
193a61bd957SAlan CoxIn multiprocessor systems, the atomicity of the atomic operations on memory
194a61bd957SAlan Coxdepends on support for cache coherence in the underlying architecture.
195a61bd957SAlan CoxIn general, cache coherence on the default memory type,
196a61bd957SAlan Cox.Dv VM_MEMATTR_DEFAULT ,
197a61bd957SAlan Coxis guaranteed by all architectures that are supported by
198a61bd957SAlan Cox.Fx .
199a61bd957SAlan CoxFor example, cache coherence is guaranteed on write-back memory by the
200a61bd957SAlan Cox.Tn amd64
201a61bd957SAlan Coxand
202eaca6183SJohn Baldwin.Tn i386
203a61bd957SAlan Coxarchitectures.
204cff0a327SAlan CoxHowever, on some architectures, cache coherence might not be enabled on all
205a61bd957SAlan Coxmemory types.
206a61bd957SAlan CoxTo determine if cache coherence is enabled for a non-default memory type,
207a61bd957SAlan Coxconsult the architecture's documentation.
208eaca6183SJohn Baldwin.Ss Semantics
209eaca6183SJohn BaldwinThis section describes the semantics of each operation using a C like notation.
210eaca6183SJohn Baldwin.Bl -hang
2112be6c09fSRuslan Ermilov.It Fn atomic_add p v
2122be6c09fSRuslan Ermilov.Bd -literal -compact
213eaca6183SJohn Baldwin*p += v;
214eaca6183SJohn Baldwin.Ed
2152be6c09fSRuslan Ermilov.It Fn atomic_clear p v
2162be6c09fSRuslan Ermilov.Bd -literal -compact
217eaca6183SJohn Baldwin*p &= ~v;
218eaca6183SJohn Baldwin.Ed
2192be6c09fSRuslan Ermilov.It Fn atomic_cmpset dst old new
2202be6c09fSRuslan Ermilov.Bd -literal -compact
221eaca6183SJohn Baldwinif (*dst == old) {
222eaca6183SJohn Baldwin	*dst = new;
2238a1ee2d3SJung-uk Kim	return (1);
224eaca6183SJohn Baldwin} else
2258a1ee2d3SJung-uk Kim	return (0);
226eaca6183SJohn Baldwin.Ed
227eaca6183SJohn Baldwin.El
228eaca6183SJohn Baldwin.Pp
229eaca6183SJohn BaldwinThe
230eaca6183SJohn Baldwin.Fn atomic_cmpset
2312be6c09fSRuslan Ermilovfunctions are not implemented for the types
2322be6c09fSRuslan Ermilov.Dq Li char ,
2332be6c09fSRuslan Ermilov.Dq Li short ,
2342be6c09fSRuslan Ermilov.Dq Li 8 ,
2352be6c09fSRuslan Ermilovand
2362be6c09fSRuslan Ermilov.Dq Li 16 .
237eaca6183SJohn Baldwin.Bl -hang
238c0b995bbSMateusz Guzik.It Fn atomic_fcmpset dst *old new
239c0b995bbSMateusz Guzik.El
240c0b995bbSMateusz Guzik.Pp
241c0b995bbSMateusz GuzikOn architectures implementing
242c0b995bbSMateusz Guzik.Em Compare And Swap
243c0b995bbSMateusz Guzikoperation in hardware, the functionality can be described as
244c0b995bbSMateusz Guzik.Bd -literal -offset indent -compact
245c0b995bbSMateusz Guzikif (*dst == *old) {
246c0b995bbSMateusz Guzik	*dst = new;
247c0b995bbSMateusz Guzik	return (1);
248c0b995bbSMateusz Guzik} else {
249c0b995bbSMateusz Guzik	*old = *dst;
250c0b995bbSMateusz Guzik	return (0);
251c0b995bbSMateusz Guzik}
252c0b995bbSMateusz Guzik.Ed
253c0b995bbSMateusz GuzikOn architectures which provide
254c0b995bbSMateusz Guzik.Em Load Linked/Store Conditional
255c0b995bbSMateusz Guzikprimitive, the write to
256c0b995bbSMateusz Guzik.Dv *dst
257c0b995bbSMateusz Guzikmight also fail for several reasons, most important of which
258c0b995bbSMateusz Guzikis a parallel write to
259c0b995bbSMateusz Guzik.Dv *dst
260c0b995bbSMateusz Guzikcache line by other CPU.
261c0b995bbSMateusz GuzikIn this case
262c0b995bbSMateusz Guzik.Fn atomic_fcmpset
263c0b995bbSMateusz Guzikfunction also returns
264c0b995bbSMateusz Guzik.Dv false ,
265c0b995bbSMateusz Guzikdespite
266c0b995bbSMateusz Guzik.Dl *old == *dst .
267c0b995bbSMateusz Guzik.Pp
268c0b995bbSMateusz GuzikThe
269c0b995bbSMateusz Guzik.Fn atomic_fcmpset
270c0b995bbSMateusz Guzikfunctions are not implemented for the types
271c0b995bbSMateusz Guzik.Dq Li char ,
272c0b995bbSMateusz Guzik.Dq Li short ,
273c0b995bbSMateusz Guzik.Dq Li 8 ,
274c0b995bbSMateusz Guzikand
275c0b995bbSMateusz Guzik.Dq Li 16 .
276c0b995bbSMateusz Guzik.Bl -hang
2774ea211a4SJohn Baldwin.It Fn atomic_fetchadd p v
2784ea211a4SJohn Baldwin.Bd -literal -compact
2794ea211a4SJohn Baldwintmp = *p;
2804ea211a4SJohn Baldwin*p += v;
2818a1ee2d3SJung-uk Kimreturn (tmp);
2824ea211a4SJohn Baldwin.Ed
2834ea211a4SJohn Baldwin.El
2844ea211a4SJohn Baldwin.Pp
2854ea211a4SJohn BaldwinThe
2864ea211a4SJohn Baldwin.Fn atomic_fetchadd
2874ea211a4SJohn Baldwinfunctions are only implemented for the types
2886eb4157fSPawel Jakub Dawidek.Dq Li int ,
2896eb4157fSPawel Jakub Dawidek.Dq Li long
2904ea211a4SJohn Baldwinand
2914ea211a4SJohn Baldwin.Dq Li 32
2924ea211a4SJohn Baldwinand do not have any variants with memory barriers at this time.
2934ea211a4SJohn Baldwin.Bl -hang
2948a1ee2d3SJung-uk Kim.It Fn atomic_load p
2952be6c09fSRuslan Ermilov.Bd -literal -compact
2968a1ee2d3SJung-uk Kimreturn (*p);
297eaca6183SJohn Baldwin.Ed
298eaca6183SJohn Baldwin.El
299eaca6183SJohn Baldwin.Pp
300eaca6183SJohn BaldwinThe
301eaca6183SJohn Baldwin.Fn atomic_load
302e6b08944SJohn Baldwinfunctions are only provided with acquire memory barriers.
303eaca6183SJohn Baldwin.Bl -hang
3048a1ee2d3SJung-uk Kim.It Fn atomic_readandclear p
3052be6c09fSRuslan Ermilov.Bd -literal -compact
3068a1ee2d3SJung-uk Kimtmp = *p;
3078a1ee2d3SJung-uk Kim*p = 0;
3088a1ee2d3SJung-uk Kimreturn (tmp);
309eaca6183SJohn Baldwin.Ed
310eaca6183SJohn Baldwin.El
311eaca6183SJohn Baldwin.Pp
312eaca6183SJohn BaldwinThe
313eaca6183SJohn Baldwin.Fn atomic_readandclear
3142be6c09fSRuslan Ermilovfunctions are not implemented for the types
3152be6c09fSRuslan Ermilov.Dq Li char ,
3162be6c09fSRuslan Ermilov.Dq Li short ,
3172be6c09fSRuslan Ermilov.Dq Li ptr ,
3182be6c09fSRuslan Ermilov.Dq Li 8 ,
3192be6c09fSRuslan Ermilovand
3202be6c09fSRuslan Ermilov.Dq Li 16
3218a1ee2d3SJung-uk Kimand do not have any variants with memory barriers at this time.
322eaca6183SJohn Baldwin.Bl -hang
3232be6c09fSRuslan Ermilov.It Fn atomic_set p v
3242be6c09fSRuslan Ermilov.Bd -literal -compact
325eaca6183SJohn Baldwin*p |= v;
326eaca6183SJohn Baldwin.Ed
3272be6c09fSRuslan Ermilov.It Fn atomic_subtract p v
3282be6c09fSRuslan Ermilov.Bd -literal -compact
329eaca6183SJohn Baldwin*p -= v;
330eaca6183SJohn Baldwin.Ed
3312be6c09fSRuslan Ermilov.It Fn atomic_store p v
3322be6c09fSRuslan Ermilov.Bd -literal -compact
333eaca6183SJohn Baldwin*p = v;
334eaca6183SJohn Baldwin.Ed
335eaca6183SJohn Baldwin.El
336eaca6183SJohn Baldwin.Pp
337eaca6183SJohn BaldwinThe
338eaca6183SJohn Baldwin.Fn atomic_store
339e6b08944SJohn Baldwinfunctions are only provided with release memory barriers.
3408a1ee2d3SJung-uk Kim.Bl -hang
3418a1ee2d3SJung-uk Kim.It Fn atomic_swap p v
3428a1ee2d3SJung-uk Kim.Bd -literal -compact
3438a1ee2d3SJung-uk Kimtmp = *p;
3448a1ee2d3SJung-uk Kim*p = v;
3458a1ee2d3SJung-uk Kimreturn (tmp);
3468a1ee2d3SJung-uk Kim.Ed
3478a1ee2d3SJung-uk Kim.El
3488a1ee2d3SJung-uk Kim.Pp
3498a1ee2d3SJung-uk KimThe
3508a1ee2d3SJung-uk Kim.Fn atomic_swap
3518a1ee2d3SJung-uk Kimfunctions are not implemented for the types
3528a1ee2d3SJung-uk Kim.Dq Li char ,
3538a1ee2d3SJung-uk Kim.Dq Li short ,
3548a1ee2d3SJung-uk Kim.Dq Li ptr ,
3558a1ee2d3SJung-uk Kim.Dq Li 8 ,
3568a1ee2d3SJung-uk Kimand
3578a1ee2d3SJung-uk Kim.Dq Li 16
3588a1ee2d3SJung-uk Kimand do not have any variants with memory barriers at this time.
3598a1ee2d3SJung-uk Kim.Bl -hang
360dfdc9a05SSepherosa Ziehau.It Fn atomic_testandclear p v
361dfdc9a05SSepherosa Ziehau.Bd -literal -compact
362dfdc9a05SSepherosa Ziehaubit = 1 << (v % (sizeof(*p) * NBBY));
363dfdc9a05SSepherosa Ziehautmp = (*p & bit) != 0;
364dfdc9a05SSepherosa Ziehau*p &= ~bit;
365dfdc9a05SSepherosa Ziehaureturn (tmp);
366dfdc9a05SSepherosa Ziehau.Ed
367dfdc9a05SSepherosa Ziehau.El
368dfdc9a05SSepherosa Ziehau.Bl -hang
3698a1ee2d3SJung-uk Kim.It Fn atomic_testandset p v
3708a1ee2d3SJung-uk Kim.Bd -literal -compact
3718a1ee2d3SJung-uk Kimbit = 1 << (v % (sizeof(*p) * NBBY));
3728a1ee2d3SJung-uk Kimtmp = (*p & bit) != 0;
3738a1ee2d3SJung-uk Kim*p |= bit;
3748a1ee2d3SJung-uk Kimreturn (tmp);
3758a1ee2d3SJung-uk Kim.Ed
3768a1ee2d3SJung-uk Kim.El
3778a1ee2d3SJung-uk Kim.Pp
3788a1ee2d3SJung-uk KimThe
3798a1ee2d3SJung-uk Kim.Fn atomic_testandset
380dfdc9a05SSepherosa Ziehauand
381dfdc9a05SSepherosa Ziehau.Fn atomic_testandclear
3828a1ee2d3SJung-uk Kimfunctions are only implemented for the types
3838a1ee2d3SJung-uk Kim.Dq Li int ,
3848a1ee2d3SJung-uk Kim.Dq Li long
3858a1ee2d3SJung-uk Kimand
3868a1ee2d3SJung-uk Kim.Dq Li 32
3878a1ee2d3SJung-uk Kimand do not have any variants with memory barriers at this time.
3888a1ee2d3SJung-uk Kim.Pp
389eaca6183SJohn BaldwinThe type
3902be6c09fSRuslan Ermilov.Dq Li 64
391eaca6183SJohn Baldwinis currently not implemented for any of the atomic operations on the
3924ea211a4SJohn Baldwin.Tn arm ,
3934ea211a4SJohn Baldwin.Tn i386 ,
3944ea211a4SJohn Baldwinand
3954ea211a4SJohn Baldwin.Tn powerpc
3964ea211a4SJohn Baldwinarchitectures.
397eaca6183SJohn Baldwin.Sh RETURN VALUES
3982be6c09fSRuslan ErmilovThe
399eaca6183SJohn Baldwin.Fn atomic_cmpset
4008a1ee2d3SJung-uk Kimfunction returns the result of the compare operation.
4012be6c09fSRuslan ErmilovThe
402c0b995bbSMateusz Guzik.Fn atomic_fcmpset
403c0b995bbSMateusz Guzikfunction returns
404c0b995bbSMateusz Guzik.Dv true
405*68278ec6SBenjamin Kadukif the operation succeeded.
406c0b995bbSMateusz GuzikOtherwise it returns
407c0b995bbSMateusz Guzik.Dv false
408c0b995bbSMateusz Guzikand sets
409c0b995bbSMateusz Guzik.Va *old
410c0b995bbSMateusz Guzikto the found value.
411c0b995bbSMateusz GuzikThe
4124ea211a4SJohn Baldwin.Fn atomic_fetchadd ,
4134ea211a4SJohn Baldwin.Fn atomic_load ,
4148a1ee2d3SJung-uk Kim.Fn atomic_readandclear ,
415eaca6183SJohn Baldwinand
4168a1ee2d3SJung-uk Kim.Fn atomic_swap
4178a1ee2d3SJung-uk Kimfunctions return the value at the specified address.
4188a1ee2d3SJung-uk KimThe
4198a1ee2d3SJung-uk Kim.Fn atomic_testandset
420dfdc9a05SSepherosa Ziehauand
421dfdc9a05SSepherosa Ziehau.Fn atomic_testandclear
4228a1ee2d3SJung-uk Kimfunction returns the result of the test operation.
423eaca6183SJohn Baldwin.Sh EXAMPLES
424eaca6183SJohn BaldwinThis example uses the
425eaca6183SJohn Baldwin.Fn atomic_cmpset_acq_ptr
426eaca6183SJohn Baldwinand
427eaca6183SJohn Baldwin.Fn atomic_set_ptr
428eaca6183SJohn Baldwinfunctions to obtain a sleep mutex and handle recursion.
429eaca6183SJohn BaldwinSince the
430eaca6183SJohn Baldwin.Va mtx_lock
431eaca6183SJohn Baldwinmember of a
4322be6c09fSRuslan Ermilov.Vt "struct mtx"
433eaca6183SJohn Baldwinis a pointer, the
4342be6c09fSRuslan Ermilov.Dq Li ptr
435eaca6183SJohn Baldwintype is used.
436eaca6183SJohn Baldwin.Bd -literal
4374ea211a4SJohn Baldwin/* Try to obtain mtx_lock once. */
438eaca6183SJohn Baldwin#define _obtain_lock(mp, tid)						\\
4394ea211a4SJohn Baldwin	atomic_cmpset_acq_ptr(&(mp)->mtx_lock, MTX_UNOWNED, (tid))
440eaca6183SJohn Baldwin
441eaca6183SJohn Baldwin/* Get a sleep lock, deal with recursion inline. */
4424ea211a4SJohn Baldwin#define _get_sleep_lock(mp, tid, opts, file, line) do {			\\
4434ea211a4SJohn Baldwin	uintptr_t _tid = (uintptr_t)(tid);				\\
4444ea211a4SJohn Baldwin									\\
445eaca6183SJohn Baldwin	if (!_obtain_lock(mp, tid)) {					\\
4464ea211a4SJohn Baldwin		if (((mp)->mtx_lock & MTX_FLAGMASK) != _tid)		\\
4474ea211a4SJohn Baldwin			_mtx_lock_sleep((mp), _tid, (opts), (file), (line));\\
448eaca6183SJohn Baldwin		else {							\\
449eaca6183SJohn Baldwin			atomic_set_ptr(&(mp)->mtx_lock, MTX_RECURSE);	\\
450eaca6183SJohn Baldwin			(mp)->mtx_recurse++;				\\
451eaca6183SJohn Baldwin		}							\\
452eaca6183SJohn Baldwin	}								\\
453eaca6183SJohn Baldwin} while (0)
454eaca6183SJohn Baldwin.Ed
455eaca6183SJohn Baldwin.Sh HISTORY
456eaca6183SJohn BaldwinThe
457eaca6183SJohn Baldwin.Fn atomic_add ,
458eaca6183SJohn Baldwin.Fn atomic_clear ,
459eaca6183SJohn Baldwin.Fn atomic_set ,
460eaca6183SJohn Baldwinand
461eaca6183SJohn Baldwin.Fn atomic_subtract
462eaca6183SJohn Baldwinoperations were first introduced in
463eaca6183SJohn Baldwin.Fx 3.0 .
4642be6c09fSRuslan ErmilovThis first set only supported the types
4652be6c09fSRuslan Ermilov.Dq Li char ,
4662be6c09fSRuslan Ermilov.Dq Li short ,
4672be6c09fSRuslan Ermilov.Dq Li int ,
4682be6c09fSRuslan Ermilovand
4692be6c09fSRuslan Ermilov.Dq Li long .
470eaca6183SJohn BaldwinThe
471eaca6183SJohn Baldwin.Fn atomic_cmpset ,
472eaca6183SJohn Baldwin.Fn atomic_load ,
473eaca6183SJohn Baldwin.Fn atomic_readandclear ,
474eaca6183SJohn Baldwinand
475eaca6183SJohn Baldwin.Fn atomic_store
476eaca6183SJohn Baldwinoperations were added in
477eaca6183SJohn Baldwin.Fx 5.0 .
4782be6c09fSRuslan ErmilovThe types
4792be6c09fSRuslan Ermilov.Dq Li 8 ,
4802be6c09fSRuslan Ermilov.Dq Li 16 ,
4812be6c09fSRuslan Ermilov.Dq Li 32 ,
4822be6c09fSRuslan Ermilov.Dq Li 64 ,
4832be6c09fSRuslan Ermilovand
4844ea211a4SJohn Baldwin.Dq Li ptr
4852be6c09fSRuslan Ermilovand all of the acquire and release variants
486eaca6183SJohn Baldwinwere added in
487eaca6183SJohn Baldwin.Fx 5.0
488eaca6183SJohn Baldwinas well.
4894ea211a4SJohn BaldwinThe
4904ea211a4SJohn Baldwin.Fn atomic_fetchadd
4914ea211a4SJohn Baldwinoperations were added in
4924ea211a4SJohn Baldwin.Fx 6.0 .
4938a1ee2d3SJung-uk KimThe
4948a1ee2d3SJung-uk Kim.Fn atomic_swap
4958a1ee2d3SJung-uk Kimand
4968a1ee2d3SJung-uk Kim.Fn atomic_testandset
4978a1ee2d3SJung-uk Kimoperations were added in
4988a1ee2d3SJung-uk Kim.Fx 10.0 .
499dfdc9a05SSepherosa Ziehau.Fn atomic_testandclear
500dfdc9a05SSepherosa Ziehauoperation was added in
501dfdc9a05SSepherosa Ziehau.Fx 11.0 .
502