xref: /freebsd/share/man/man9/atomic.9 (revision c645e17a12c9c0a0c000ee26dd2fd64d763886f5)
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.\"
26eaca6183SJohn Baldwin.Dd October 27, 2000
27eaca6183SJohn Baldwin.Os
28eaca6183SJohn Baldwin.Dt ATOMIC 9
29eaca6183SJohn Baldwin.Sh NAME
30eaca6183SJohn Baldwin.Nm atomic_add ,
31eaca6183SJohn Baldwin.Nm atomic_clear ,
32eaca6183SJohn Baldwin.Nm atomic_cmpset ,
33eaca6183SJohn Baldwin.Nm atomic_load ,
34eaca6183SJohn Baldwin.Nm atomic_readandclear ,
35eaca6183SJohn Baldwin.Nm atomic_set ,
36eaca6183SJohn Baldwin.Nm atomic_subtract ,
37eaca6183SJohn Baldwin.Nm atomic_store
38eaca6183SJohn Baldwin.Nd atomic operations
39eaca6183SJohn Baldwin.Sh SYNOPSIS
4032eef9aeSRuslan Ermilov.In sys/types.h
4132eef9aeSRuslan Ermilov.In machine/atomic.h
42eaca6183SJohn Baldwin.Ft void
43baeb94c7SJohn Baldwin.Fn atomic_add_{acq_,rel_,}<type> "volatile <type> *p" "<type> v"
44eaca6183SJohn Baldwin.Ft void
45baeb94c7SJohn Baldwin.Fn atomic_clear_{acq_,rel_,}<type> "volatile <type> *p" "<type> v"
46eaca6183SJohn Baldwin.Ft int
47baeb94c7SJohn Baldwin.Fo atomic_cmpset_{acq_,rel_,}<type>
48eaca6183SJohn Baldwin.Fa "volatile <type> *dst"
49eaca6183SJohn Baldwin.Fa "<type> old"
50eaca6183SJohn Baldwin.Fa "<type> new"
51eaca6183SJohn Baldwin.Fc
52eaca6183SJohn Baldwin.Ft <type>
53eaca6183SJohn Baldwin.Fn atomic_load_acq_<type> "volatile <type> *p"
54eaca6183SJohn Baldwin.Ft <type>
55eaca6183SJohn Baldwin.Fn atomic_readandclear_<type> "volatile <type> *p"
56eaca6183SJohn Baldwin.Ft void
57baeb94c7SJohn Baldwin.Fn atomic_set_{acq_,rel_,}<type> "volatile <type> *p" "<type> v"
58eaca6183SJohn Baldwin.Ft void
59baeb94c7SJohn Baldwin.Fn atomic_subtract_{acq_,rel_,}<type> "volatile <type> *p" "<type> v"
60eaca6183SJohn Baldwin.Ft void
61eaca6183SJohn Baldwin.Fn atomic_store_rel_<type> "volatile <type> *p" "<type> v"
62eaca6183SJohn Baldwin.Sh DESCRIPTION
63eaca6183SJohn BaldwinEach of the atomic operations is guaranteed to be atomic in the presence of
64eaca6183SJohn Baldwininterrupts.
65eaca6183SJohn BaldwinThey can be used to implement reference counts or as building blocks for more
66eaca6183SJohn Baldwinadvanced synchronization primitives such as mutexes.
67eaca6183SJohn Baldwin.Ss Types
68eaca6183SJohn BaldwinEach atomic operation operates on a specific type.
69eaca6183SJohn BaldwinThe type to use is indicated in the function name.
70eaca6183SJohn BaldwinThe available types that can be used are:
71eaca6183SJohn Baldwin.Bl -tag -offset indent -width short
72eaca6183SJohn Baldwin.It int
73eaca6183SJohn Baldwinunsigned integer
74eaca6183SJohn Baldwin.It long
75eaca6183SJohn Baldwinunsigned long integer
76eaca6183SJohn Baldwin.It ptr
77eaca6183SJohn Baldwinunsigned integer the size of a pointer
78eaca6183SJohn Baldwin.It 32
79eaca6183SJohn Baldwinunsigned 32-bit integer
80eaca6183SJohn Baldwin.It 64
81eaca6183SJohn Baldwinunsigned 64-bit integer
82eaca6183SJohn Baldwin.El
83eaca6183SJohn Baldwin.Pp
84eaca6183SJohn BaldwinFor example, the function to atomically add two integers is called
85eaca6183SJohn Baldwin.Fn atomic_add_int .
86c645e17aSJake Burkholder.Pp
87c645e17aSJake BurkholderCertain architectures also provide operations for types smaller than int.
88c645e17aSJake Burkholder.Bl -tag -offset indent -width short
89c645e17aSJake Burkholder.It char
90c645e17aSJake Burkholderunsigned character
91c645e17aSJake Burkholder.It short
92c645e17aSJake Burkholderunsigned short integer
93c645e17aSJake Burkholder.It 8
94c645e17aSJake Burkholderunsigned 8-bit integer
95c645e17aSJake Burkholder.It 16
96c645e17aSJake Burkholderunsigned 16-bit integer
97c645e17aSJake Burkholder.El
98c645e17aSJake Burkholder.Pp
99c645e17aSJake BurkholderThese must not be used in MI code because the instructions to implement them
100c645e17aSJake Burkholderefficiently may not be available.
101eaca6183SJohn Baldwin.Ss Memory Barriers
102eaca6183SJohn BaldwinMemory barriers are used to guarantee the order the order of data accesses in
103eaca6183SJohn Baldwintwo ways.
104eaca6183SJohn BaldwinFirst, they specify hints to the compiler to not re-order or optimize the
105eaca6183SJohn Baldwinoperations.
106eaca6183SJohn BaldwinSecondly, on architectures that do not guarantee ordered data accesses,
107eaca6183SJohn Baldwinspecial instructions or special variants of instructions are used to indicate
108eaca6183SJohn Baldwinto the processor that data accesses need to occur in a certain order.
109eaca6183SJohn BaldwinAs a result, most of the atomic operations have three variants in order to
110eaca6183SJohn Baldwininclude optional memory barriers.
111eaca6183SJohn BaldwinThe first form just performs the operation without any explicit barriers.
112eaca6183SJohn BaldwinThe second form uses a read memory barrier, and the final variant uses a write
113eaca6183SJohn Baldwinmemory barrier.
114eaca6183SJohn Baldwin.Pp
115eaca6183SJohn BaldwinThe second variant of each operation includes a read memory barrier.
116eaca6183SJohn BaldwinThis barrier ensures that the effects of this operation are completed before the
117eaca6183SJohn Baldwineffects of any later data accesses.
118eaca6183SJohn BaldwinAs a result, the operation is said to have acquire semantics as it acquires a
119eaca6183SJohn Baldwinpseudo-lock requiring further operations to wait until it has completed.
120eaca6183SJohn BaldwinTo denote this, the suffix
121eaca6183SJohn Baldwin.Dq _acq
122eaca6183SJohn Baldwinis inserted into the function name immediately prior to the
123eaca6183SJohn Baldwin.Em _type
124eaca6183SJohn Baldwinsuffix.
125eaca6183SJohn BaldwinFor example, to subtract two integers ensuring that any later writes will
126eaca6183SJohn Baldwinhappen after the subtraction is performed, use
127eaca6183SJohn Baldwin.Fn atomic_subtract_acq_int .
128eaca6183SJohn Baldwin.Pp
129eaca6183SJohn BaldwinThe third variant of each operation includes a write memory barrier.
130eaca6183SJohn BaldwinThis ensures that all effects of all previous data accesses are completed
131eaca6183SJohn Baldwinbefore this operation takes place.
132eaca6183SJohn BaldwinAs a result, the operation is said to have release semantics as it releases
133eaca6183SJohn Baldwinany pending data accesses to be completed before its operation is performed.
134eaca6183SJohn BaldwinTo denote this, the suffix
135eaca6183SJohn Baldwin.Dq _rel
136eaca6183SJohn Baldwinis inserted into the function name immediately prior to the
137eaca6183SJohn Baldwin.Em _type
138eaca6183SJohn Baldwinsuffix.
139eaca6183SJohn BaldwinFor example, to add two long integers ensuring that all previous
140eaca6183SJohn Baldwinwrites will happen first, use
141eaca6183SJohn Baldwin.Fn atomic_add_rel_long .
142eaca6183SJohn Baldwin.Pp
143eaca6183SJohn BaldwinA practical example of using memory barriers is to ensure that data accesses
144eaca6183SJohn Baldwinthat are protected by a lock are all performed while the lock is held.
145eaca6183SJohn BaldwinTo achieve this, one would use a read barrier when acquiring the lock to
146eaca6183SJohn Baldwinguarantee that the lock is held before any protected operations are performed.
147eaca6183SJohn BaldwinFinally, one would use a write barrier when releasing the lock to ensure that
148eaca6183SJohn Baldwinall of the protected operations are completed before the lock is released.
149eaca6183SJohn Baldwin.Pp
150eaca6183SJohn Baldwin.Ss Multiple Processors
151eaca6183SJohn BaldwinThe current set of atomic operations do not necessarily guarantee atomicity
152eaca6183SJohn Baldwinacross multiple processors.
153eaca6183SJohn BaldwinTo guarantee atomicity across processors, not only does the individual
154d1ed27b6SJens Schweikhardtoperation need to be atomic on the processor performing the operation, but
155eaca6183SJohn Baldwinthe result of the operation needs to be pushed out to stable storage and the
156eaca6183SJohn Baldwincaches of all other processors on the system need to invalidate any cache
157eaca6183SJohn Baldwinlines that include the affected memory region.
158eaca6183SJohn BaldwinOn the
159eaca6183SJohn Baldwin.Tn i386
160eaca6183SJohn Baldwinarchitecture, the cache coherency model requires that the hardware perform
161eaca6183SJohn Baldwinthis task, thus the atomic operations are atomic across multiple processors.
162eaca6183SJohn BaldwinOn the
163eaca6183SJohn Baldwin.Tn ia64
164eaca6183SJohn Baldwinarchitecture, coherency is only guaranteed for pages that are configured to
165eaca6183SJohn Baldwinusing a caching policy of either uncached or write back.
166eaca6183SJohn Baldwin.Ss Semantics
167eaca6183SJohn BaldwinThis section describes the semantics of each operation using a C like notation.
168eaca6183SJohn Baldwin.Bl -hang
169eaca6183SJohn Baldwin.It Fn atomic_add "p" "v"
170eaca6183SJohn Baldwin.Bd -literal
171eaca6183SJohn Baldwin*p += v;
172eaca6183SJohn Baldwin.Ed
173eaca6183SJohn Baldwin.It Fn atomic_clear "p" "v"
174eaca6183SJohn Baldwin.Bd -literal
175eaca6183SJohn Baldwin*p &= ~v;
176eaca6183SJohn Baldwin.Ed
177eaca6183SJohn Baldwin.It Fn atomic_cmpset "dst" "old" "new"
178eaca6183SJohn Baldwin.Bd -literal
179eaca6183SJohn Baldwinif (*dst == old) {
180eaca6183SJohn Baldwin	*dst = new;
181eaca6183SJohn Baldwin	return 1;
182eaca6183SJohn Baldwin} else
183eaca6183SJohn Baldwin	return 0;
184eaca6183SJohn Baldwin.Ed
185eaca6183SJohn Baldwin.El
186eaca6183SJohn Baldwin.Pp
187eaca6183SJohn BaldwinThe
188eaca6183SJohn Baldwin.Fn atomic_cmpset
189eaca6183SJohn Baldwinfunctions are not implemented for the types char, short, 8, and 16.
190eaca6183SJohn Baldwin.Bl -hang
191eaca6183SJohn Baldwin.It Fn atomic_load "addr"
192eaca6183SJohn Baldwin.Bd -literal
193eaca6183SJohn Baldwinreturn (*addr)
194eaca6183SJohn Baldwin.Ed
195eaca6183SJohn Baldwin.El
196eaca6183SJohn Baldwin.Pp
197eaca6183SJohn BaldwinThe
198eaca6183SJohn Baldwin.Fn atomic_load
199eaca6183SJohn Baldwinfunctions always have acquire semantics.
200eaca6183SJohn Baldwin.Bl -hang
201eaca6183SJohn Baldwin.It Fn atomic_readandclear "addr"
202eaca6183SJohn Baldwin.Bd -literal
203eaca6183SJohn Baldwintemp = *addr;
204eaca6183SJohn Baldwin*addr = 0;
205eaca6183SJohn Baldwinreturn (temp);
206eaca6183SJohn Baldwin.Ed
207eaca6183SJohn Baldwin.El
208eaca6183SJohn Baldwin.Pp
209eaca6183SJohn BaldwinThe
210eaca6183SJohn Baldwin.Fn atomic_readandclear
211eaca6183SJohn Baldwinfunctions are not implemented for the types char, short, ptr, 8, and 16 and do
212eaca6183SJohn Baldwinnot have any variants with memory barriers at this time.
213eaca6183SJohn Baldwin.Bl -hang
214eaca6183SJohn Baldwin.It Fn atomic_set "p" "v"
215eaca6183SJohn Baldwin.Bd -literal
216eaca6183SJohn Baldwin*p |= v;
217eaca6183SJohn Baldwin.Ed
218eaca6183SJohn Baldwin.It Fn atomic_subtract "p" "v"
219eaca6183SJohn Baldwin.Bd -literal
220eaca6183SJohn Baldwin*p -= v;
221eaca6183SJohn Baldwin.Ed
222eaca6183SJohn Baldwin.It Fn atomic_store "p" "v"
223eaca6183SJohn Baldwin.Bd -literal
224eaca6183SJohn Baldwin*p = v;
225eaca6183SJohn Baldwin.Ed
226eaca6183SJohn Baldwin.El
227eaca6183SJohn Baldwin.Pp
228eaca6183SJohn BaldwinThe
229eaca6183SJohn Baldwin.Fn atomic_store
230eaca6183SJohn Baldwinfunctions always have release semantics.
231eaca6183SJohn Baldwin.Pp
232eaca6183SJohn BaldwinThe type
233eaca6183SJohn Baldwin.Dq 64
234eaca6183SJohn Baldwinis currently not implemented for any of the atomic operations on the
235eaca6183SJohn Baldwin.Tn i386
236eaca6183SJohn Baldwinarchitecture.
237eaca6183SJohn Baldwin.Sh RETURN VALUES
238eaca6183SJohn Baldwin.Fn atomic_cmpset
239eaca6183SJohn Baldwinreturns the result of the compare operation.
240eaca6183SJohn Baldwin.Fn atomic_load
241eaca6183SJohn Baldwinand
242eaca6183SJohn Baldwin.Fn atomic_readandclear
243eaca6183SJohn Baldwinreturn the value at the specified address.
244eaca6183SJohn Baldwin.Sh EXAMPLES
245eaca6183SJohn BaldwinThis example uses the
246eaca6183SJohn Baldwin.Fn atomic_cmpset_acq_ptr
247eaca6183SJohn Baldwinand
248eaca6183SJohn Baldwin.Fn atomic_set_ptr
249eaca6183SJohn Baldwinfunctions to obtain a sleep mutex and handle recursion.
250eaca6183SJohn BaldwinSince the
251eaca6183SJohn Baldwin.Va mtx_lock
252eaca6183SJohn Baldwinmember of a
253eaca6183SJohn Baldwin.Li struct mtx
254eaca6183SJohn Baldwinis a pointer, the
255eaca6183SJohn Baldwin.Dq ptr
256eaca6183SJohn Baldwintype is used.
257eaca6183SJohn Baldwin.Bd -literal
258eaca6183SJohn Baldwin#define _obtain_lock(mp, tid)						\\
259eaca6183SJohn Baldwin	atomic_cmpset_acq_ptr(&(mp)->mtx_lock, (void *)MTX_UNOWNED, (tid))
260eaca6183SJohn Baldwin
261eaca6183SJohn Baldwin/* Get a sleep lock, deal with recursion inline. */
262eaca6183SJohn Baldwin#define	_getlock_sleep(mp, tid, type) do {				\\
263eaca6183SJohn Baldwin	if (!_obtain_lock(mp, tid)) {					\\
264eaca6183SJohn Baldwin		if (((mp)->mtx_lock & MTX_FLAGMASK) != ((uintptr_t)(tid)))\\
265eaca6183SJohn Baldwin			mtx_enter_hard(mp, (type) & MTX_HARDOPTS, 0);	\\
266eaca6183SJohn Baldwin		else {							\\
267eaca6183SJohn Baldwin			atomic_set_ptr(&(mp)->mtx_lock, MTX_RECURSE);	\\
268eaca6183SJohn Baldwin			(mp)->mtx_recurse++;				\\
269eaca6183SJohn Baldwin		}							\\
270eaca6183SJohn Baldwin	}								\\
271eaca6183SJohn Baldwin} while (0)
272eaca6183SJohn Baldwin.Ed
273eaca6183SJohn Baldwin.Sh HISTORY
274eaca6183SJohn BaldwinThe
275eaca6183SJohn Baldwin.Fn atomic_add ,
276eaca6183SJohn Baldwin.Fn atomic_clear ,
277eaca6183SJohn Baldwin.Fn atomic_set ,
278eaca6183SJohn Baldwinand
279eaca6183SJohn Baldwin.Fn atomic_subtract
280eaca6183SJohn Baldwinoperations were first introduced in
281eaca6183SJohn Baldwin.Fx 3.0 .
282eaca6183SJohn BaldwinThis first set only suppored the types char, short, int, and long.
283eaca6183SJohn BaldwinThe
284eaca6183SJohn Baldwin.Fn atomic_cmpset ,
285eaca6183SJohn Baldwin.Fn atomic_load ,
286eaca6183SJohn Baldwin.Fn atomic_readandclear ,
287eaca6183SJohn Baldwinand
288eaca6183SJohn Baldwin.Fn atomic_store
289eaca6183SJohn Baldwinoperations were added in
290eaca6183SJohn Baldwin.Fx 5.0 .
291eaca6183SJohn BaldwinThe types 8, 16, 32, 64, and ptr and all of the acquire and release variants
292eaca6183SJohn Baldwinwere added in
293eaca6183SJohn Baldwin.Fx 5.0
294eaca6183SJohn Baldwinas well.
295