xref: /freebsd/share/man/man9/atomic.9 (revision 8a1ee2d346716fc0c13fa3349839ad1aed0144ad)
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.\"
26*8a1ee2d3SJung-uk Kim.Dd August 20, 2013
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 ,
334ea211a4SJohn Baldwin.Nm atomic_fetchadd ,
34eaca6183SJohn Baldwin.Nm atomic_load ,
35eaca6183SJohn Baldwin.Nm atomic_readandclear ,
36eaca6183SJohn Baldwin.Nm atomic_set ,
37eaca6183SJohn Baldwin.Nm atomic_subtract ,
38eaca6183SJohn Baldwin.Nm atomic_store
39eaca6183SJohn Baldwin.Nd atomic operations
40eaca6183SJohn Baldwin.Sh SYNOPSIS
4132eef9aeSRuslan Ermilov.In sys/types.h
4232eef9aeSRuslan Ermilov.In machine/atomic.h
43eaca6183SJohn Baldwin.Ft void
44c6a51f1cSRuslan Ermilov.Fn atomic_add_[acq_|rel_]<type> "volatile <type> *p" "<type> v"
45eaca6183SJohn Baldwin.Ft void
46c6a51f1cSRuslan Ermilov.Fn atomic_clear_[acq_|rel_]<type> "volatile <type> *p" "<type> v"
47eaca6183SJohn Baldwin.Ft int
48c6a51f1cSRuslan Ermilov.Fo atomic_cmpset_[acq_|rel_]<type>
49c6a51f1cSRuslan Ermilov.Fa "volatile <type> *dst"
50c6a51f1cSRuslan Ermilov.Fa "<type> old"
51c6a51f1cSRuslan Ermilov.Fa "<type> new"
52eaca6183SJohn Baldwin.Fc
53c6a51f1cSRuslan Ermilov.Ft <type>
544ea211a4SJohn Baldwin.Fn atomic_fetchadd_<type> "volatile <type> *p" "<type> v"
554ea211a4SJohn Baldwin.Ft <type>
56c6a51f1cSRuslan Ermilov.Fn atomic_load_acq_<type> "volatile <type> *p"
57c6a51f1cSRuslan Ermilov.Ft <type>
58c6a51f1cSRuslan Ermilov.Fn atomic_readandclear_<type> "volatile <type> *p"
59eaca6183SJohn Baldwin.Ft void
60c6a51f1cSRuslan Ermilov.Fn atomic_set_[acq_|rel_]<type> "volatile <type> *p" "<type> v"
61eaca6183SJohn Baldwin.Ft void
62c6a51f1cSRuslan Ermilov.Fn atomic_subtract_[acq_|rel_]<type> "volatile <type> *p" "<type> v"
63eaca6183SJohn Baldwin.Ft void
64c6a51f1cSRuslan Ermilov.Fn atomic_store_rel_<type> "volatile <type> *p" "<type> v"
65*8a1ee2d3SJung-uk Kim.Ft <type>
66*8a1ee2d3SJung-uk Kim.Fn atomic_swap_<type> "volatile <type> *p" "<type> v"
67*8a1ee2d3SJung-uk Kim.Ft int
68*8a1ee2d3SJung-uk Kim.Fn atomic_testandset_<type> "volatile <type> *p" "u_int v"
69eaca6183SJohn Baldwin.Sh DESCRIPTION
70eaca6183SJohn BaldwinEach of the atomic operations is guaranteed to be atomic in the presence of
71eaca6183SJohn Baldwininterrupts.
72eaca6183SJohn BaldwinThey can be used to implement reference counts or as building blocks for more
73eaca6183SJohn Baldwinadvanced synchronization primitives such as mutexes.
74eaca6183SJohn Baldwin.Ss Types
752be6c09fSRuslan ErmilovEach atomic operation operates on a specific
760640e9e0SHiten Pandya.Fa type .
77eaca6183SJohn BaldwinThe type to use is indicated in the function name.
78eaca6183SJohn BaldwinThe available types that can be used are:
792be6c09fSRuslan Ermilov.Pp
802be6c09fSRuslan Ermilov.Bl -tag -offset indent -width short -compact
812be6c09fSRuslan Ermilov.It Li int
82eaca6183SJohn Baldwinunsigned integer
832be6c09fSRuslan Ermilov.It Li long
84eaca6183SJohn Baldwinunsigned long integer
852be6c09fSRuslan Ermilov.It Li ptr
86eaca6183SJohn Baldwinunsigned integer the size of a pointer
872be6c09fSRuslan Ermilov.It Li 32
88eaca6183SJohn Baldwinunsigned 32-bit integer
892be6c09fSRuslan Ermilov.It Li 64
90eaca6183SJohn Baldwinunsigned 64-bit integer
91eaca6183SJohn Baldwin.El
92eaca6183SJohn Baldwin.Pp
93eaca6183SJohn BaldwinFor example, the function to atomically add two integers is called
94eaca6183SJohn Baldwin.Fn atomic_add_int .
95c645e17aSJake Burkholder.Pp
962be6c09fSRuslan ErmilovCertain architectures also provide operations for types smaller than
972be6c09fSRuslan Ermilov.Dq Li int .
982be6c09fSRuslan Ermilov.Pp
992be6c09fSRuslan Ermilov.Bl -tag -offset indent -width short -compact
1002be6c09fSRuslan Ermilov.It Li char
101c645e17aSJake Burkholderunsigned character
1022be6c09fSRuslan Ermilov.It Li short
103c645e17aSJake Burkholderunsigned short integer
1042be6c09fSRuslan Ermilov.It Li 8
105c645e17aSJake Burkholderunsigned 8-bit integer
1062be6c09fSRuslan Ermilov.It Li 16
107c645e17aSJake Burkholderunsigned 16-bit integer
108c645e17aSJake Burkholder.El
109c645e17aSJake Burkholder.Pp
110c645e17aSJake BurkholderThese must not be used in MI code because the instructions to implement them
111c645e17aSJake Burkholderefficiently may not be available.
112eaca6183SJohn Baldwin.Ss Memory Barriers
1132be6c09fSRuslan ErmilovMemory barriers are used to guarantee the order of data accesses in
114eaca6183SJohn Baldwintwo ways.
115eaca6183SJohn BaldwinFirst, they specify hints to the compiler to not re-order or optimize the
116eaca6183SJohn Baldwinoperations.
1172be6c09fSRuslan ErmilovSecond, on architectures that do not guarantee ordered data accesses,
118eaca6183SJohn Baldwinspecial instructions or special variants of instructions are used to indicate
119eaca6183SJohn Baldwinto the processor that data accesses need to occur in a certain order.
120eaca6183SJohn BaldwinAs a result, most of the atomic operations have three variants in order to
121eaca6183SJohn Baldwininclude optional memory barriers.
122eaca6183SJohn BaldwinThe first form just performs the operation without any explicit barriers.
1232be6c09fSRuslan ErmilovThe second form uses a read memory barrier, and the third variant uses a write
124eaca6183SJohn Baldwinmemory barrier.
125eaca6183SJohn Baldwin.Pp
126eaca6183SJohn BaldwinThe second variant of each operation includes a read memory barrier.
127eaca6183SJohn BaldwinThis barrier ensures that the effects of this operation are completed before the
128eaca6183SJohn Baldwineffects of any later data accesses.
129eaca6183SJohn BaldwinAs a result, the operation is said to have acquire semantics as it acquires a
130eaca6183SJohn Baldwinpseudo-lock requiring further operations to wait until it has completed.
131eaca6183SJohn BaldwinTo denote this, the suffix
1322be6c09fSRuslan Ermilov.Dq Li _acq
133eaca6183SJohn Baldwinis inserted into the function name immediately prior to the
1340640e9e0SHiten Pandya.Dq Li _ Ns Aq Fa type
135eaca6183SJohn Baldwinsuffix.
136eaca6183SJohn BaldwinFor example, to subtract two integers ensuring that any later writes will
137eaca6183SJohn Baldwinhappen after the subtraction is performed, use
138eaca6183SJohn Baldwin.Fn atomic_subtract_acq_int .
139eaca6183SJohn Baldwin.Pp
140eaca6183SJohn BaldwinThe third variant of each operation includes a write memory barrier.
141eaca6183SJohn BaldwinThis ensures that all effects of all previous data accesses are completed
142eaca6183SJohn Baldwinbefore this operation takes place.
143eaca6183SJohn BaldwinAs a result, the operation is said to have release semantics as it releases
144eaca6183SJohn Baldwinany pending data accesses to be completed before its operation is performed.
145eaca6183SJohn BaldwinTo denote this, the suffix
1462be6c09fSRuslan Ermilov.Dq Li _rel
147eaca6183SJohn Baldwinis inserted into the function name immediately prior to the
1480640e9e0SHiten Pandya.Dq Li _ Ns Aq Fa type
149eaca6183SJohn Baldwinsuffix.
150eaca6183SJohn BaldwinFor example, to add two long integers ensuring that all previous
151eaca6183SJohn Baldwinwrites will happen first, use
152eaca6183SJohn Baldwin.Fn atomic_add_rel_long .
153eaca6183SJohn Baldwin.Pp
154eaca6183SJohn BaldwinA practical example of using memory barriers is to ensure that data accesses
155eaca6183SJohn Baldwinthat are protected by a lock are all performed while the lock is held.
156eaca6183SJohn BaldwinTo achieve this, one would use a read barrier when acquiring the lock to
157eaca6183SJohn Baldwinguarantee that the lock is held before any protected operations are performed.
158eaca6183SJohn BaldwinFinally, one would use a write barrier when releasing the lock to ensure that
159eaca6183SJohn Baldwinall of the protected operations are completed before the lock is released.
160eaca6183SJohn Baldwin.Ss Multiple Processors
161eaca6183SJohn BaldwinThe current set of atomic operations do not necessarily guarantee atomicity
162eaca6183SJohn Baldwinacross multiple processors.
163eaca6183SJohn BaldwinTo guarantee atomicity across processors, not only does the individual
164d1ed27b6SJens Schweikhardtoperation need to be atomic on the processor performing the operation, but
165eaca6183SJohn Baldwinthe result of the operation needs to be pushed out to stable storage and the
166eaca6183SJohn Baldwincaches of all other processors on the system need to invalidate any cache
167eaca6183SJohn Baldwinlines that include the affected memory region.
168eaca6183SJohn BaldwinOn the
169eaca6183SJohn Baldwin.Tn i386
170eaca6183SJohn Baldwinarchitecture, the cache coherency model requires that the hardware perform
171eaca6183SJohn Baldwinthis task, thus the atomic operations are atomic across multiple processors.
172eaca6183SJohn BaldwinOn the
173eaca6183SJohn Baldwin.Tn ia64
174eaca6183SJohn Baldwinarchitecture, coherency is only guaranteed for pages that are configured to
175eaca6183SJohn Baldwinusing a caching policy of either uncached or write back.
176eaca6183SJohn Baldwin.Ss Semantics
177eaca6183SJohn BaldwinThis section describes the semantics of each operation using a C like notation.
178eaca6183SJohn Baldwin.Bl -hang
1792be6c09fSRuslan Ermilov.It Fn atomic_add p v
1802be6c09fSRuslan Ermilov.Bd -literal -compact
181eaca6183SJohn Baldwin*p += v;
182eaca6183SJohn Baldwin.Ed
1832be6c09fSRuslan Ermilov.It Fn atomic_clear p v
1842be6c09fSRuslan Ermilov.Bd -literal -compact
185eaca6183SJohn Baldwin*p &= ~v;
186eaca6183SJohn Baldwin.Ed
1872be6c09fSRuslan Ermilov.It Fn atomic_cmpset dst old new
1882be6c09fSRuslan Ermilov.Bd -literal -compact
189eaca6183SJohn Baldwinif (*dst == old) {
190eaca6183SJohn Baldwin	*dst = new;
191*8a1ee2d3SJung-uk Kim	return (1);
192eaca6183SJohn Baldwin} else
193*8a1ee2d3SJung-uk Kim	return (0);
194eaca6183SJohn Baldwin.Ed
195eaca6183SJohn Baldwin.El
196eaca6183SJohn Baldwin.Pp
197eaca6183SJohn BaldwinThe
198eaca6183SJohn Baldwin.Fn atomic_cmpset
1992be6c09fSRuslan Ermilovfunctions are not implemented for the types
2002be6c09fSRuslan Ermilov.Dq Li char ,
2012be6c09fSRuslan Ermilov.Dq Li short ,
2022be6c09fSRuslan Ermilov.Dq Li 8 ,
2032be6c09fSRuslan Ermilovand
2042be6c09fSRuslan Ermilov.Dq Li 16 .
205eaca6183SJohn Baldwin.Bl -hang
2064ea211a4SJohn Baldwin.It Fn atomic_fetchadd p v
2074ea211a4SJohn Baldwin.Bd -literal -compact
2084ea211a4SJohn Baldwintmp = *p;
2094ea211a4SJohn Baldwin*p += v;
210*8a1ee2d3SJung-uk Kimreturn (tmp);
2114ea211a4SJohn Baldwin.Ed
2124ea211a4SJohn Baldwin.El
2134ea211a4SJohn Baldwin.Pp
2144ea211a4SJohn BaldwinThe
2154ea211a4SJohn Baldwin.Fn atomic_fetchadd
2164ea211a4SJohn Baldwinfunctions are only implemented for the types
2176eb4157fSPawel Jakub Dawidek.Dq Li int ,
2186eb4157fSPawel Jakub Dawidek.Dq Li long
2194ea211a4SJohn Baldwinand
2204ea211a4SJohn Baldwin.Dq Li 32
2214ea211a4SJohn Baldwinand do not have any variants with memory barriers at this time.
2224ea211a4SJohn Baldwin.Bl -hang
223*8a1ee2d3SJung-uk Kim.It Fn atomic_load p
2242be6c09fSRuslan Ermilov.Bd -literal -compact
225*8a1ee2d3SJung-uk Kimreturn (*p);
226eaca6183SJohn Baldwin.Ed
227eaca6183SJohn Baldwin.El
228eaca6183SJohn Baldwin.Pp
229eaca6183SJohn BaldwinThe
230eaca6183SJohn Baldwin.Fn atomic_load
231e6b08944SJohn Baldwinfunctions are only provided with acquire memory barriers.
232eaca6183SJohn Baldwin.Bl -hang
233*8a1ee2d3SJung-uk Kim.It Fn atomic_readandclear p
2342be6c09fSRuslan Ermilov.Bd -literal -compact
235*8a1ee2d3SJung-uk Kimtmp = *p;
236*8a1ee2d3SJung-uk Kim*p = 0;
237*8a1ee2d3SJung-uk Kimreturn (tmp);
238eaca6183SJohn Baldwin.Ed
239eaca6183SJohn Baldwin.El
240eaca6183SJohn Baldwin.Pp
241eaca6183SJohn BaldwinThe
242eaca6183SJohn Baldwin.Fn atomic_readandclear
2432be6c09fSRuslan Ermilovfunctions are not implemented for the types
2442be6c09fSRuslan Ermilov.Dq Li char ,
2452be6c09fSRuslan Ermilov.Dq Li short ,
2462be6c09fSRuslan Ermilov.Dq Li ptr ,
2472be6c09fSRuslan Ermilov.Dq Li 8 ,
2482be6c09fSRuslan Ermilovand
2492be6c09fSRuslan Ermilov.Dq Li 16
250*8a1ee2d3SJung-uk Kimand do not have any variants with memory barriers at this time.
251eaca6183SJohn Baldwin.Bl -hang
2522be6c09fSRuslan Ermilov.It Fn atomic_set p v
2532be6c09fSRuslan Ermilov.Bd -literal -compact
254eaca6183SJohn Baldwin*p |= v;
255eaca6183SJohn Baldwin.Ed
2562be6c09fSRuslan Ermilov.It Fn atomic_subtract p v
2572be6c09fSRuslan Ermilov.Bd -literal -compact
258eaca6183SJohn Baldwin*p -= v;
259eaca6183SJohn Baldwin.Ed
2602be6c09fSRuslan Ermilov.It Fn atomic_store p v
2612be6c09fSRuslan Ermilov.Bd -literal -compact
262eaca6183SJohn Baldwin*p = v;
263eaca6183SJohn Baldwin.Ed
264eaca6183SJohn Baldwin.El
265eaca6183SJohn Baldwin.Pp
266eaca6183SJohn BaldwinThe
267eaca6183SJohn Baldwin.Fn atomic_store
268e6b08944SJohn Baldwinfunctions are only provided with release memory barriers.
269eaca6183SJohn Baldwin.Pp
270*8a1ee2d3SJung-uk Kim.Bl -hang
271*8a1ee2d3SJung-uk Kim.It Fn atomic_swap p v
272*8a1ee2d3SJung-uk Kim.Bd -literal -compact
273*8a1ee2d3SJung-uk Kimtmp = *p;
274*8a1ee2d3SJung-uk Kim*p = v;
275*8a1ee2d3SJung-uk Kimreturn (tmp);
276*8a1ee2d3SJung-uk Kim.Ed
277*8a1ee2d3SJung-uk Kim.El
278*8a1ee2d3SJung-uk Kim.Pp
279*8a1ee2d3SJung-uk KimThe
280*8a1ee2d3SJung-uk Kim.Fn atomic_swap
281*8a1ee2d3SJung-uk Kimfunctions are not implemented for the types
282*8a1ee2d3SJung-uk Kim.Dq Li char ,
283*8a1ee2d3SJung-uk Kim.Dq Li short ,
284*8a1ee2d3SJung-uk Kim.Dq Li ptr ,
285*8a1ee2d3SJung-uk Kim.Dq Li 8 ,
286*8a1ee2d3SJung-uk Kimand
287*8a1ee2d3SJung-uk Kim.Dq Li 16
288*8a1ee2d3SJung-uk Kimand do not have any variants with memory barriers at this time.
289*8a1ee2d3SJung-uk Kim.Bl -hang
290*8a1ee2d3SJung-uk Kim.It Fn atomic_testandset p v
291*8a1ee2d3SJung-uk Kim.Bd -literal -compact
292*8a1ee2d3SJung-uk Kimbit = 1 << (v % (sizeof(*p) * NBBY));
293*8a1ee2d3SJung-uk Kimtmp = (*p & bit) != 0;
294*8a1ee2d3SJung-uk Kim*p |= bit;
295*8a1ee2d3SJung-uk Kimreturn (tmp);
296*8a1ee2d3SJung-uk Kim.Ed
297*8a1ee2d3SJung-uk Kim.El
298*8a1ee2d3SJung-uk Kim.Pp
299*8a1ee2d3SJung-uk KimThe
300*8a1ee2d3SJung-uk Kim.Fn atomic_testandset
301*8a1ee2d3SJung-uk Kimfunctions are only implemented for the types
302*8a1ee2d3SJung-uk Kim.Dq Li int ,
303*8a1ee2d3SJung-uk Kim.Dq Li long
304*8a1ee2d3SJung-uk Kimand
305*8a1ee2d3SJung-uk Kim.Dq Li 32
306*8a1ee2d3SJung-uk Kimand do not have any variants with memory barriers at this time.
307*8a1ee2d3SJung-uk Kim.Pp
308eaca6183SJohn BaldwinThe type
3092be6c09fSRuslan Ermilov.Dq Li 64
310eaca6183SJohn Baldwinis currently not implemented for any of the atomic operations on the
3114ea211a4SJohn Baldwin.Tn arm ,
3124ea211a4SJohn Baldwin.Tn i386 ,
3134ea211a4SJohn Baldwinand
3144ea211a4SJohn Baldwin.Tn powerpc
3154ea211a4SJohn Baldwinarchitectures.
316eaca6183SJohn Baldwin.Sh RETURN VALUES
3172be6c09fSRuslan ErmilovThe
318eaca6183SJohn Baldwin.Fn atomic_cmpset
319*8a1ee2d3SJung-uk Kimfunction returns the result of the compare operation.
3202be6c09fSRuslan ErmilovThe
3214ea211a4SJohn Baldwin.Fn atomic_fetchadd ,
3224ea211a4SJohn Baldwin.Fn atomic_load ,
323*8a1ee2d3SJung-uk Kim.Fn atomic_readandclear ,
324eaca6183SJohn Baldwinand
325*8a1ee2d3SJung-uk Kim.Fn atomic_swap
326*8a1ee2d3SJung-uk Kimfunctions return the value at the specified address.
327*8a1ee2d3SJung-uk KimThe
328*8a1ee2d3SJung-uk Kim.Fn atomic_testandset
329*8a1ee2d3SJung-uk Kimfunction returns the result of the test operation.
330eaca6183SJohn Baldwin.Sh EXAMPLES
331eaca6183SJohn BaldwinThis example uses the
332eaca6183SJohn Baldwin.Fn atomic_cmpset_acq_ptr
333eaca6183SJohn Baldwinand
334eaca6183SJohn Baldwin.Fn atomic_set_ptr
335eaca6183SJohn Baldwinfunctions to obtain a sleep mutex and handle recursion.
336eaca6183SJohn BaldwinSince the
337eaca6183SJohn Baldwin.Va mtx_lock
338eaca6183SJohn Baldwinmember of a
3392be6c09fSRuslan Ermilov.Vt "struct mtx"
340eaca6183SJohn Baldwinis a pointer, the
3412be6c09fSRuslan Ermilov.Dq Li ptr
342eaca6183SJohn Baldwintype is used.
343eaca6183SJohn Baldwin.Bd -literal
3444ea211a4SJohn Baldwin/* Try to obtain mtx_lock once. */
345eaca6183SJohn Baldwin#define _obtain_lock(mp, tid)						\\
3464ea211a4SJohn Baldwin	atomic_cmpset_acq_ptr(&(mp)->mtx_lock, MTX_UNOWNED, (tid))
347eaca6183SJohn Baldwin
348eaca6183SJohn Baldwin/* Get a sleep lock, deal with recursion inline. */
3494ea211a4SJohn Baldwin#define _get_sleep_lock(mp, tid, opts, file, line) do {			\\
3504ea211a4SJohn Baldwin	uintptr_t _tid = (uintptr_t)(tid);				\\
3514ea211a4SJohn Baldwin									\\
352eaca6183SJohn Baldwin	if (!_obtain_lock(mp, tid)) {					\\
3534ea211a4SJohn Baldwin		if (((mp)->mtx_lock & MTX_FLAGMASK) != _tid)		\\
3544ea211a4SJohn Baldwin			_mtx_lock_sleep((mp), _tid, (opts), (file), (line));\\
355eaca6183SJohn Baldwin		else {							\\
356eaca6183SJohn Baldwin			atomic_set_ptr(&(mp)->mtx_lock, MTX_RECURSE);	\\
357eaca6183SJohn Baldwin			(mp)->mtx_recurse++;				\\
358eaca6183SJohn Baldwin		}							\\
359eaca6183SJohn Baldwin	}								\\
360eaca6183SJohn Baldwin} while (0)
361eaca6183SJohn Baldwin.Ed
362eaca6183SJohn Baldwin.Sh HISTORY
363eaca6183SJohn BaldwinThe
364eaca6183SJohn Baldwin.Fn atomic_add ,
365eaca6183SJohn Baldwin.Fn atomic_clear ,
366eaca6183SJohn Baldwin.Fn atomic_set ,
367eaca6183SJohn Baldwinand
368eaca6183SJohn Baldwin.Fn atomic_subtract
369eaca6183SJohn Baldwinoperations were first introduced in
370eaca6183SJohn Baldwin.Fx 3.0 .
3712be6c09fSRuslan ErmilovThis first set only supported the types
3722be6c09fSRuslan Ermilov.Dq Li char ,
3732be6c09fSRuslan Ermilov.Dq Li short ,
3742be6c09fSRuslan Ermilov.Dq Li int ,
3752be6c09fSRuslan Ermilovand
3762be6c09fSRuslan Ermilov.Dq Li long .
377eaca6183SJohn BaldwinThe
378eaca6183SJohn Baldwin.Fn atomic_cmpset ,
379eaca6183SJohn Baldwin.Fn atomic_load ,
380eaca6183SJohn Baldwin.Fn atomic_readandclear ,
381eaca6183SJohn Baldwinand
382eaca6183SJohn Baldwin.Fn atomic_store
383eaca6183SJohn Baldwinoperations were added in
384eaca6183SJohn Baldwin.Fx 5.0 .
3852be6c09fSRuslan ErmilovThe types
3862be6c09fSRuslan Ermilov.Dq Li 8 ,
3872be6c09fSRuslan Ermilov.Dq Li 16 ,
3882be6c09fSRuslan Ermilov.Dq Li 32 ,
3892be6c09fSRuslan Ermilov.Dq Li 64 ,
3902be6c09fSRuslan Ermilovand
3914ea211a4SJohn Baldwin.Dq Li ptr
3922be6c09fSRuslan Ermilovand all of the acquire and release variants
393eaca6183SJohn Baldwinwere added in
394eaca6183SJohn Baldwin.Fx 5.0
395eaca6183SJohn Baldwinas well.
3964ea211a4SJohn BaldwinThe
3974ea211a4SJohn Baldwin.Fn atomic_fetchadd
3984ea211a4SJohn Baldwinoperations were added in
3994ea211a4SJohn Baldwin.Fx 6.0 .
400*8a1ee2d3SJung-uk KimThe
401*8a1ee2d3SJung-uk Kim.Fn atomic_swap
402*8a1ee2d3SJung-uk Kimand
403*8a1ee2d3SJung-uk Kim.Fn atomic_testandset
404*8a1ee2d3SJung-uk Kimoperations were added in
405*8a1ee2d3SJung-uk Kim.Fx 10.0 .
406