1d265f300SJohn Baldwin.\" Copyright (c) 2000-2001 John H. Baldwin <jhb@FreeBSD.org> 2eaca6183SJohn Baldwin.\" All rights reserved. 3eaca6183SJohn Baldwin.\" 4eaca6183SJohn Baldwin.\" Redistribution and use in source and binary forms, with or without 5eaca6183SJohn Baldwin.\" modification, are permitted provided that the following conditions 6eaca6183SJohn Baldwin.\" are met: 7eaca6183SJohn Baldwin.\" 1. Redistributions of source code must retain the above copyright 8eaca6183SJohn Baldwin.\" notice, this list of conditions and the following disclaimer. 9eaca6183SJohn Baldwin.\" 2. Redistributions in binary form must reproduce the above copyright 10eaca6183SJohn Baldwin.\" notice, this list of conditions and the following disclaimer in the 11eaca6183SJohn Baldwin.\" documentation and/or other materials provided with the distribution. 12eaca6183SJohn Baldwin.\" 13eaca6183SJohn Baldwin.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR 14eaca6183SJohn Baldwin.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 15eaca6183SJohn Baldwin.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 16eaca6183SJohn Baldwin.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, 17eaca6183SJohn Baldwin.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 18eaca6183SJohn Baldwin.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 19eaca6183SJohn Baldwin.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 20eaca6183SJohn Baldwin.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21eaca6183SJohn Baldwin.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22eaca6183SJohn Baldwin.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23eaca6183SJohn Baldwin.\" 24eaca6183SJohn Baldwin.\" $FreeBSD$ 25eaca6183SJohn Baldwin.\" 26eaca6183SJohn Baldwin.Dd October 27, 2000 27eaca6183SJohn Baldwin.Os 28eaca6183SJohn Baldwin.Dt ATOMIC 9 29eaca6183SJohn Baldwin.Sh NAME 30eaca6183SJohn Baldwin.Nm atomic_add , 31eaca6183SJohn Baldwin.Nm atomic_clear , 32eaca6183SJohn Baldwin.Nm atomic_cmpset , 33eaca6183SJohn Baldwin.Nm atomic_load , 34eaca6183SJohn Baldwin.Nm atomic_readandclear , 35eaca6183SJohn Baldwin.Nm atomic_set , 36eaca6183SJohn Baldwin.Nm atomic_subtract , 37eaca6183SJohn Baldwin.Nm atomic_store 38eaca6183SJohn Baldwin.Nd atomic operations 39eaca6183SJohn Baldwin.Sh SYNOPSIS 4032eef9aeSRuslan Ermilov.In sys/types.h 4132eef9aeSRuslan Ermilov.In machine/atomic.h 42eaca6183SJohn Baldwin.Ft void 43c6a51f1cSRuslan Ermilov.Fn atomic_add_[acq_|rel_]<type> "volatile <type> *p" "<type> v" 44eaca6183SJohn Baldwin.Ft void 45c6a51f1cSRuslan Ermilov.Fn atomic_clear_[acq_|rel_]<type> "volatile <type> *p" "<type> v" 46eaca6183SJohn Baldwin.Ft int 47c6a51f1cSRuslan Ermilov.Fo atomic_cmpset_[acq_|rel_]<type> 48c6a51f1cSRuslan Ermilov.Fa "volatile <type> *dst" 49c6a51f1cSRuslan Ermilov.Fa "<type> old" 50c6a51f1cSRuslan Ermilov.Fa "<type> new" 51eaca6183SJohn Baldwin.Fc 52c6a51f1cSRuslan Ermilov.Ft <type> 53c6a51f1cSRuslan Ermilov.Fn atomic_load_acq_<type> "volatile <type> *p" 54c6a51f1cSRuslan Ermilov.Ft <type> 55c6a51f1cSRuslan Ermilov.Fn atomic_readandclear_<type> "volatile <type> *p" 56eaca6183SJohn Baldwin.Ft void 57c6a51f1cSRuslan Ermilov.Fn atomic_set_[acq_|rel_]<type> "volatile <type> *p" "<type> v" 58eaca6183SJohn Baldwin.Ft void 59c6a51f1cSRuslan Ermilov.Fn atomic_subtract_[acq_|rel_]<type> "volatile <type> *p" "<type> v" 60eaca6183SJohn Baldwin.Ft void 61c6a51f1cSRuslan Ermilov.Fn atomic_store_rel_<type> "volatile <type> *p" "<type> v" 622be6c09fSRuslan Ermilov.rm LB RB La Ra 63eaca6183SJohn Baldwin.Sh DESCRIPTION 64eaca6183SJohn BaldwinEach of the atomic operations is guaranteed to be atomic in the presence of 65eaca6183SJohn Baldwininterrupts. 66eaca6183SJohn BaldwinThey can be used to implement reference counts or as building blocks for more 67eaca6183SJohn Baldwinadvanced synchronization primitives such as mutexes. 68eaca6183SJohn Baldwin.Ss Types 692be6c09fSRuslan ErmilovEach atomic operation operates on a specific 700640e9e0SHiten Pandya.Fa type . 71eaca6183SJohn BaldwinThe type to use is indicated in the function name. 72eaca6183SJohn BaldwinThe available types that can be used are: 732be6c09fSRuslan Ermilov.Pp 742be6c09fSRuslan Ermilov.Bl -tag -offset indent -width short -compact 752be6c09fSRuslan Ermilov.It Li int 76eaca6183SJohn Baldwinunsigned integer 772be6c09fSRuslan Ermilov.It Li long 78eaca6183SJohn Baldwinunsigned long integer 792be6c09fSRuslan Ermilov.It Li ptr 80eaca6183SJohn Baldwinunsigned integer the size of a pointer 812be6c09fSRuslan Ermilov.It Li 32 82eaca6183SJohn Baldwinunsigned 32-bit integer 832be6c09fSRuslan Ermilov.It Li 64 84eaca6183SJohn Baldwinunsigned 64-bit integer 85eaca6183SJohn Baldwin.El 86eaca6183SJohn Baldwin.Pp 87eaca6183SJohn BaldwinFor example, the function to atomically add two integers is called 88eaca6183SJohn Baldwin.Fn atomic_add_int . 89c645e17aSJake Burkholder.Pp 902be6c09fSRuslan ErmilovCertain architectures also provide operations for types smaller than 912be6c09fSRuslan Ermilov.Dq Li int . 922be6c09fSRuslan Ermilov.Pp 932be6c09fSRuslan Ermilov.Bl -tag -offset indent -width short -compact 942be6c09fSRuslan Ermilov.It Li char 95c645e17aSJake Burkholderunsigned character 962be6c09fSRuslan Ermilov.It Li short 97c645e17aSJake Burkholderunsigned short integer 982be6c09fSRuslan Ermilov.It Li 8 99c645e17aSJake Burkholderunsigned 8-bit integer 1002be6c09fSRuslan Ermilov.It Li 16 101c645e17aSJake Burkholderunsigned 16-bit integer 102c645e17aSJake Burkholder.El 103c645e17aSJake Burkholder.Pp 104c645e17aSJake BurkholderThese must not be used in MI code because the instructions to implement them 105c645e17aSJake Burkholderefficiently may not be available. 106eaca6183SJohn Baldwin.Ss Memory Barriers 1072be6c09fSRuslan ErmilovMemory barriers are used to guarantee the order of data accesses in 108eaca6183SJohn Baldwintwo ways. 109eaca6183SJohn BaldwinFirst, they specify hints to the compiler to not re-order or optimize the 110eaca6183SJohn Baldwinoperations. 1112be6c09fSRuslan ErmilovSecond, on architectures that do not guarantee ordered data accesses, 112eaca6183SJohn Baldwinspecial instructions or special variants of instructions are used to indicate 113eaca6183SJohn Baldwinto the processor that data accesses need to occur in a certain order. 114eaca6183SJohn BaldwinAs a result, most of the atomic operations have three variants in order to 115eaca6183SJohn Baldwininclude optional memory barriers. 116eaca6183SJohn BaldwinThe first form just performs the operation without any explicit barriers. 1172be6c09fSRuslan ErmilovThe second form uses a read memory barrier, and the third variant uses a write 118eaca6183SJohn Baldwinmemory barrier. 119eaca6183SJohn Baldwin.Pp 120eaca6183SJohn BaldwinThe second variant of each operation includes a read memory barrier. 121eaca6183SJohn BaldwinThis barrier ensures that the effects of this operation are completed before the 122eaca6183SJohn Baldwineffects of any later data accesses. 123eaca6183SJohn BaldwinAs a result, the operation is said to have acquire semantics as it acquires a 124eaca6183SJohn Baldwinpseudo-lock requiring further operations to wait until it has completed. 125eaca6183SJohn BaldwinTo denote this, the suffix 1262be6c09fSRuslan Ermilov.Dq Li _acq 127eaca6183SJohn Baldwinis inserted into the function name immediately prior to the 1280640e9e0SHiten Pandya.Dq Li _ Ns Aq Fa type 129eaca6183SJohn Baldwinsuffix. 130eaca6183SJohn BaldwinFor example, to subtract two integers ensuring that any later writes will 131eaca6183SJohn Baldwinhappen after the subtraction is performed, use 132eaca6183SJohn Baldwin.Fn atomic_subtract_acq_int . 133eaca6183SJohn Baldwin.Pp 134eaca6183SJohn BaldwinThe third variant of each operation includes a write memory barrier. 135eaca6183SJohn BaldwinThis ensures that all effects of all previous data accesses are completed 136eaca6183SJohn Baldwinbefore this operation takes place. 137eaca6183SJohn BaldwinAs a result, the operation is said to have release semantics as it releases 138eaca6183SJohn Baldwinany pending data accesses to be completed before its operation is performed. 139eaca6183SJohn BaldwinTo denote this, the suffix 1402be6c09fSRuslan Ermilov.Dq Li _rel 141eaca6183SJohn Baldwinis inserted into the function name immediately prior to the 1420640e9e0SHiten Pandya.Dq Li _ Ns Aq Fa type 143eaca6183SJohn Baldwinsuffix. 144eaca6183SJohn BaldwinFor example, to add two long integers ensuring that all previous 145eaca6183SJohn Baldwinwrites will happen first, use 146eaca6183SJohn Baldwin.Fn atomic_add_rel_long . 147eaca6183SJohn Baldwin.Pp 148eaca6183SJohn BaldwinA practical example of using memory barriers is to ensure that data accesses 149eaca6183SJohn Baldwinthat are protected by a lock are all performed while the lock is held. 150eaca6183SJohn BaldwinTo achieve this, one would use a read barrier when acquiring the lock to 151eaca6183SJohn Baldwinguarantee that the lock is held before any protected operations are performed. 152eaca6183SJohn BaldwinFinally, one would use a write barrier when releasing the lock to ensure that 153eaca6183SJohn Baldwinall of the protected operations are completed before the lock is released. 154eaca6183SJohn Baldwin.Ss Multiple Processors 155eaca6183SJohn BaldwinThe current set of atomic operations do not necessarily guarantee atomicity 156eaca6183SJohn Baldwinacross multiple processors. 157eaca6183SJohn BaldwinTo guarantee atomicity across processors, not only does the individual 158d1ed27b6SJens Schweikhardtoperation need to be atomic on the processor performing the operation, but 159eaca6183SJohn Baldwinthe result of the operation needs to be pushed out to stable storage and the 160eaca6183SJohn Baldwincaches of all other processors on the system need to invalidate any cache 161eaca6183SJohn Baldwinlines that include the affected memory region. 162eaca6183SJohn BaldwinOn the 163eaca6183SJohn Baldwin.Tn i386 164eaca6183SJohn Baldwinarchitecture, the cache coherency model requires that the hardware perform 165eaca6183SJohn Baldwinthis task, thus the atomic operations are atomic across multiple processors. 166eaca6183SJohn BaldwinOn the 167eaca6183SJohn Baldwin.Tn ia64 168eaca6183SJohn Baldwinarchitecture, coherency is only guaranteed for pages that are configured to 169eaca6183SJohn Baldwinusing a caching policy of either uncached or write back. 170eaca6183SJohn Baldwin.Ss Semantics 171eaca6183SJohn BaldwinThis section describes the semantics of each operation using a C like notation. 172eaca6183SJohn Baldwin.Bl -hang 1732be6c09fSRuslan Ermilov.It Fn atomic_add p v 1742be6c09fSRuslan Ermilov.Bd -literal -compact 175eaca6183SJohn Baldwin*p += v; 176eaca6183SJohn Baldwin.Ed 1772be6c09fSRuslan Ermilov.It Fn atomic_clear p v 1782be6c09fSRuslan Ermilov.Bd -literal -compact 179eaca6183SJohn Baldwin*p &= ~v; 180eaca6183SJohn Baldwin.Ed 1812be6c09fSRuslan Ermilov.It Fn atomic_cmpset dst old new 1822be6c09fSRuslan Ermilov.Bd -literal -compact 183eaca6183SJohn Baldwinif (*dst == old) { 184eaca6183SJohn Baldwin *dst = new; 185eaca6183SJohn Baldwin return 1; 186eaca6183SJohn Baldwin} else 187eaca6183SJohn Baldwin return 0; 188eaca6183SJohn Baldwin.Ed 189eaca6183SJohn Baldwin.El 190eaca6183SJohn Baldwin.Pp 191eaca6183SJohn BaldwinThe 192eaca6183SJohn Baldwin.Fn atomic_cmpset 1932be6c09fSRuslan Ermilovfunctions are not implemented for the types 1942be6c09fSRuslan Ermilov.Dq Li char , 1952be6c09fSRuslan Ermilov.Dq Li short , 1962be6c09fSRuslan Ermilov.Dq Li 8 , 1972be6c09fSRuslan Ermilovand 1982be6c09fSRuslan Ermilov.Dq Li 16 . 199eaca6183SJohn Baldwin.Bl -hang 2002be6c09fSRuslan Ermilov.It Fn atomic_load addr 2012be6c09fSRuslan Ermilov.Bd -literal -compact 202eaca6183SJohn Baldwinreturn (*addr) 203eaca6183SJohn Baldwin.Ed 204eaca6183SJohn Baldwin.El 205eaca6183SJohn Baldwin.Pp 206eaca6183SJohn BaldwinThe 207eaca6183SJohn Baldwin.Fn atomic_load 208eaca6183SJohn Baldwinfunctions always have acquire semantics. 209eaca6183SJohn Baldwin.Bl -hang 2102be6c09fSRuslan Ermilov.It Fn atomic_readandclear addr 2112be6c09fSRuslan Ermilov.Bd -literal -compact 212eaca6183SJohn Baldwintemp = *addr; 213eaca6183SJohn Baldwin*addr = 0; 214eaca6183SJohn Baldwinreturn (temp); 215eaca6183SJohn Baldwin.Ed 216eaca6183SJohn Baldwin.El 217eaca6183SJohn Baldwin.Pp 218eaca6183SJohn BaldwinThe 219eaca6183SJohn Baldwin.Fn atomic_readandclear 2202be6c09fSRuslan Ermilovfunctions are not implemented for the types 2212be6c09fSRuslan Ermilov.Dq Li char , 2222be6c09fSRuslan Ermilov.Dq Li short , 2232be6c09fSRuslan Ermilov.Dq Li ptr , 2242be6c09fSRuslan Ermilov.Dq Li 8 , 2252be6c09fSRuslan Ermilovand 2262be6c09fSRuslan Ermilov.Dq Li 16 2272be6c09fSRuslan Ermilovand do 228eaca6183SJohn Baldwinnot have any variants with memory barriers at this time. 229eaca6183SJohn Baldwin.Bl -hang 2302be6c09fSRuslan Ermilov.It Fn atomic_set p v 2312be6c09fSRuslan Ermilov.Bd -literal -compact 232eaca6183SJohn Baldwin*p |= v; 233eaca6183SJohn Baldwin.Ed 2342be6c09fSRuslan Ermilov.It Fn atomic_subtract p v 2352be6c09fSRuslan Ermilov.Bd -literal -compact 236eaca6183SJohn Baldwin*p -= v; 237eaca6183SJohn Baldwin.Ed 2382be6c09fSRuslan Ermilov.It Fn atomic_store p v 2392be6c09fSRuslan Ermilov.Bd -literal -compact 240eaca6183SJohn Baldwin*p = v; 241eaca6183SJohn Baldwin.Ed 242eaca6183SJohn Baldwin.El 243eaca6183SJohn Baldwin.Pp 244eaca6183SJohn BaldwinThe 245eaca6183SJohn Baldwin.Fn atomic_store 246eaca6183SJohn Baldwinfunctions always have release semantics. 247eaca6183SJohn Baldwin.Pp 248eaca6183SJohn BaldwinThe type 2492be6c09fSRuslan Ermilov.Dq Li 64 250eaca6183SJohn Baldwinis currently not implemented for any of the atomic operations on the 251eaca6183SJohn Baldwin.Tn i386 252eaca6183SJohn Baldwinarchitecture. 253eaca6183SJohn Baldwin.Sh RETURN VALUES 2542be6c09fSRuslan ErmilovThe 255eaca6183SJohn Baldwin.Fn atomic_cmpset 2562be6c09fSRuslan Ermilovfunction 257eaca6183SJohn Baldwinreturns the result of the compare operation. 2582be6c09fSRuslan ErmilovThe 259eaca6183SJohn Baldwin.Fn atomic_load 260eaca6183SJohn Baldwinand 261eaca6183SJohn Baldwin.Fn atomic_readandclear 2622be6c09fSRuslan Ermilovfunctions 263eaca6183SJohn Baldwinreturn the value at the specified address. 264eaca6183SJohn Baldwin.Sh EXAMPLES 265eaca6183SJohn BaldwinThis example uses the 266eaca6183SJohn Baldwin.Fn atomic_cmpset_acq_ptr 267eaca6183SJohn Baldwinand 268eaca6183SJohn Baldwin.Fn atomic_set_ptr 269eaca6183SJohn Baldwinfunctions to obtain a sleep mutex and handle recursion. 270eaca6183SJohn BaldwinSince the 271eaca6183SJohn Baldwin.Va mtx_lock 272eaca6183SJohn Baldwinmember of a 2732be6c09fSRuslan Ermilov.Vt "struct mtx" 274eaca6183SJohn Baldwinis a pointer, the 2752be6c09fSRuslan Ermilov.Dq Li ptr 276eaca6183SJohn Baldwintype is used. 277eaca6183SJohn Baldwin.Bd -literal 278eaca6183SJohn Baldwin#define _obtain_lock(mp, tid) \\ 279eaca6183SJohn Baldwin atomic_cmpset_acq_ptr(&(mp)->mtx_lock, (void *)MTX_UNOWNED, (tid)) 280eaca6183SJohn Baldwin 281eaca6183SJohn Baldwin/* Get a sleep lock, deal with recursion inline. */ 282eaca6183SJohn Baldwin#define _getlock_sleep(mp, tid, type) do { \\ 283eaca6183SJohn Baldwin if (!_obtain_lock(mp, tid)) { \\ 284eaca6183SJohn Baldwin if (((mp)->mtx_lock & MTX_FLAGMASK) != ((uintptr_t)(tid)))\\ 285eaca6183SJohn Baldwin mtx_enter_hard(mp, (type) & MTX_HARDOPTS, 0); \\ 286eaca6183SJohn Baldwin else { \\ 287eaca6183SJohn Baldwin atomic_set_ptr(&(mp)->mtx_lock, MTX_RECURSE); \\ 288eaca6183SJohn Baldwin (mp)->mtx_recurse++; \\ 289eaca6183SJohn Baldwin } \\ 290eaca6183SJohn Baldwin } \\ 291eaca6183SJohn Baldwin} while (0) 292eaca6183SJohn Baldwin.Ed 293eaca6183SJohn Baldwin.Sh HISTORY 294eaca6183SJohn BaldwinThe 295eaca6183SJohn Baldwin.Fn atomic_add , 296eaca6183SJohn Baldwin.Fn atomic_clear , 297eaca6183SJohn Baldwin.Fn atomic_set , 298eaca6183SJohn Baldwinand 299eaca6183SJohn Baldwin.Fn atomic_subtract 300eaca6183SJohn Baldwinoperations were first introduced in 301eaca6183SJohn Baldwin.Fx 3.0 . 3022be6c09fSRuslan ErmilovThis first set only supported the types 3032be6c09fSRuslan Ermilov.Dq Li char , 3042be6c09fSRuslan Ermilov.Dq Li short , 3052be6c09fSRuslan Ermilov.Dq Li int , 3062be6c09fSRuslan Ermilovand 3072be6c09fSRuslan Ermilov.Dq Li long . 308eaca6183SJohn BaldwinThe 309eaca6183SJohn Baldwin.Fn atomic_cmpset , 310eaca6183SJohn Baldwin.Fn atomic_load , 311eaca6183SJohn Baldwin.Fn atomic_readandclear , 312eaca6183SJohn Baldwinand 313eaca6183SJohn Baldwin.Fn atomic_store 314eaca6183SJohn Baldwinoperations were added in 315eaca6183SJohn Baldwin.Fx 5.0 . 3162be6c09fSRuslan ErmilovThe types 3172be6c09fSRuslan Ermilov.Dq Li 8 , 3182be6c09fSRuslan Ermilov.Dq Li 16 , 3192be6c09fSRuslan Ermilov.Dq Li 32 , 3202be6c09fSRuslan Ermilov.Dq Li 64 , 3212be6c09fSRuslan Ermilovand 3222be6c09fSRuslan Ermilov.Dq Li ptr , 3232be6c09fSRuslan Ermilovand all of the acquire and release variants 324eaca6183SJohn Baldwinwere added in 325eaca6183SJohn Baldwin.Fx 5.0 326eaca6183SJohn Baldwinas well. 327