1d265f300SJohn Baldwin.\" Copyright (c) 2000-2001 John H. Baldwin <jhb@FreeBSD.org> 2eaca6183SJohn Baldwin.\" All rights reserved. 3eaca6183SJohn Baldwin.\" 4eaca6183SJohn Baldwin.\" Redistribution and use in source and binary forms, with or without 5eaca6183SJohn Baldwin.\" modification, are permitted provided that the following conditions 6eaca6183SJohn Baldwin.\" are met: 7eaca6183SJohn Baldwin.\" 1. Redistributions of source code must retain the above copyright 8eaca6183SJohn Baldwin.\" notice, this list of conditions and the following disclaimer. 9eaca6183SJohn Baldwin.\" 2. Redistributions in binary form must reproduce the above copyright 10eaca6183SJohn Baldwin.\" notice, this list of conditions and the following disclaimer in the 11eaca6183SJohn Baldwin.\" documentation and/or other materials provided with the distribution. 12eaca6183SJohn Baldwin.\" 13eaca6183SJohn Baldwin.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR 14eaca6183SJohn Baldwin.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 15eaca6183SJohn Baldwin.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 16eaca6183SJohn Baldwin.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, 17eaca6183SJohn Baldwin.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 18eaca6183SJohn Baldwin.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 19eaca6183SJohn Baldwin.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 20eaca6183SJohn Baldwin.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21eaca6183SJohn Baldwin.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22eaca6183SJohn Baldwin.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23eaca6183SJohn Baldwin.\" 24eaca6183SJohn Baldwin.\" $FreeBSD$ 25eaca6183SJohn Baldwin.\" 26*a61bd957SAlan Cox.Dd August 9, 2015 27eaca6183SJohn Baldwin.Dt ATOMIC 9 28aa12cea2SUlrich Spörlein.Os 29eaca6183SJohn Baldwin.Sh NAME 30eaca6183SJohn Baldwin.Nm atomic_add , 31eaca6183SJohn Baldwin.Nm atomic_clear , 32eaca6183SJohn Baldwin.Nm atomic_cmpset , 334ea211a4SJohn Baldwin.Nm atomic_fetchadd , 34eaca6183SJohn Baldwin.Nm atomic_load , 35eaca6183SJohn Baldwin.Nm atomic_readandclear , 36eaca6183SJohn Baldwin.Nm atomic_set , 37eaca6183SJohn Baldwin.Nm atomic_subtract , 38eaca6183SJohn Baldwin.Nm atomic_store 39eaca6183SJohn Baldwin.Nd atomic operations 40eaca6183SJohn Baldwin.Sh SYNOPSIS 4132eef9aeSRuslan Ermilov.In sys/types.h 4232eef9aeSRuslan Ermilov.In machine/atomic.h 43eaca6183SJohn Baldwin.Ft void 44c6a51f1cSRuslan Ermilov.Fn atomic_add_[acq_|rel_]<type> "volatile <type> *p" "<type> v" 45eaca6183SJohn Baldwin.Ft void 46c6a51f1cSRuslan Ermilov.Fn atomic_clear_[acq_|rel_]<type> "volatile <type> *p" "<type> v" 47eaca6183SJohn Baldwin.Ft int 48c6a51f1cSRuslan Ermilov.Fo atomic_cmpset_[acq_|rel_]<type> 49c6a51f1cSRuslan Ermilov.Fa "volatile <type> *dst" 50c6a51f1cSRuslan Ermilov.Fa "<type> old" 51c6a51f1cSRuslan Ermilov.Fa "<type> new" 52eaca6183SJohn Baldwin.Fc 53c6a51f1cSRuslan Ermilov.Ft <type> 544ea211a4SJohn Baldwin.Fn atomic_fetchadd_<type> "volatile <type> *p" "<type> v" 554ea211a4SJohn Baldwin.Ft <type> 56c6a51f1cSRuslan Ermilov.Fn atomic_load_acq_<type> "volatile <type> *p" 57c6a51f1cSRuslan Ermilov.Ft <type> 58c6a51f1cSRuslan Ermilov.Fn atomic_readandclear_<type> "volatile <type> *p" 59eaca6183SJohn Baldwin.Ft void 60c6a51f1cSRuslan Ermilov.Fn atomic_set_[acq_|rel_]<type> "volatile <type> *p" "<type> v" 61eaca6183SJohn Baldwin.Ft void 62c6a51f1cSRuslan Ermilov.Fn atomic_subtract_[acq_|rel_]<type> "volatile <type> *p" "<type> v" 63eaca6183SJohn Baldwin.Ft void 64c6a51f1cSRuslan Ermilov.Fn atomic_store_rel_<type> "volatile <type> *p" "<type> v" 658a1ee2d3SJung-uk Kim.Ft <type> 668a1ee2d3SJung-uk Kim.Fn atomic_swap_<type> "volatile <type> *p" "<type> v" 678a1ee2d3SJung-uk Kim.Ft int 688a1ee2d3SJung-uk Kim.Fn atomic_testandset_<type> "volatile <type> *p" "u_int v" 69eaca6183SJohn Baldwin.Sh DESCRIPTION 70*a61bd957SAlan CoxEach of the atomic operations is guaranteed to be atomic across multiple 71*a61bd957SAlan Coxprocessors and in the presence of interrupts. 72eaca6183SJohn BaldwinThey can be used to implement reference counts or as building blocks for more 73eaca6183SJohn Baldwinadvanced synchronization primitives such as mutexes. 74eaca6183SJohn Baldwin.Ss Types 752be6c09fSRuslan ErmilovEach atomic operation operates on a specific 760640e9e0SHiten Pandya.Fa type . 77eaca6183SJohn BaldwinThe type to use is indicated in the function name. 78eaca6183SJohn BaldwinThe available types that can be used are: 792be6c09fSRuslan Ermilov.Pp 802be6c09fSRuslan Ermilov.Bl -tag -offset indent -width short -compact 812be6c09fSRuslan Ermilov.It Li int 82eaca6183SJohn Baldwinunsigned integer 832be6c09fSRuslan Ermilov.It Li long 84eaca6183SJohn Baldwinunsigned long integer 852be6c09fSRuslan Ermilov.It Li ptr 86eaca6183SJohn Baldwinunsigned integer the size of a pointer 872be6c09fSRuslan Ermilov.It Li 32 88eaca6183SJohn Baldwinunsigned 32-bit integer 892be6c09fSRuslan Ermilov.It Li 64 90eaca6183SJohn Baldwinunsigned 64-bit integer 91eaca6183SJohn Baldwin.El 92eaca6183SJohn Baldwin.Pp 93eaca6183SJohn BaldwinFor example, the function to atomically add two integers is called 94eaca6183SJohn Baldwin.Fn atomic_add_int . 95c645e17aSJake Burkholder.Pp 962be6c09fSRuslan ErmilovCertain architectures also provide operations for types smaller than 972be6c09fSRuslan Ermilov.Dq Li int . 982be6c09fSRuslan Ermilov.Pp 992be6c09fSRuslan Ermilov.Bl -tag -offset indent -width short -compact 1002be6c09fSRuslan Ermilov.It Li char 101c645e17aSJake Burkholderunsigned character 1022be6c09fSRuslan Ermilov.It Li short 103c645e17aSJake Burkholderunsigned short integer 1042be6c09fSRuslan Ermilov.It Li 8 105c645e17aSJake Burkholderunsigned 8-bit integer 1062be6c09fSRuslan Ermilov.It Li 16 107c645e17aSJake Burkholderunsigned 16-bit integer 108c645e17aSJake Burkholder.El 109c645e17aSJake Burkholder.Pp 110c645e17aSJake BurkholderThese must not be used in MI code because the instructions to implement them 111c645e17aSJake Burkholderefficiently may not be available. 112eaca6183SJohn Baldwin.Ss Memory Barriers 1132be6c09fSRuslan ErmilovMemory barriers are used to guarantee the order of data accesses in 114eaca6183SJohn Baldwintwo ways. 115eaca6183SJohn BaldwinFirst, they specify hints to the compiler to not re-order or optimize the 116eaca6183SJohn Baldwinoperations. 1172be6c09fSRuslan ErmilovSecond, on architectures that do not guarantee ordered data accesses, 118eaca6183SJohn Baldwinspecial instructions or special variants of instructions are used to indicate 119eaca6183SJohn Baldwinto the processor that data accesses need to occur in a certain order. 120eaca6183SJohn BaldwinAs a result, most of the atomic operations have three variants in order to 121eaca6183SJohn Baldwininclude optional memory barriers. 122eaca6183SJohn BaldwinThe first form just performs the operation without any explicit barriers. 1232be6c09fSRuslan ErmilovThe second form uses a read memory barrier, and the third variant uses a write 124eaca6183SJohn Baldwinmemory barrier. 125eaca6183SJohn Baldwin.Pp 12677054356SKonstantin BelousovThe second variant of each operation includes an 12777054356SKonstantin Belousov.Em acquire 12877054356SKonstantin Belousovmemory barrier. 129eaca6183SJohn BaldwinThis barrier ensures that the effects of this operation are completed before the 130eaca6183SJohn Baldwineffects of any later data accesses. 131eaca6183SJohn BaldwinAs a result, the operation is said to have acquire semantics as it acquires a 132eaca6183SJohn Baldwinpseudo-lock requiring further operations to wait until it has completed. 133eaca6183SJohn BaldwinTo denote this, the suffix 1342be6c09fSRuslan Ermilov.Dq Li _acq 135eaca6183SJohn Baldwinis inserted into the function name immediately prior to the 1360640e9e0SHiten Pandya.Dq Li _ Ns Aq Fa type 137eaca6183SJohn Baldwinsuffix. 138eaca6183SJohn BaldwinFor example, to subtract two integers ensuring that any later writes will 139eaca6183SJohn Baldwinhappen after the subtraction is performed, use 140eaca6183SJohn Baldwin.Fn atomic_subtract_acq_int . 141eaca6183SJohn Baldwin.Pp 14277054356SKonstantin BelousovThe third variant of each operation includes a 14377054356SKonstantin Belousov.Em release 14477054356SKonstantin Belousovmemory barrier. 145eaca6183SJohn BaldwinThis ensures that all effects of all previous data accesses are completed 146eaca6183SJohn Baldwinbefore this operation takes place. 147eaca6183SJohn BaldwinAs a result, the operation is said to have release semantics as it releases 148eaca6183SJohn Baldwinany pending data accesses to be completed before its operation is performed. 149eaca6183SJohn BaldwinTo denote this, the suffix 1502be6c09fSRuslan Ermilov.Dq Li _rel 151eaca6183SJohn Baldwinis inserted into the function name immediately prior to the 1520640e9e0SHiten Pandya.Dq Li _ Ns Aq Fa type 153eaca6183SJohn Baldwinsuffix. 154eaca6183SJohn BaldwinFor example, to add two long integers ensuring that all previous 155eaca6183SJohn Baldwinwrites will happen first, use 156eaca6183SJohn Baldwin.Fn atomic_add_rel_long . 157eaca6183SJohn Baldwin.Pp 158eaca6183SJohn BaldwinA practical example of using memory barriers is to ensure that data accesses 159eaca6183SJohn Baldwinthat are protected by a lock are all performed while the lock is held. 160eaca6183SJohn BaldwinTo achieve this, one would use a read barrier when acquiring the lock to 161eaca6183SJohn Baldwinguarantee that the lock is held before any protected operations are performed. 162eaca6183SJohn BaldwinFinally, one would use a write barrier when releasing the lock to ensure that 163eaca6183SJohn Baldwinall of the protected operations are completed before the lock is released. 164eaca6183SJohn Baldwin.Ss Multiple Processors 165*a61bd957SAlan CoxIn multiprocessor systems, the atomicity of the atomic operations on memory 166*a61bd957SAlan Coxdepends on support for cache coherence in the underlying architecture. 167*a61bd957SAlan CoxIn general, cache coherence on the default memory type, 168*a61bd957SAlan Cox.Dv VM_MEMATTR_DEFAULT , 169*a61bd957SAlan Coxis guaranteed by all architectures that are supported by 170*a61bd957SAlan Cox.Fx . 171*a61bd957SAlan CoxFor example, cache coherence is guaranteed on write-back memory by the 172*a61bd957SAlan Cox.Tn amd64 173*a61bd957SAlan Coxand 174eaca6183SJohn Baldwin.Tn i386 175*a61bd957SAlan Coxarchitectures. 176*a61bd957SAlan CoxHowever, on some architectures, cache coherence may not be enabled on all 177*a61bd957SAlan Coxmemory types. 178*a61bd957SAlan CoxTo determine if cache coherence is enabled for a non-default memory type, 179*a61bd957SAlan Coxconsult the architecture's documentation. 180eaca6183SJohn Baldwin.Ss Semantics 181eaca6183SJohn BaldwinThis section describes the semantics of each operation using a C like notation. 182eaca6183SJohn Baldwin.Bl -hang 1832be6c09fSRuslan Ermilov.It Fn atomic_add p v 1842be6c09fSRuslan Ermilov.Bd -literal -compact 185eaca6183SJohn Baldwin*p += v; 186eaca6183SJohn Baldwin.Ed 1872be6c09fSRuslan Ermilov.It Fn atomic_clear p v 1882be6c09fSRuslan Ermilov.Bd -literal -compact 189eaca6183SJohn Baldwin*p &= ~v; 190eaca6183SJohn Baldwin.Ed 1912be6c09fSRuslan Ermilov.It Fn atomic_cmpset dst old new 1922be6c09fSRuslan Ermilov.Bd -literal -compact 193eaca6183SJohn Baldwinif (*dst == old) { 194eaca6183SJohn Baldwin *dst = new; 1958a1ee2d3SJung-uk Kim return (1); 196eaca6183SJohn Baldwin} else 1978a1ee2d3SJung-uk Kim return (0); 198eaca6183SJohn Baldwin.Ed 199eaca6183SJohn Baldwin.El 200eaca6183SJohn Baldwin.Pp 201eaca6183SJohn BaldwinThe 202eaca6183SJohn Baldwin.Fn atomic_cmpset 2032be6c09fSRuslan Ermilovfunctions are not implemented for the types 2042be6c09fSRuslan Ermilov.Dq Li char , 2052be6c09fSRuslan Ermilov.Dq Li short , 2062be6c09fSRuslan Ermilov.Dq Li 8 , 2072be6c09fSRuslan Ermilovand 2082be6c09fSRuslan Ermilov.Dq Li 16 . 209eaca6183SJohn Baldwin.Bl -hang 2104ea211a4SJohn Baldwin.It Fn atomic_fetchadd p v 2114ea211a4SJohn Baldwin.Bd -literal -compact 2124ea211a4SJohn Baldwintmp = *p; 2134ea211a4SJohn Baldwin*p += v; 2148a1ee2d3SJung-uk Kimreturn (tmp); 2154ea211a4SJohn Baldwin.Ed 2164ea211a4SJohn Baldwin.El 2174ea211a4SJohn Baldwin.Pp 2184ea211a4SJohn BaldwinThe 2194ea211a4SJohn Baldwin.Fn atomic_fetchadd 2204ea211a4SJohn Baldwinfunctions are only implemented for the types 2216eb4157fSPawel Jakub Dawidek.Dq Li int , 2226eb4157fSPawel Jakub Dawidek.Dq Li long 2234ea211a4SJohn Baldwinand 2244ea211a4SJohn Baldwin.Dq Li 32 2254ea211a4SJohn Baldwinand do not have any variants with memory barriers at this time. 2264ea211a4SJohn Baldwin.Bl -hang 2278a1ee2d3SJung-uk Kim.It Fn atomic_load p 2282be6c09fSRuslan Ermilov.Bd -literal -compact 2298a1ee2d3SJung-uk Kimreturn (*p); 230eaca6183SJohn Baldwin.Ed 231eaca6183SJohn Baldwin.El 232eaca6183SJohn Baldwin.Pp 233eaca6183SJohn BaldwinThe 234eaca6183SJohn Baldwin.Fn atomic_load 235e6b08944SJohn Baldwinfunctions are only provided with acquire memory barriers. 236eaca6183SJohn Baldwin.Bl -hang 2378a1ee2d3SJung-uk Kim.It Fn atomic_readandclear p 2382be6c09fSRuslan Ermilov.Bd -literal -compact 2398a1ee2d3SJung-uk Kimtmp = *p; 2408a1ee2d3SJung-uk Kim*p = 0; 2418a1ee2d3SJung-uk Kimreturn (tmp); 242eaca6183SJohn Baldwin.Ed 243eaca6183SJohn Baldwin.El 244eaca6183SJohn Baldwin.Pp 245eaca6183SJohn BaldwinThe 246eaca6183SJohn Baldwin.Fn atomic_readandclear 2472be6c09fSRuslan Ermilovfunctions are not implemented for the types 2482be6c09fSRuslan Ermilov.Dq Li char , 2492be6c09fSRuslan Ermilov.Dq Li short , 2502be6c09fSRuslan Ermilov.Dq Li ptr , 2512be6c09fSRuslan Ermilov.Dq Li 8 , 2522be6c09fSRuslan Ermilovand 2532be6c09fSRuslan Ermilov.Dq Li 16 2548a1ee2d3SJung-uk Kimand do not have any variants with memory barriers at this time. 255eaca6183SJohn Baldwin.Bl -hang 2562be6c09fSRuslan Ermilov.It Fn atomic_set p v 2572be6c09fSRuslan Ermilov.Bd -literal -compact 258eaca6183SJohn Baldwin*p |= v; 259eaca6183SJohn Baldwin.Ed 2602be6c09fSRuslan Ermilov.It Fn atomic_subtract p v 2612be6c09fSRuslan Ermilov.Bd -literal -compact 262eaca6183SJohn Baldwin*p -= v; 263eaca6183SJohn Baldwin.Ed 2642be6c09fSRuslan Ermilov.It Fn atomic_store p v 2652be6c09fSRuslan Ermilov.Bd -literal -compact 266eaca6183SJohn Baldwin*p = v; 267eaca6183SJohn Baldwin.Ed 268eaca6183SJohn Baldwin.El 269eaca6183SJohn Baldwin.Pp 270eaca6183SJohn BaldwinThe 271eaca6183SJohn Baldwin.Fn atomic_store 272e6b08944SJohn Baldwinfunctions are only provided with release memory barriers. 2738a1ee2d3SJung-uk Kim.Bl -hang 2748a1ee2d3SJung-uk Kim.It Fn atomic_swap p v 2758a1ee2d3SJung-uk Kim.Bd -literal -compact 2768a1ee2d3SJung-uk Kimtmp = *p; 2778a1ee2d3SJung-uk Kim*p = v; 2788a1ee2d3SJung-uk Kimreturn (tmp); 2798a1ee2d3SJung-uk Kim.Ed 2808a1ee2d3SJung-uk Kim.El 2818a1ee2d3SJung-uk Kim.Pp 2828a1ee2d3SJung-uk KimThe 2838a1ee2d3SJung-uk Kim.Fn atomic_swap 2848a1ee2d3SJung-uk Kimfunctions are not implemented for the types 2858a1ee2d3SJung-uk Kim.Dq Li char , 2868a1ee2d3SJung-uk Kim.Dq Li short , 2878a1ee2d3SJung-uk Kim.Dq Li ptr , 2888a1ee2d3SJung-uk Kim.Dq Li 8 , 2898a1ee2d3SJung-uk Kimand 2908a1ee2d3SJung-uk Kim.Dq Li 16 2918a1ee2d3SJung-uk Kimand do not have any variants with memory barriers at this time. 2928a1ee2d3SJung-uk Kim.Bl -hang 2938a1ee2d3SJung-uk Kim.It Fn atomic_testandset p v 2948a1ee2d3SJung-uk Kim.Bd -literal -compact 2958a1ee2d3SJung-uk Kimbit = 1 << (v % (sizeof(*p) * NBBY)); 2968a1ee2d3SJung-uk Kimtmp = (*p & bit) != 0; 2978a1ee2d3SJung-uk Kim*p |= bit; 2988a1ee2d3SJung-uk Kimreturn (tmp); 2998a1ee2d3SJung-uk Kim.Ed 3008a1ee2d3SJung-uk Kim.El 3018a1ee2d3SJung-uk Kim.Pp 3028a1ee2d3SJung-uk KimThe 3038a1ee2d3SJung-uk Kim.Fn atomic_testandset 3048a1ee2d3SJung-uk Kimfunctions are only implemented for the types 3058a1ee2d3SJung-uk Kim.Dq Li int , 3068a1ee2d3SJung-uk Kim.Dq Li long 3078a1ee2d3SJung-uk Kimand 3088a1ee2d3SJung-uk Kim.Dq Li 32 3098a1ee2d3SJung-uk Kimand do not have any variants with memory barriers at this time. 3108a1ee2d3SJung-uk Kim.Pp 311eaca6183SJohn BaldwinThe type 3122be6c09fSRuslan Ermilov.Dq Li 64 313eaca6183SJohn Baldwinis currently not implemented for any of the atomic operations on the 3144ea211a4SJohn Baldwin.Tn arm , 3154ea211a4SJohn Baldwin.Tn i386 , 3164ea211a4SJohn Baldwinand 3174ea211a4SJohn Baldwin.Tn powerpc 3184ea211a4SJohn Baldwinarchitectures. 319eaca6183SJohn Baldwin.Sh RETURN VALUES 3202be6c09fSRuslan ErmilovThe 321eaca6183SJohn Baldwin.Fn atomic_cmpset 3228a1ee2d3SJung-uk Kimfunction returns the result of the compare operation. 3232be6c09fSRuslan ErmilovThe 3244ea211a4SJohn Baldwin.Fn atomic_fetchadd , 3254ea211a4SJohn Baldwin.Fn atomic_load , 3268a1ee2d3SJung-uk Kim.Fn atomic_readandclear , 327eaca6183SJohn Baldwinand 3288a1ee2d3SJung-uk Kim.Fn atomic_swap 3298a1ee2d3SJung-uk Kimfunctions return the value at the specified address. 3308a1ee2d3SJung-uk KimThe 3318a1ee2d3SJung-uk Kim.Fn atomic_testandset 3328a1ee2d3SJung-uk Kimfunction returns the result of the test operation. 333eaca6183SJohn Baldwin.Sh EXAMPLES 334eaca6183SJohn BaldwinThis example uses the 335eaca6183SJohn Baldwin.Fn atomic_cmpset_acq_ptr 336eaca6183SJohn Baldwinand 337eaca6183SJohn Baldwin.Fn atomic_set_ptr 338eaca6183SJohn Baldwinfunctions to obtain a sleep mutex and handle recursion. 339eaca6183SJohn BaldwinSince the 340eaca6183SJohn Baldwin.Va mtx_lock 341eaca6183SJohn Baldwinmember of a 3422be6c09fSRuslan Ermilov.Vt "struct mtx" 343eaca6183SJohn Baldwinis a pointer, the 3442be6c09fSRuslan Ermilov.Dq Li ptr 345eaca6183SJohn Baldwintype is used. 346eaca6183SJohn Baldwin.Bd -literal 3474ea211a4SJohn Baldwin/* Try to obtain mtx_lock once. */ 348eaca6183SJohn Baldwin#define _obtain_lock(mp, tid) \\ 3494ea211a4SJohn Baldwin atomic_cmpset_acq_ptr(&(mp)->mtx_lock, MTX_UNOWNED, (tid)) 350eaca6183SJohn Baldwin 351eaca6183SJohn Baldwin/* Get a sleep lock, deal with recursion inline. */ 3524ea211a4SJohn Baldwin#define _get_sleep_lock(mp, tid, opts, file, line) do { \\ 3534ea211a4SJohn Baldwin uintptr_t _tid = (uintptr_t)(tid); \\ 3544ea211a4SJohn Baldwin \\ 355eaca6183SJohn Baldwin if (!_obtain_lock(mp, tid)) { \\ 3564ea211a4SJohn Baldwin if (((mp)->mtx_lock & MTX_FLAGMASK) != _tid) \\ 3574ea211a4SJohn Baldwin _mtx_lock_sleep((mp), _tid, (opts), (file), (line));\\ 358eaca6183SJohn Baldwin else { \\ 359eaca6183SJohn Baldwin atomic_set_ptr(&(mp)->mtx_lock, MTX_RECURSE); \\ 360eaca6183SJohn Baldwin (mp)->mtx_recurse++; \\ 361eaca6183SJohn Baldwin } \\ 362eaca6183SJohn Baldwin } \\ 363eaca6183SJohn Baldwin} while (0) 364eaca6183SJohn Baldwin.Ed 365eaca6183SJohn Baldwin.Sh HISTORY 366eaca6183SJohn BaldwinThe 367eaca6183SJohn Baldwin.Fn atomic_add , 368eaca6183SJohn Baldwin.Fn atomic_clear , 369eaca6183SJohn Baldwin.Fn atomic_set , 370eaca6183SJohn Baldwinand 371eaca6183SJohn Baldwin.Fn atomic_subtract 372eaca6183SJohn Baldwinoperations were first introduced in 373eaca6183SJohn Baldwin.Fx 3.0 . 3742be6c09fSRuslan ErmilovThis first set only supported the types 3752be6c09fSRuslan Ermilov.Dq Li char , 3762be6c09fSRuslan Ermilov.Dq Li short , 3772be6c09fSRuslan Ermilov.Dq Li int , 3782be6c09fSRuslan Ermilovand 3792be6c09fSRuslan Ermilov.Dq Li long . 380eaca6183SJohn BaldwinThe 381eaca6183SJohn Baldwin.Fn atomic_cmpset , 382eaca6183SJohn Baldwin.Fn atomic_load , 383eaca6183SJohn Baldwin.Fn atomic_readandclear , 384eaca6183SJohn Baldwinand 385eaca6183SJohn Baldwin.Fn atomic_store 386eaca6183SJohn Baldwinoperations were added in 387eaca6183SJohn Baldwin.Fx 5.0 . 3882be6c09fSRuslan ErmilovThe types 3892be6c09fSRuslan Ermilov.Dq Li 8 , 3902be6c09fSRuslan Ermilov.Dq Li 16 , 3912be6c09fSRuslan Ermilov.Dq Li 32 , 3922be6c09fSRuslan Ermilov.Dq Li 64 , 3932be6c09fSRuslan Ermilovand 3944ea211a4SJohn Baldwin.Dq Li ptr 3952be6c09fSRuslan Ermilovand all of the acquire and release variants 396eaca6183SJohn Baldwinwere added in 397eaca6183SJohn Baldwin.Fx 5.0 398eaca6183SJohn Baldwinas well. 3994ea211a4SJohn BaldwinThe 4004ea211a4SJohn Baldwin.Fn atomic_fetchadd 4014ea211a4SJohn Baldwinoperations were added in 4024ea211a4SJohn Baldwin.Fx 6.0 . 4038a1ee2d3SJung-uk KimThe 4048a1ee2d3SJung-uk Kim.Fn atomic_swap 4058a1ee2d3SJung-uk Kimand 4068a1ee2d3SJung-uk Kim.Fn atomic_testandset 4078a1ee2d3SJung-uk Kimoperations were added in 4088a1ee2d3SJung-uk Kim.Fx 10.0 . 409