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