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