xref: /freebsd/share/man/man9/atomic.9 (revision 3a91d1062a879a73439c9a2209767ca7708e4d8e)
1d265f300SJohn Baldwin.\" Copyright (c) 2000-2001 John H. Baldwin <jhb@FreeBSD.org>
2eaca6183SJohn Baldwin.\"
3eaca6183SJohn Baldwin.\" Redistribution and use in source and binary forms, with or without
4eaca6183SJohn Baldwin.\" modification, are permitted provided that the following conditions
5eaca6183SJohn Baldwin.\" are met:
6eaca6183SJohn Baldwin.\" 1. Redistributions of source code must retain the above copyright
7eaca6183SJohn Baldwin.\"    notice, this list of conditions and the following disclaimer.
8eaca6183SJohn Baldwin.\" 2. Redistributions in binary form must reproduce the above copyright
9eaca6183SJohn Baldwin.\"    notice, this list of conditions and the following disclaimer in the
10eaca6183SJohn Baldwin.\"    documentation and/or other materials provided with the distribution.
11eaca6183SJohn Baldwin.\"
12eaca6183SJohn Baldwin.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
13eaca6183SJohn Baldwin.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
14eaca6183SJohn Baldwin.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
15eaca6183SJohn Baldwin.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
16eaca6183SJohn Baldwin.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
17eaca6183SJohn Baldwin.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
18eaca6183SJohn Baldwin.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
19eaca6183SJohn Baldwin.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20eaca6183SJohn Baldwin.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
21eaca6183SJohn Baldwin.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22eaca6183SJohn Baldwin.\"
23eaca6183SJohn Baldwin.\" $FreeBSD$
24eaca6183SJohn Baldwin.\"
25*3a91d106SKonstantin Belousov.Dd August 18, 2019
26eaca6183SJohn Baldwin.Dt ATOMIC 9
27aa12cea2SUlrich Spörlein.Os
28eaca6183SJohn Baldwin.Sh NAME
29eaca6183SJohn Baldwin.Nm atomic_add ,
30eaca6183SJohn Baldwin.Nm atomic_clear ,
31eaca6183SJohn Baldwin.Nm atomic_cmpset ,
32c0b995bbSMateusz Guzik.Nm atomic_fcmpset ,
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 ,
3822fd1b5dSAlan Cox.Nm atomic_store ,
3922fd1b5dSAlan Cox.Nm atomic_thread_fence
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>
6322fd1b5dSAlan Cox.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
7122fd1b5dSAlan Cox.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"
7822fd1b5dSAlan Cox.Ft void
7922fd1b5dSAlan Cox.Fn atomic_thread_fence_[acq|acq_rel|rel|seq_cst] "void"
80eaca6183SJohn Baldwin.Sh DESCRIPTION
8122fd1b5dSAlan CoxAtomic operations are commonly used to implement reference counts and as
8222fd1b5dSAlan Coxbuilding blocks for synchronization primitives, such as mutexes.
8322fd1b5dSAlan Cox.Pp
8422fd1b5dSAlan CoxAll of these operations are performed
8522fd1b5dSAlan Cox.Em atomically
8622fd1b5dSAlan Coxacross multiple threads and in the presence of interrupts, meaning that they
8722fd1b5dSAlan Coxare performed in an indivisible manner from the perspective of concurrently
88c9b6b582SKonstantin Belousovrunning threads and interrupt handlers.
89c9b6b582SKonstantin Belousov.Pp
9022fd1b5dSAlan CoxOn all architectures supported by
9122fd1b5dSAlan Cox.Fx ,
9222fd1b5dSAlan Coxordinary loads and stores of integers in cache-coherent memory are
9322fd1b5dSAlan Coxinherently atomic if the integer is naturally aligned and its size does not
9422fd1b5dSAlan Coxexceed the processor's word size.
9522fd1b5dSAlan CoxHowever, such loads and stores may be elided from the program by
9622fd1b5dSAlan Coxthe compiler, whereas atomic operations are always performed.
9722fd1b5dSAlan Cox.Pp
98c9b6b582SKonstantin BelousovWhen atomic operations are performed on cache-coherent memory, all
99c9b6b582SKonstantin Belousovoperations on the same location are totally ordered.
100c9b6b582SKonstantin Belousov.Pp
101c9b6b582SKonstantin BelousovWhen an atomic load is performed on a location in cache-coherent memory,
102c9b6b582SKonstantin Belousovit reads the entire value that was defined by the last atomic store to
103c9b6b582SKonstantin Belousoveach byte of the location.
104c9b6b582SKonstantin BelousovAn atomic load will never return a value out of thin air.
105c9b6b582SKonstantin BelousovWhen an atomic store is performed on a location, no other thread or
106c9b6b582SKonstantin Belousovinterrupt handler will observe a
107c9b6b582SKonstantin Belousov.Em torn write ,
108c9b6b582SKonstantin Belousovor partial modification of the location.
109c9b6b582SKonstantin Belousov.Pp
11022fd1b5dSAlan CoxExcept as noted below, the semantics of these operations are almost
11122fd1b5dSAlan Coxidentical to the semantics of similarly named C11 atomic operations.
112eaca6183SJohn Baldwin.Ss Types
11322fd1b5dSAlan CoxMost atomic operations act upon a specific
1140640e9e0SHiten Pandya.Fa type .
11522fd1b5dSAlan CoxThat type is indicated in the function name.
11622fd1b5dSAlan CoxIn contrast to C11 atomic operations,
11722fd1b5dSAlan Cox.Fx Ns 's
11822fd1b5dSAlan Coxatomic operations are performed on ordinary integer types.
11922fd1b5dSAlan CoxThe available types are:
1202be6c09fSRuslan Ermilov.Pp
1212be6c09fSRuslan Ermilov.Bl -tag -offset indent -width short -compact
1222be6c09fSRuslan Ermilov.It Li int
123eaca6183SJohn Baldwinunsigned integer
1242be6c09fSRuslan Ermilov.It Li long
125eaca6183SJohn Baldwinunsigned long integer
1262be6c09fSRuslan Ermilov.It Li ptr
127eaca6183SJohn Baldwinunsigned integer the size of a pointer
1282be6c09fSRuslan Ermilov.It Li 32
129eaca6183SJohn Baldwinunsigned 32-bit integer
1302be6c09fSRuslan Ermilov.It Li 64
131eaca6183SJohn Baldwinunsigned 64-bit integer
132eaca6183SJohn Baldwin.El
133eaca6183SJohn Baldwin.Pp
134eaca6183SJohn BaldwinFor example, the function to atomically add two integers is called
135eaca6183SJohn Baldwin.Fn atomic_add_int .
136c645e17aSJake Burkholder.Pp
1372be6c09fSRuslan ErmilovCertain architectures also provide operations for types smaller than
1382be6c09fSRuslan Ermilov.Dq Li int .
1392be6c09fSRuslan Ermilov.Pp
1402be6c09fSRuslan Ermilov.Bl -tag -offset indent -width short -compact
1412be6c09fSRuslan Ermilov.It Li char
142c645e17aSJake Burkholderunsigned character
1432be6c09fSRuslan Ermilov.It Li short
144c645e17aSJake Burkholderunsigned short integer
1452be6c09fSRuslan Ermilov.It Li 8
146c645e17aSJake Burkholderunsigned 8-bit integer
1472be6c09fSRuslan Ermilov.It Li 16
148c645e17aSJake Burkholderunsigned 16-bit integer
149c645e17aSJake Burkholder.El
150c645e17aSJake Burkholder.Pp
15122fd1b5dSAlan CoxThese types must not be used in machine-independent code.
152cff0a327SAlan Cox.Ss Acquire and Release Operations
153cff0a327SAlan CoxBy default, a thread's accesses to different memory locations might not be
154cff0a327SAlan Coxperformed in
155cff0a327SAlan Cox.Em program order ,
156cff0a327SAlan Coxthat is, the order in which the accesses appear in the source code.
157cff0a327SAlan CoxTo optimize the program's execution, both the compiler and processor might
158cff0a327SAlan Coxreorder the thread's accesses.
159cff0a327SAlan CoxHowever, both ensure that their reordering of the accesses is not visible to
160cff0a327SAlan Coxthe thread.
161cff0a327SAlan CoxOtherwise, the traditional memory model that is expected by single-threaded
162cff0a327SAlan Coxprograms would be violated.
163cff0a327SAlan CoxNonetheless, other threads in a multithreaded program, such as the
164cff0a327SAlan Cox.Fx
165cff0a327SAlan Coxkernel, might observe the reordering.
166cff0a327SAlan CoxMoreover, in some cases, such as the implementation of synchronization between
167cff0a327SAlan Coxthreads, arbitrary reordering might result in the incorrect execution of the
168cff0a327SAlan Coxprogram.
169cff0a327SAlan CoxTo constrain the reordering that both the compiler and processor might perform
17022fd1b5dSAlan Coxon a thread's accesses, a programmer can use atomic operations with
17177054356SKonstantin Belousov.Em acquire
172cff0a327SAlan Coxand
173cff0a327SAlan Cox.Em release
174cff0a327SAlan Coxsemantics.
175cff0a327SAlan Cox.Pp
17622fd1b5dSAlan CoxAtomic operations on memory have up to three variants.
17777863e4bSKonstantin BelousovThe first, or
17877863e4bSKonstantin Belousov.Em relaxed
17977863e4bSKonstantin Belousovvariant, performs the operation without imposing any ordering constraints on
18077863e4bSKonstantin Belousovaccesses to other memory locations.
18177863e4bSKonstantin BelousovThis variant is the default.
182cff0a327SAlan CoxThe second variant has acquire semantics, and the third variant has release
183cff0a327SAlan Coxsemantics.
184cff0a327SAlan Cox.Pp
18522fd1b5dSAlan CoxWhen an atomic operation has acquire semantics, the operation must have
18622fd1b5dSAlan Coxcompleted before any subsequent load or store (by program order) is
187cff0a327SAlan Coxperformed.
188cff0a327SAlan CoxConversely, acquire semantics do not require that prior loads or stores have
189cff0a327SAlan Coxcompleted before the atomic operation is performed.
19022fd1b5dSAlan CoxAn atomic operation can only have acquire semantics if it performs a load
19122fd1b5dSAlan Coxfrom memory.
192cff0a327SAlan CoxTo denote acquire semantics, the suffix
1932be6c09fSRuslan Ermilov.Dq Li _acq
194eaca6183SJohn Baldwinis inserted into the function name immediately prior to the
1950640e9e0SHiten Pandya.Dq Li _ Ns Aq Fa type
196eaca6183SJohn Baldwinsuffix.
19722fd1b5dSAlan CoxFor example, to subtract two integers ensuring that the subtraction is
19822fd1b5dSAlan Coxcompleted before any subsequent loads and stores are performed, use
199eaca6183SJohn Baldwin.Fn atomic_subtract_acq_int .
200eaca6183SJohn Baldwin.Pp
20122fd1b5dSAlan CoxWhen an atomic operation has release semantics, all prior loads or stores
20222fd1b5dSAlan Cox(by program order) must have completed before the operation is performed.
20322fd1b5dSAlan CoxConversely, release semantics do not require that the atomic operation must
20422fd1b5dSAlan Coxhave completed before any subsequent load or store is performed.
20522fd1b5dSAlan CoxAn atomic operation can only have release semantics if it performs a store
20622fd1b5dSAlan Coxto memory.
207cff0a327SAlan CoxTo denote release semantics, the suffix
2082be6c09fSRuslan Ermilov.Dq Li _rel
209eaca6183SJohn Baldwinis inserted into the function name immediately prior to the
2100640e9e0SHiten Pandya.Dq Li _ Ns Aq Fa type
211eaca6183SJohn Baldwinsuffix.
212cff0a327SAlan CoxFor example, to add two long integers ensuring that all prior loads and
21322fd1b5dSAlan Coxstores are completed before the addition is performed, use
214eaca6183SJohn Baldwin.Fn atomic_add_rel_long .
215eaca6183SJohn Baldwin.Pp
21622fd1b5dSAlan CoxWhen a release operation by one thread
21722fd1b5dSAlan Cox.Em synchronizes with
21822fd1b5dSAlan Coxan acquire operation by another thread, usually meaning that the acquire
21922fd1b5dSAlan Coxoperation reads the value written by the release operation, then the effects
22022fd1b5dSAlan Coxof all prior stores by the releasing thread must become visible to
22122fd1b5dSAlan Coxsubsequent loads by the acquiring thread.
22222fd1b5dSAlan CoxMoreover, the effects of all stores (by other threads) that were visible to
22322fd1b5dSAlan Coxthe releasing thread must also become visible to the acquiring thread.
22422fd1b5dSAlan CoxThese rules only apply to the synchronizing threads.
22522fd1b5dSAlan CoxOther threads might observe these stores in a different order.
22622fd1b5dSAlan Cox.Pp
22722fd1b5dSAlan CoxIn effect, atomic operations with acquire and release semantics establish
22822fd1b5dSAlan Coxone-way barriers to reordering that enable the implementations of
22922fd1b5dSAlan Coxsynchronization primitives to express their ordering requirements without
23022fd1b5dSAlan Coxalso imposing unnecessary ordering.
231cff0a327SAlan CoxFor example, for a critical section guarded by a mutex, an acquire operation
232cff0a327SAlan Coxwhen the mutex is locked and a release operation when the mutex is unlocked
233cff0a327SAlan Coxwill prevent any loads or stores from moving outside of the critical
234cff0a327SAlan Coxsection.
235cff0a327SAlan CoxHowever, they will not prevent the compiler or processor from moving loads
236cff0a327SAlan Coxor stores into the critical section, which does not violate the semantics of
237cff0a327SAlan Coxa mutex.
23822fd1b5dSAlan Cox.Ss Thread Fence Operations
23922fd1b5dSAlan CoxAlternatively, a programmer can use atomic thread fence operations to
24022fd1b5dSAlan Coxconstrain the reordering of accesses.
24122fd1b5dSAlan CoxIn contrast to other atomic operations, fences do not, themselves, access
24222fd1b5dSAlan Coxmemory.
24322fd1b5dSAlan Cox.Pp
24422fd1b5dSAlan CoxWhen a fence has acquire semantics, all prior loads (by program order) must
24522fd1b5dSAlan Coxhave completed before any subsequent load or store is performed.
24622fd1b5dSAlan CoxThus, an acquire fence is a two-way barrier for load operations.
24722fd1b5dSAlan CoxTo denote acquire semantics, the suffix
24822fd1b5dSAlan Cox.Dq Li _acq
24922fd1b5dSAlan Coxis appended to the function name, for example,
25022fd1b5dSAlan Cox.Fn atomic_thread_fence_acq .
25122fd1b5dSAlan Cox.Pp
25222fd1b5dSAlan CoxWhen a fence has release semantics, all prior loads or stores (by program
25322fd1b5dSAlan Coxorder) must have completed before any subsequent store operation is
25422fd1b5dSAlan Coxperformed.
25522fd1b5dSAlan CoxThus, a release fence is a two-way barrier for store operations.
25622fd1b5dSAlan CoxTo denote release semantics, the suffix
25722fd1b5dSAlan Cox.Dq Li _rel
25822fd1b5dSAlan Coxis appended to the function name, for example,
25922fd1b5dSAlan Cox.Fn atomic_thread_fence_rel .
26022fd1b5dSAlan Cox.Pp
26122fd1b5dSAlan CoxAlthough
26222fd1b5dSAlan Cox.Fn atomic_thread_fence_acq_rel
26322fd1b5dSAlan Coximplements both acquire and release semantics, it is not a full barrier.
26422fd1b5dSAlan CoxFor example, a store prior to the fence (in program order) may be completed
26522fd1b5dSAlan Coxafter a load subsequent to the fence.
26622fd1b5dSAlan CoxIn contrast,
26722fd1b5dSAlan Cox.Fn atomic_thread_fence_seq_cst
26822fd1b5dSAlan Coximplements a full barrier.
26922fd1b5dSAlan CoxNeither loads nor stores may cross this barrier in either direction.
27022fd1b5dSAlan Cox.Pp
27122fd1b5dSAlan CoxIn C11, a release fence by one thread synchronizes with an acquire fence by
27222fd1b5dSAlan Coxanother thread when an atomic load that is prior to the acquire fence (by
27322fd1b5dSAlan Coxprogram order) reads the value written by an atomic store that is subsequent
27422fd1b5dSAlan Coxto the release fence.
27522fd1b5dSAlan CoxIn constrast, in FreeBSD, because of the atomicity of ordinary, naturally
27622fd1b5dSAlan Coxaligned loads and stores, fences can also be synchronized by ordinary loads
27722fd1b5dSAlan Coxand stores.
27822fd1b5dSAlan CoxThis simplifies the implementation and use of some synchronization
27922fd1b5dSAlan Coxprimitives in
28022fd1b5dSAlan Cox.Fx .
28122fd1b5dSAlan Cox.Pp
28222fd1b5dSAlan CoxSince neither a compiler nor a processor can foresee which (atomic) load
28322fd1b5dSAlan Coxwill read the value written by an (atomic) store, the ordering constraints
28422fd1b5dSAlan Coximposed by fences must be more restrictive than acquire loads and release
28522fd1b5dSAlan Coxstores.
28622fd1b5dSAlan CoxEssentially, this is why fences are two-way barriers.
28722fd1b5dSAlan Cox.Pp
28822fd1b5dSAlan CoxAlthough fences impose more restrictive ordering than acquire loads and
28922fd1b5dSAlan Coxrelease stores, by separating access from ordering, they can sometimes
29022fd1b5dSAlan Coxfacilitate more efficient implementations of synchronization primitives.
29122fd1b5dSAlan CoxFor example, they can be used to avoid executing a memory barrier until a
29222fd1b5dSAlan Coxmemory access shows that some condition is satisfied.
293eaca6183SJohn Baldwin.Ss Multiple Processors
294a61bd957SAlan CoxIn multiprocessor systems, the atomicity of the atomic operations on memory
295a61bd957SAlan Coxdepends on support for cache coherence in the underlying architecture.
296a61bd957SAlan CoxIn general, cache coherence on the default memory type,
297a61bd957SAlan Cox.Dv VM_MEMATTR_DEFAULT ,
298a61bd957SAlan Coxis guaranteed by all architectures that are supported by
299a61bd957SAlan Cox.Fx .
300a61bd957SAlan CoxFor example, cache coherence is guaranteed on write-back memory by the
301a61bd957SAlan Cox.Tn amd64
302a61bd957SAlan Coxand
303eaca6183SJohn Baldwin.Tn i386
304a61bd957SAlan Coxarchitectures.
305cff0a327SAlan CoxHowever, on some architectures, cache coherence might not be enabled on all
306a61bd957SAlan Coxmemory types.
307a61bd957SAlan CoxTo determine if cache coherence is enabled for a non-default memory type,
308a61bd957SAlan Coxconsult the architecture's documentation.
309eaca6183SJohn Baldwin.Ss Semantics
310eaca6183SJohn BaldwinThis section describes the semantics of each operation using a C like notation.
311eaca6183SJohn Baldwin.Bl -hang
3122be6c09fSRuslan Ermilov.It Fn atomic_add p v
3132be6c09fSRuslan Ermilov.Bd -literal -compact
314eaca6183SJohn Baldwin*p += v;
315eaca6183SJohn Baldwin.Ed
3162be6c09fSRuslan Ermilov.It Fn atomic_clear p v
3172be6c09fSRuslan Ermilov.Bd -literal -compact
318eaca6183SJohn Baldwin*p &= ~v;
319eaca6183SJohn Baldwin.Ed
3202be6c09fSRuslan Ermilov.It Fn atomic_cmpset dst old new
3212be6c09fSRuslan Ermilov.Bd -literal -compact
322eaca6183SJohn Baldwinif (*dst == old) {
323eaca6183SJohn Baldwin	*dst = new;
3248a1ee2d3SJung-uk Kim	return (1);
325eaca6183SJohn Baldwin} else
3268a1ee2d3SJung-uk Kim	return (0);
327eaca6183SJohn Baldwin.Ed
328eaca6183SJohn Baldwin.El
329eaca6183SJohn Baldwin.Pp
3303d673254SMark JohnstonSome architectures do not implement the
331eaca6183SJohn Baldwin.Fn atomic_cmpset
3323d673254SMark Johnstonfunctions for the types
3332be6c09fSRuslan Ermilov.Dq Li char ,
3342be6c09fSRuslan Ermilov.Dq Li short ,
3352be6c09fSRuslan Ermilov.Dq Li 8 ,
3362be6c09fSRuslan Ermilovand
3372be6c09fSRuslan Ermilov.Dq Li 16 .
338eaca6183SJohn Baldwin.Bl -hang
339c0b995bbSMateusz Guzik.It Fn atomic_fcmpset dst *old new
340c0b995bbSMateusz Guzik.El
341c0b995bbSMateusz Guzik.Pp
342c0b995bbSMateusz GuzikOn architectures implementing
343c0b995bbSMateusz Guzik.Em Compare And Swap
344c0b995bbSMateusz Guzikoperation in hardware, the functionality can be described as
345c0b995bbSMateusz Guzik.Bd -literal -offset indent -compact
346c0b995bbSMateusz Guzikif (*dst == *old) {
347c0b995bbSMateusz Guzik	*dst = new;
348c0b995bbSMateusz Guzik	return (1);
349c0b995bbSMateusz Guzik} else {
350c0b995bbSMateusz Guzik	*old = *dst;
351c0b995bbSMateusz Guzik	return (0);
352c0b995bbSMateusz Guzik}
353c0b995bbSMateusz Guzik.Ed
354c0b995bbSMateusz GuzikOn architectures which provide
355c0b995bbSMateusz Guzik.Em Load Linked/Store Conditional
356c0b995bbSMateusz Guzikprimitive, the write to
357c0b995bbSMateusz Guzik.Dv *dst
358c0b995bbSMateusz Guzikmight also fail for several reasons, most important of which
359c0b995bbSMateusz Guzikis a parallel write to
360c0b995bbSMateusz Guzik.Dv *dst
361c0b995bbSMateusz Guzikcache line by other CPU.
362c0b995bbSMateusz GuzikIn this case
363c0b995bbSMateusz Guzik.Fn atomic_fcmpset
364c0b995bbSMateusz Guzikfunction also returns
365c0b995bbSMateusz Guzik.Dv false ,
366c0b995bbSMateusz Guzikdespite
367c0b995bbSMateusz Guzik.Dl *old == *dst .
368c0b995bbSMateusz Guzik.Pp
3693d673254SMark JohnstonSome architectures do not implement the
370c0b995bbSMateusz Guzik.Fn atomic_fcmpset
3713d673254SMark Johnstonfunctions for the types
372c0b995bbSMateusz Guzik.Dq Li char ,
373c0b995bbSMateusz Guzik.Dq Li short ,
374c0b995bbSMateusz Guzik.Dq Li 8 ,
375c0b995bbSMateusz Guzikand
376c0b995bbSMateusz Guzik.Dq Li 16 .
377c0b995bbSMateusz Guzik.Bl -hang
3784ea211a4SJohn Baldwin.It Fn atomic_fetchadd p v
3794ea211a4SJohn Baldwin.Bd -literal -compact
3804ea211a4SJohn Baldwintmp = *p;
3814ea211a4SJohn Baldwin*p += v;
3828a1ee2d3SJung-uk Kimreturn (tmp);
3834ea211a4SJohn Baldwin.Ed
3844ea211a4SJohn Baldwin.El
3854ea211a4SJohn Baldwin.Pp
3864ea211a4SJohn BaldwinThe
3874ea211a4SJohn Baldwin.Fn atomic_fetchadd
3884ea211a4SJohn Baldwinfunctions are only implemented for the types
3896eb4157fSPawel Jakub Dawidek.Dq Li int ,
3906eb4157fSPawel Jakub Dawidek.Dq Li long
3914ea211a4SJohn Baldwinand
3924ea211a4SJohn Baldwin.Dq Li 32
3934ea211a4SJohn Baldwinand do not have any variants with memory barriers at this time.
3944ea211a4SJohn Baldwin.Bl -hang
3958a1ee2d3SJung-uk Kim.It Fn atomic_load p
3962be6c09fSRuslan Ermilov.Bd -literal -compact
3978a1ee2d3SJung-uk Kimreturn (*p);
398eaca6183SJohn Baldwin.Ed
3998a1ee2d3SJung-uk Kim.It Fn atomic_readandclear p
4002be6c09fSRuslan Ermilov.Bd -literal -compact
4018a1ee2d3SJung-uk Kimtmp = *p;
4028a1ee2d3SJung-uk Kim*p = 0;
4038a1ee2d3SJung-uk Kimreturn (tmp);
404eaca6183SJohn Baldwin.Ed
405eaca6183SJohn Baldwin.El
406eaca6183SJohn Baldwin.Pp
407eaca6183SJohn BaldwinThe
408eaca6183SJohn Baldwin.Fn atomic_readandclear
4092be6c09fSRuslan Ermilovfunctions are not implemented for the types
4102be6c09fSRuslan Ermilov.Dq Li char ,
4112be6c09fSRuslan Ermilov.Dq Li short ,
4122be6c09fSRuslan Ermilov.Dq Li ptr ,
4132be6c09fSRuslan Ermilov.Dq Li 8 ,
4142be6c09fSRuslan Ermilovand
4152be6c09fSRuslan Ermilov.Dq Li 16
4168a1ee2d3SJung-uk Kimand do not have any variants with memory barriers at this time.
417eaca6183SJohn Baldwin.Bl -hang
4182be6c09fSRuslan Ermilov.It Fn atomic_set p v
4192be6c09fSRuslan Ermilov.Bd -literal -compact
420eaca6183SJohn Baldwin*p |= v;
421eaca6183SJohn Baldwin.Ed
4222be6c09fSRuslan Ermilov.It Fn atomic_subtract p v
4232be6c09fSRuslan Ermilov.Bd -literal -compact
424eaca6183SJohn Baldwin*p -= v;
425eaca6183SJohn Baldwin.Ed
4262be6c09fSRuslan Ermilov.It Fn atomic_store p v
4272be6c09fSRuslan Ermilov.Bd -literal -compact
428eaca6183SJohn Baldwin*p = v;
429eaca6183SJohn Baldwin.Ed
4308a1ee2d3SJung-uk Kim.It Fn atomic_swap p v
4318a1ee2d3SJung-uk Kim.Bd -literal -compact
4328a1ee2d3SJung-uk Kimtmp = *p;
4338a1ee2d3SJung-uk Kim*p = v;
4348a1ee2d3SJung-uk Kimreturn (tmp);
4358a1ee2d3SJung-uk Kim.Ed
4368a1ee2d3SJung-uk Kim.El
4378a1ee2d3SJung-uk Kim.Pp
4388a1ee2d3SJung-uk KimThe
4398a1ee2d3SJung-uk Kim.Fn atomic_swap
4408a1ee2d3SJung-uk Kimfunctions are not implemented for the types
4418a1ee2d3SJung-uk Kim.Dq Li char ,
4428a1ee2d3SJung-uk Kim.Dq Li short ,
4438a1ee2d3SJung-uk Kim.Dq Li ptr ,
4448a1ee2d3SJung-uk Kim.Dq Li 8 ,
4458a1ee2d3SJung-uk Kimand
4468a1ee2d3SJung-uk Kim.Dq Li 16
4478a1ee2d3SJung-uk Kimand do not have any variants with memory barriers at this time.
4488a1ee2d3SJung-uk Kim.Bl -hang
449dfdc9a05SSepherosa Ziehau.It Fn atomic_testandclear p v
450dfdc9a05SSepherosa Ziehau.Bd -literal -compact
451dfdc9a05SSepherosa Ziehaubit = 1 << (v % (sizeof(*p) * NBBY));
452dfdc9a05SSepherosa Ziehautmp = (*p & bit) != 0;
453dfdc9a05SSepherosa Ziehau*p &= ~bit;
454dfdc9a05SSepherosa Ziehaureturn (tmp);
455dfdc9a05SSepherosa Ziehau.Ed
456dfdc9a05SSepherosa Ziehau.El
457dfdc9a05SSepherosa Ziehau.Bl -hang
4588a1ee2d3SJung-uk Kim.It Fn atomic_testandset p v
4598a1ee2d3SJung-uk Kim.Bd -literal -compact
4608a1ee2d3SJung-uk Kimbit = 1 << (v % (sizeof(*p) * NBBY));
4618a1ee2d3SJung-uk Kimtmp = (*p & bit) != 0;
4628a1ee2d3SJung-uk Kim*p |= bit;
4638a1ee2d3SJung-uk Kimreturn (tmp);
4648a1ee2d3SJung-uk Kim.Ed
4658a1ee2d3SJung-uk Kim.El
4668a1ee2d3SJung-uk Kim.Pp
4678a1ee2d3SJung-uk KimThe
4688a1ee2d3SJung-uk Kim.Fn atomic_testandset
469dfdc9a05SSepherosa Ziehauand
470dfdc9a05SSepherosa Ziehau.Fn atomic_testandclear
4718a1ee2d3SJung-uk Kimfunctions are only implemented for the types
4728a1ee2d3SJung-uk Kim.Dq Li int ,
4738a1ee2d3SJung-uk Kim.Dq Li long
4748a1ee2d3SJung-uk Kimand
4758a1ee2d3SJung-uk Kim.Dq Li 32
4768a1ee2d3SJung-uk Kimand do not have any variants with memory barriers at this time.
4778a1ee2d3SJung-uk Kim.Pp
478eaca6183SJohn BaldwinThe type
4792be6c09fSRuslan Ermilov.Dq Li 64
480*3a91d106SKonstantin Belousovis currently not implemented for some of the atomic operations on the
4814ea211a4SJohn Baldwin.Tn arm ,
4824ea211a4SJohn Baldwin.Tn i386 ,
4834ea211a4SJohn Baldwinand
4844ea211a4SJohn Baldwin.Tn powerpc
4854ea211a4SJohn Baldwinarchitectures.
486eaca6183SJohn Baldwin.Sh RETURN VALUES
4872be6c09fSRuslan ErmilovThe
488eaca6183SJohn Baldwin.Fn atomic_cmpset
4898a1ee2d3SJung-uk Kimfunction returns the result of the compare operation.
4902be6c09fSRuslan ErmilovThe
491c0b995bbSMateusz Guzik.Fn atomic_fcmpset
492c0b995bbSMateusz Guzikfunction returns
493c0b995bbSMateusz Guzik.Dv true
49468278ec6SBenjamin Kadukif the operation succeeded.
495c0b995bbSMateusz GuzikOtherwise it returns
496c0b995bbSMateusz Guzik.Dv false
497c0b995bbSMateusz Guzikand sets
498c0b995bbSMateusz Guzik.Va *old
499c0b995bbSMateusz Guzikto the found value.
500c0b995bbSMateusz GuzikThe
5014ea211a4SJohn Baldwin.Fn atomic_fetchadd ,
5024ea211a4SJohn Baldwin.Fn atomic_load ,
5038a1ee2d3SJung-uk Kim.Fn atomic_readandclear ,
504eaca6183SJohn Baldwinand
5058a1ee2d3SJung-uk Kim.Fn atomic_swap
5068a1ee2d3SJung-uk Kimfunctions return the value at the specified address.
5078a1ee2d3SJung-uk KimThe
5088a1ee2d3SJung-uk Kim.Fn atomic_testandset
509dfdc9a05SSepherosa Ziehauand
510dfdc9a05SSepherosa Ziehau.Fn atomic_testandclear
5118a1ee2d3SJung-uk Kimfunction returns the result of the test operation.
512eaca6183SJohn Baldwin.Sh EXAMPLES
513eaca6183SJohn BaldwinThis example uses the
514eaca6183SJohn Baldwin.Fn atomic_cmpset_acq_ptr
515eaca6183SJohn Baldwinand
516eaca6183SJohn Baldwin.Fn atomic_set_ptr
517eaca6183SJohn Baldwinfunctions to obtain a sleep mutex and handle recursion.
518eaca6183SJohn BaldwinSince the
519eaca6183SJohn Baldwin.Va mtx_lock
520eaca6183SJohn Baldwinmember of a
5212be6c09fSRuslan Ermilov.Vt "struct mtx"
522eaca6183SJohn Baldwinis a pointer, the
5232be6c09fSRuslan Ermilov.Dq Li ptr
524eaca6183SJohn Baldwintype is used.
525eaca6183SJohn Baldwin.Bd -literal
5264ea211a4SJohn Baldwin/* Try to obtain mtx_lock once. */
527eaca6183SJohn Baldwin#define _obtain_lock(mp, tid)						\\
5284ea211a4SJohn Baldwin	atomic_cmpset_acq_ptr(&(mp)->mtx_lock, MTX_UNOWNED, (tid))
529eaca6183SJohn Baldwin
530eaca6183SJohn Baldwin/* Get a sleep lock, deal with recursion inline. */
5314ea211a4SJohn Baldwin#define _get_sleep_lock(mp, tid, opts, file, line) do {			\\
5324ea211a4SJohn Baldwin	uintptr_t _tid = (uintptr_t)(tid);				\\
5334ea211a4SJohn Baldwin									\\
534eaca6183SJohn Baldwin	if (!_obtain_lock(mp, tid)) {					\\
5354ea211a4SJohn Baldwin		if (((mp)->mtx_lock & MTX_FLAGMASK) != _tid)		\\
5364ea211a4SJohn Baldwin			_mtx_lock_sleep((mp), _tid, (opts), (file), (line));\\
537eaca6183SJohn Baldwin		else {							\\
538eaca6183SJohn Baldwin			atomic_set_ptr(&(mp)->mtx_lock, MTX_RECURSE);	\\
539eaca6183SJohn Baldwin			(mp)->mtx_recurse++;				\\
540eaca6183SJohn Baldwin		}							\\
541eaca6183SJohn Baldwin	}								\\
542eaca6183SJohn Baldwin} while (0)
543eaca6183SJohn Baldwin.Ed
544eaca6183SJohn Baldwin.Sh HISTORY
545eaca6183SJohn BaldwinThe
546eaca6183SJohn Baldwin.Fn atomic_add ,
547eaca6183SJohn Baldwin.Fn atomic_clear ,
548eaca6183SJohn Baldwin.Fn atomic_set ,
549eaca6183SJohn Baldwinand
550eaca6183SJohn Baldwin.Fn atomic_subtract
55177863e4bSKonstantin Belousovoperations were introduced in
552eaca6183SJohn Baldwin.Fx 3.0 .
55377863e4bSKonstantin BelousovInitially, these operations were defined on the types
5542be6c09fSRuslan Ermilov.Dq Li char ,
5552be6c09fSRuslan Ermilov.Dq Li short ,
5562be6c09fSRuslan Ermilov.Dq Li int ,
5572be6c09fSRuslan Ermilovand
5582be6c09fSRuslan Ermilov.Dq Li long .
55977863e4bSKonstantin Belousov.Pp
560eaca6183SJohn BaldwinThe
561eaca6183SJohn Baldwin.Fn atomic_cmpset ,
56277863e4bSKonstantin Belousov.Fn atomic_load_acq ,
563eaca6183SJohn Baldwin.Fn atomic_readandclear ,
564eaca6183SJohn Baldwinand
56577863e4bSKonstantin Belousov.Fn atomic_store_rel
566eaca6183SJohn Baldwinoperations were added in
567eaca6183SJohn Baldwin.Fx 5.0 .
56877863e4bSKonstantin BelousovSimultaneously, the acquire and release variants were introduced, and
56977863e4bSKonstantin Belousovsupport was added for operation on the types
5702be6c09fSRuslan Ermilov.Dq Li 8 ,
5712be6c09fSRuslan Ermilov.Dq Li 16 ,
5722be6c09fSRuslan Ermilov.Dq Li 32 ,
5732be6c09fSRuslan Ermilov.Dq Li 64 ,
5742be6c09fSRuslan Ermilovand
57577863e4bSKonstantin Belousov.Dq Li ptr .
57677863e4bSKonstantin Belousov.Pp
5774ea211a4SJohn BaldwinThe
5784ea211a4SJohn Baldwin.Fn atomic_fetchadd
57977863e4bSKonstantin Belousovoperation was added in
5804ea211a4SJohn Baldwin.Fx 6.0 .
58177863e4bSKonstantin Belousov.Pp
5828a1ee2d3SJung-uk KimThe
5838a1ee2d3SJung-uk Kim.Fn atomic_swap
5848a1ee2d3SJung-uk Kimand
5858a1ee2d3SJung-uk Kim.Fn atomic_testandset
5868a1ee2d3SJung-uk Kimoperations were added in
5878a1ee2d3SJung-uk Kim.Fx 10.0 .
58877863e4bSKonstantin Belousov.Pp
58977863e4bSKonstantin BelousovThe
590dfdc9a05SSepherosa Ziehau.Fn atomic_testandclear
59177863e4bSKonstantin Belousovand
59277863e4bSKonstantin Belousov.Fn atomic_thread_fence
59377863e4bSKonstantin Belousovoperations were added in
594dfdc9a05SSepherosa Ziehau.Fx 11.0 .
59577863e4bSKonstantin Belousov.Pp
59677863e4bSKonstantin BelousovThe relaxed variants of
59777863e4bSKonstantin Belousov.Fn atomic_load
59877863e4bSKonstantin Belousovand
59977863e4bSKonstantin Belousov.Fn atomic_store
60077863e4bSKonstantin Belousovwere added in
60177863e4bSKonstantin Belousov.Fx 12.0 .
602