1cb0ac91aSSascha Wildner.\" Copyright (c) 2000-2001 John H. Baldwin <jhb@FreeBSD.org> 2cb0ac91aSSascha Wildner.\" All rights reserved. 3cb0ac91aSSascha Wildner.\" 4cb0ac91aSSascha Wildner.\" Redistribution and use in source and binary forms, with or without 5cb0ac91aSSascha Wildner.\" modification, are permitted provided that the following conditions 6cb0ac91aSSascha Wildner.\" are met: 7cb0ac91aSSascha Wildner.\" 1. Redistributions of source code must retain the above copyright 8cb0ac91aSSascha Wildner.\" notice, this list of conditions and the following disclaimer. 9cb0ac91aSSascha Wildner.\" 2. Redistributions in binary form must reproduce the above copyright 10cb0ac91aSSascha Wildner.\" notice, this list of conditions and the following disclaimer in the 11cb0ac91aSSascha Wildner.\" documentation and/or other materials provided with the distribution. 12cb0ac91aSSascha Wildner.\" 13cb0ac91aSSascha Wildner.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR 14cb0ac91aSSascha Wildner.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 15cb0ac91aSSascha Wildner.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 16cb0ac91aSSascha Wildner.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, 17cb0ac91aSSascha Wildner.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 18cb0ac91aSSascha Wildner.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 19cb0ac91aSSascha Wildner.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 20cb0ac91aSSascha Wildner.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21cb0ac91aSSascha Wildner.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22cb0ac91aSSascha Wildner.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23cb0ac91aSSascha Wildner.\" 24cb0ac91aSSascha Wildner.\" $FreeBSD: src/share/man/man9/atomic.9,v 1.17 2010/05/27 13:56:27 uqs Exp $ 25cb0ac91aSSascha Wildner.\" 26d42a763bSAaron LI.Dd January 14, 2024 27cb0ac91aSSascha Wildner.Dt ATOMIC 9 28cb0ac91aSSascha Wildner.Os 29cb0ac91aSSascha Wildner.Sh NAME 30cb0ac91aSSascha Wildner.Nm atomic_add , 31cb0ac91aSSascha Wildner.Nm atomic_clear , 32cb0ac91aSSascha Wildner.Nm atomic_cmpset , 33cb0ac91aSSascha Wildner.Nm atomic_fetchadd , 34cb0ac91aSSascha Wildner.Nm atomic_load , 35cb0ac91aSSascha Wildner.Nm atomic_readandclear , 36cb0ac91aSSascha Wildner.Nm atomic_set , 37cb0ac91aSSascha Wildner.Nm atomic_subtract , 38cb0ac91aSSascha Wildner.Nm atomic_store 39cb0ac91aSSascha Wildner.Nd atomic operations 40cb0ac91aSSascha Wildner.Sh SYNOPSIS 41cb0ac91aSSascha Wildner.In sys/types.h 42cb0ac91aSSascha Wildner.In machine/atomic.h 43cb0ac91aSSascha Wildner.Ft void 44cb0ac91aSSascha Wildner.Fn atomic_add_[acq_|rel_]<type> "volatile <type> *p" "<type> v" 45cb0ac91aSSascha Wildner.Ft void 46cb0ac91aSSascha Wildner.Fn atomic_clear_[acq_|rel_]<type> "volatile <type> *p" "<type> v" 47cb0ac91aSSascha Wildner.Ft int 48cb0ac91aSSascha Wildner.Fo atomic_cmpset_[acq_|rel_]<type> 49cb0ac91aSSascha Wildner.Fa "volatile <type> *dst" 50cb0ac91aSSascha Wildner.Fa "<type> old" 51cb0ac91aSSascha Wildner.Fa "<type> new" 52cb0ac91aSSascha Wildner.Fc 53cb0ac91aSSascha Wildner.Ft <type> 54cb0ac91aSSascha Wildner.Fn atomic_fetchadd_<type> "volatile <type> *p" "<type> v" 55cb0ac91aSSascha Wildner.Ft <type> 56d42a763bSAaron LI.Fn atomic_load_[acq_]<type> "volatile <type> *p" 57cb0ac91aSSascha Wildner.Ft <type> 58cb0ac91aSSascha Wildner.Fn atomic_readandclear_<type> "volatile <type> *p" 59cb0ac91aSSascha Wildner.Ft void 60cb0ac91aSSascha Wildner.Fn atomic_set_[acq_|rel_]<type> "volatile <type> *p" "<type> v" 61cb0ac91aSSascha Wildner.Ft void 62cb0ac91aSSascha Wildner.Fn atomic_subtract_[acq_|rel_]<type> "volatile <type> *p" "<type> v" 63cb0ac91aSSascha Wildner.Ft void 64d42a763bSAaron LI.Fn atomic_store_[rel_]<type> "volatile <type> *p" "<type> v" 65cb0ac91aSSascha Wildner.Sh DESCRIPTION 66cb0ac91aSSascha WildnerEach of the atomic operations is guaranteed to be atomic in the presence of 67cb0ac91aSSascha Wildnerinterrupts. 68cb0ac91aSSascha WildnerThey can be used to implement reference counts or as building blocks for more 69*2f45ab90SAaron LIadvanced synchronization primitives, such as mutexes. 70*2f45ab90SAaron LI.Pp 71*2f45ab90SAaron LIOn all architectures supported by 72*2f45ab90SAaron LI. Dx , 73*2f45ab90SAaron LIordinary loads and stores of integers in cache-coherent memory are 74*2f45ab90SAaron LIinherently atomic if the integer is naturally aligned and its size does 75*2f45ab90SAaron LInot exceed the processor's word size. 76*2f45ab90SAaron LIHowever, such loads and stores may be elided from the program by the 77*2f45ab90SAaron LIcompiler, whereas atomic operations are always performed. 78*2f45ab90SAaron LI.Pp 79*2f45ab90SAaron LIExcept as noted below, the semantics of these operations are almost 80*2f45ab90SAaron LIidentical to the semantics of similarly named C11 atomic operations. 81cb0ac91aSSascha Wildner.Ss Types 82cb0ac91aSSascha WildnerEach atomic operation operates on a specific 83cb0ac91aSSascha Wildner.Fa type . 84cb0ac91aSSascha WildnerThe type to use is indicated in the function name. 85*2f45ab90SAaron LIIn contrast to C11 atomic operations, 86*2f45ab90SAaron LI.Dx Ns 's 87*2f45ab90SAaron LIatomic operations are performed on ordinary integer types. 88*2f45ab90SAaron LIThe available types are: 89cb0ac91aSSascha Wildner.Pp 907cecd65aSzrj.Bl -tag -offset indent -width ".Li cpumask" -compact 91619596bfSSascha Wildner.It Li cpumask 92619596bfSSascha WildnerCPU mask (cpumask_t) 93cb0ac91aSSascha Wildner.It Li int 94cb0ac91aSSascha Wildnerunsigned integer 95cb0ac91aSSascha Wildner.It Li long 96cb0ac91aSSascha Wildnerunsigned long integer 97cb0ac91aSSascha Wildner.It Li ptr 98cb0ac91aSSascha Wildnerunsigned integer the size of a pointer 99cb0ac91aSSascha Wildner.It Li 32 100cb0ac91aSSascha Wildnerunsigned 32-bit integer 101*2f45ab90SAaron LI.It Li 64 102*2f45ab90SAaron LIunsigned 64-bit integer 103cb0ac91aSSascha Wildner.El 104cb0ac91aSSascha Wildner.Pp 105cb0ac91aSSascha WildnerFor example, the function to atomically add two integers is called 106cb0ac91aSSascha Wildner.Fn atomic_add_int . 107cb0ac91aSSascha Wildner.Pp 108cb0ac91aSSascha WildnerCertain architectures also provide operations for types smaller than 109cb0ac91aSSascha Wildner.Dq Li int . 110cb0ac91aSSascha Wildner.Pp 111cb0ac91aSSascha Wildner.Bl -tag -offset indent -width short -compact 112cb0ac91aSSascha Wildner.It Li char 113cb0ac91aSSascha Wildnerunsigned character 114cb0ac91aSSascha Wildner.It Li short 115cb0ac91aSSascha Wildnerunsigned short integer 116cb0ac91aSSascha Wildner.It Li 8 117cb0ac91aSSascha Wildnerunsigned 8-bit integer 118cb0ac91aSSascha Wildner.It Li 16 119cb0ac91aSSascha Wildnerunsigned 16-bit integer 120cb0ac91aSSascha Wildner.El 121cb0ac91aSSascha Wildner.Pp 122*2f45ab90SAaron LIThese must not be used in machine-independent code, because the instructions 123*2f45ab90SAaron LIto implement them efficiently may not be available. 124cb0ac91aSSascha Wildner.Ss Memory Barriers 125cb0ac91aSSascha WildnerMemory barriers are used to guarantee the order of data accesses in 126cb0ac91aSSascha Wildnertwo ways. 127cb0ac91aSSascha WildnerFirst, they specify hints to the compiler to not re-order or optimize the 128cb0ac91aSSascha Wildneroperations. 129cb0ac91aSSascha WildnerSecond, on architectures that do not guarantee ordered data accesses, 130cb0ac91aSSascha Wildnerspecial instructions or special variants of instructions are used to indicate 131cb0ac91aSSascha Wildnerto the processor that data accesses need to occur in a certain order. 132cb0ac91aSSascha WildnerAs a result, most of the atomic operations have three variants in order to 133cb0ac91aSSascha Wildnerinclude optional memory barriers. 134cb0ac91aSSascha WildnerThe first form just performs the operation without any explicit barriers. 135cb0ac91aSSascha WildnerThe second form uses a read memory barrier, and the third variant uses a write 136cb0ac91aSSascha Wildnermemory barrier. 137cb0ac91aSSascha Wildner.Pp 138cb0ac91aSSascha WildnerThe second variant of each operation includes a read memory barrier. 139cb0ac91aSSascha WildnerThis barrier ensures that the effects of this operation are completed before the 140cb0ac91aSSascha Wildnereffects of any later data accesses. 141cb0ac91aSSascha WildnerAs a result, the operation is said to have acquire semantics as it acquires a 142cb0ac91aSSascha Wildnerpseudo-lock requiring further operations to wait until it has completed. 143cb0ac91aSSascha WildnerTo denote this, the suffix 144cb0ac91aSSascha Wildner.Dq Li _acq 145cb0ac91aSSascha Wildneris inserted into the function name immediately prior to the 146cb0ac91aSSascha Wildner.Dq Li _ Ns Aq Fa type 147cb0ac91aSSascha Wildnersuffix. 148cb0ac91aSSascha WildnerFor example, to subtract two integers ensuring that any later writes will 149cb0ac91aSSascha Wildnerhappen after the subtraction is performed, use 150cb0ac91aSSascha Wildner.Fn atomic_subtract_acq_int . 151cb0ac91aSSascha Wildner.Pp 152cb0ac91aSSascha WildnerThe third variant of each operation includes a write memory barrier. 153cb0ac91aSSascha WildnerThis ensures that all effects of all previous data accesses are completed 154cb0ac91aSSascha Wildnerbefore this operation takes place. 155cb0ac91aSSascha WildnerAs a result, the operation is said to have release semantics as it releases 156cb0ac91aSSascha Wildnerany pending data accesses to be completed before its operation is performed. 157cb0ac91aSSascha WildnerTo denote this, the suffix 158cb0ac91aSSascha Wildner.Dq Li _rel 159cb0ac91aSSascha Wildneris inserted into the function name immediately prior to the 160cb0ac91aSSascha Wildner.Dq Li _ Ns Aq Fa type 161cb0ac91aSSascha Wildnersuffix. 162cb0ac91aSSascha WildnerFor example, to add two long integers ensuring that all previous 163cb0ac91aSSascha Wildnerwrites will happen first, use 164cb0ac91aSSascha Wildner.Fn atomic_add_rel_long . 165cb0ac91aSSascha Wildner.Pp 166cb0ac91aSSascha WildnerA practical example of using memory barriers is to ensure that data accesses 167cb0ac91aSSascha Wildnerthat are protected by a lock are all performed while the lock is held. 168cb0ac91aSSascha WildnerTo achieve this, one would use a read barrier when acquiring the lock to 169cb0ac91aSSascha Wildnerguarantee that the lock is held before any protected operations are performed. 170cb0ac91aSSascha WildnerFinally, one would use a write barrier when releasing the lock to ensure that 171cb0ac91aSSascha Wildnerall of the protected operations are completed before the lock is released. 172cb0ac91aSSascha Wildner.Ss Multiple Processors 173cb0ac91aSSascha WildnerThe current set of atomic operations do not necessarily guarantee atomicity 174cb0ac91aSSascha Wildneracross multiple processors. 175cb0ac91aSSascha WildnerTo guarantee atomicity across processors, not only does the individual 176cb0ac91aSSascha Wildneroperation need to be atomic on the processor performing the operation, but 177cb0ac91aSSascha Wildnerthe result of the operation needs to be pushed out to stable storage and the 178cb0ac91aSSascha Wildnercaches of all other processors on the system need to invalidate any cache 179cb0ac91aSSascha Wildnerlines that include the affected memory region. 180cb0ac91aSSascha Wildner.Ss Semantics 181cb0ac91aSSascha WildnerThis section describes the semantics of each operation using a C like notation. 182cb0ac91aSSascha Wildner.Bl -hang 183cb0ac91aSSascha Wildner.It Fn atomic_add p v 184cb0ac91aSSascha Wildner.Bd -literal -compact 185cb0ac91aSSascha Wildner*p += v; 186cb0ac91aSSascha Wildner.Ed 187619596bfSSascha Wildner.El 188619596bfSSascha Wildner.Pp 189619596bfSSascha WildnerThe 190619596bfSSascha Wildner.Fn atomic_add 191619596bfSSascha Wildnerfunctions are not implemented for the type 192619596bfSSascha Wildner.Dq Li cpumask . 193619596bfSSascha Wildner.Bl -hang 194cb0ac91aSSascha Wildner.It Fn atomic_clear p v 195cb0ac91aSSascha Wildner.Bd -literal -compact 196cb0ac91aSSascha Wildner*p &= ~v; 197cb0ac91aSSascha Wildner.Ed 198cb0ac91aSSascha Wildner.It Fn atomic_cmpset dst old new 199cb0ac91aSSascha Wildner.Bd -literal -compact 200cb0ac91aSSascha Wildnerif (*dst == old) { 201cb0ac91aSSascha Wildner *dst = new; 202cb0ac91aSSascha Wildner return 1; 2038dae8275SJoris GIOVANNANGELI} else { 204cb0ac91aSSascha Wildner return 0; 2058dae8275SJoris GIOVANNANGELI} 206cb0ac91aSSascha Wildner.Ed 207cb0ac91aSSascha Wildner.El 208cb0ac91aSSascha Wildner.Pp 209cb0ac91aSSascha WildnerThe 210cb0ac91aSSascha Wildner.Fn atomic_cmpset 211cb0ac91aSSascha Wildnerfunctions are not implemented for the types 212cb0ac91aSSascha Wildner.Dq Li char , 213cb0ac91aSSascha Wildner.Dq Li short , 214cb0ac91aSSascha Wildner.Dq Li 8 , 215cb0ac91aSSascha Wildnerand 216cb0ac91aSSascha Wildner.Dq Li 16 . 217cb0ac91aSSascha Wildner.Bl -hang 218cb0ac91aSSascha Wildner.It Fn atomic_fetchadd p v 219cb0ac91aSSascha Wildner.Bd -literal -compact 220cb0ac91aSSascha Wildnertmp = *p; 221cb0ac91aSSascha Wildner*p += v; 222cb0ac91aSSascha Wildnerreturn tmp; 223cb0ac91aSSascha Wildner.Ed 224cb0ac91aSSascha Wildner.El 225cb0ac91aSSascha Wildner.Pp 226cb0ac91aSSascha WildnerThe 227cb0ac91aSSascha Wildner.Fn atomic_fetchadd 228cb0ac91aSSascha Wildnerfunctions are only implemented for the types 229cb0ac91aSSascha Wildner.Dq Li int , 230cb0ac91aSSascha Wildner.Dq Li long 231cb0ac91aSSascha Wildnerand 232cb0ac91aSSascha Wildner.Dq Li 32 233cb0ac91aSSascha Wildnerand do not have any variants with memory barriers at this time. 234cb0ac91aSSascha Wildner.Bl -hang 235cb0ac91aSSascha Wildner.It Fn atomic_load addr 236cb0ac91aSSascha Wildner.Bd -literal -compact 237cb0ac91aSSascha Wildnerreturn (*addr) 238cb0ac91aSSascha Wildner.Ed 239cb0ac91aSSascha Wildner.It Fn atomic_readandclear addr 240cb0ac91aSSascha Wildner.Bd -literal -compact 241cb0ac91aSSascha Wildnertemp = *addr; 242cb0ac91aSSascha Wildner*addr = 0; 243cb0ac91aSSascha Wildnerreturn (temp); 244cb0ac91aSSascha Wildner.Ed 245cb0ac91aSSascha Wildner.El 246cb0ac91aSSascha Wildner.Pp 247cb0ac91aSSascha WildnerThe 248cb0ac91aSSascha Wildner.Fn atomic_readandclear 249cb0ac91aSSascha Wildnerfunctions are not implemented for the types 250cb0ac91aSSascha Wildner.Dq Li char , 251cb0ac91aSSascha Wildner.Dq Li short , 252cb0ac91aSSascha Wildner.Dq Li ptr , 253cb0ac91aSSascha Wildner.Dq Li 8 , 254619596bfSSascha Wildner.Dq Li 16 , 255cb0ac91aSSascha Wildnerand 256619596bfSSascha Wildner.Dq Li cpumask 257cb0ac91aSSascha Wildnerand do 258cb0ac91aSSascha Wildnernot have any variants with memory barriers at this time. 259cb0ac91aSSascha Wildner.Bl -hang 260cb0ac91aSSascha Wildner.It Fn atomic_set p v 261cb0ac91aSSascha Wildner.Bd -literal -compact 262cb0ac91aSSascha Wildner*p |= v; 263cb0ac91aSSascha Wildner.Ed 264cb0ac91aSSascha Wildner.It Fn atomic_subtract p v 265cb0ac91aSSascha Wildner.Bd -literal -compact 266cb0ac91aSSascha Wildner*p -= v; 267cb0ac91aSSascha Wildner.Ed 268619596bfSSascha Wildner.El 269619596bfSSascha Wildner.Pp 270619596bfSSascha WildnerThe 271619596bfSSascha Wildner.Fn atomic_subtract 272619596bfSSascha Wildnerfunctions are not implemented for the type 273619596bfSSascha Wildner.Dq Li cpumask . 274619596bfSSascha Wildner.Bl -hang 275cb0ac91aSSascha Wildner.It Fn atomic_store p v 276cb0ac91aSSascha Wildner.Bd -literal -compact 277cb0ac91aSSascha Wildner*p = v; 278cb0ac91aSSascha Wildner.Ed 279cb0ac91aSSascha Wildner.El 280cb0ac91aSSascha Wildner.Sh RETURN VALUES 281cb0ac91aSSascha WildnerThe 282cb0ac91aSSascha Wildner.Fn atomic_cmpset 283cb0ac91aSSascha Wildnerfunction 284cb0ac91aSSascha Wildnerreturns the result of the compare operation. 285cb0ac91aSSascha WildnerThe 286cb0ac91aSSascha Wildner.Fn atomic_fetchadd , 287cb0ac91aSSascha Wildner.Fn atomic_load , 288cb0ac91aSSascha Wildnerand 289cb0ac91aSSascha Wildner.Fn atomic_readandclear 290cb0ac91aSSascha Wildnerfunctions 291cb0ac91aSSascha Wildnerreturn the value at the specified address. 292cb0ac91aSSascha Wildner.\".Sh EXAMPLES 293cb0ac91aSSascha Wildner.\"This example uses the 294cb0ac91aSSascha Wildner.\".Fn atomic_cmpset_acq_ptr 295cb0ac91aSSascha Wildner.\"and 296cb0ac91aSSascha Wildner.\".Fn atomic_set_ptr 297cb0ac91aSSascha Wildner.\"functions to obtain a sleep mutex and handle recursion. 298cb0ac91aSSascha Wildner.\"Since the 299cb0ac91aSSascha Wildner.\".Va mtx_lock 300cb0ac91aSSascha Wildner.\"member of a 301cb0ac91aSSascha Wildner.\".Vt "struct mtx" 302cb0ac91aSSascha Wildner.\"is a pointer, the 303cb0ac91aSSascha Wildner.\".Dq Li ptr 304cb0ac91aSSascha Wildner.\"type is used. 305cb0ac91aSSascha Wildner.\".Bd -literal 306cb0ac91aSSascha Wildner.\"/* Try to obtain mtx_lock once. */ 307cb0ac91aSSascha Wildner.\"#define _obtain_lock(mp, tid) \\ 308cb0ac91aSSascha Wildner.\" atomic_cmpset_acq_ptr(&(mp)->mtx_lock, MTX_UNOWNED, (tid)) 309cb0ac91aSSascha Wildner.\" 310cb0ac91aSSascha Wildner.\"/* Get a sleep lock, deal with recursion inline. */ 311cb0ac91aSSascha Wildner.\"#define _get_sleep_lock(mp, tid, opts, file, line) do { \\ 312cb0ac91aSSascha Wildner.\" uintptr_t _tid = (uintptr_t)(tid); \\ 313cb0ac91aSSascha Wildner.\" \\ 314cb0ac91aSSascha Wildner.\" if (!_obtain_lock(mp, tid)) { \\ 315cb0ac91aSSascha Wildner.\" if (((mp)->mtx_lock & MTX_FLAGMASK) != _tid) \\ 316cb0ac91aSSascha Wildner.\" _mtx_lock_sleep((mp), _tid, (opts), (file), (line));\\ 317cb0ac91aSSascha Wildner.\" else { \\ 318cb0ac91aSSascha Wildner.\" atomic_set_ptr(&(mp)->mtx_lock, MTX_RECURSE); \\ 319cb0ac91aSSascha Wildner.\" (mp)->mtx_recurse++; \\ 320cb0ac91aSSascha Wildner.\" } \\ 321cb0ac91aSSascha Wildner.\" } \\ 322cb0ac91aSSascha Wildner.\"} while (0) 323cb0ac91aSSascha Wildner.\".Ed 324cb0ac91aSSascha Wildner.Sh HISTORY 325cb0ac91aSSascha WildnerThe 326cb0ac91aSSascha Wildner.Fn atomic_add , 327cb0ac91aSSascha Wildner.Fn atomic_clear , 328cb0ac91aSSascha Wildner.Fn atomic_set , 329cb0ac91aSSascha Wildnerand 330cb0ac91aSSascha Wildner.Fn atomic_subtract 331cb0ac91aSSascha Wildneroperations were first introduced in 332cb0ac91aSSascha Wildner.Fx 3.0 . 333cb0ac91aSSascha WildnerThis first set only supported the types 334cb0ac91aSSascha Wildner.Dq Li char , 335cb0ac91aSSascha Wildner.Dq Li short , 336cb0ac91aSSascha Wildner.Dq Li int , 337cb0ac91aSSascha Wildnerand 338cb0ac91aSSascha Wildner.Dq Li long . 339d42a763bSAaron LI.Pp 340cb0ac91aSSascha WildnerThe 341cb0ac91aSSascha Wildner.Fn atomic_cmpset , 342cb0ac91aSSascha Wildner.Fn atomic_load , 343cb0ac91aSSascha Wildner.Fn atomic_readandclear , 344cb0ac91aSSascha Wildnerand 345cb0ac91aSSascha Wildner.Fn atomic_store 346cb0ac91aSSascha Wildneroperations were added in 347cb0ac91aSSascha Wildner.Fx 5.0 . 348cb0ac91aSSascha WildnerThe types 349cb0ac91aSSascha Wildner.Dq Li 8 , 350cb0ac91aSSascha Wildner.Dq Li 16 , 351cb0ac91aSSascha Wildner.Dq Li 32 , 352*2f45ab90SAaron LI.Dq Li 64 , 353cb0ac91aSSascha Wildnerand 354cb0ac91aSSascha Wildner.Dq Li ptr 355cb0ac91aSSascha Wildnerand all of the acquire and release variants 356cb0ac91aSSascha Wildnerwere added in 357cb0ac91aSSascha Wildner.Fx 5.0 358cb0ac91aSSascha Wildneras well. 359d42a763bSAaron LI.Pp 360cb0ac91aSSascha WildnerThe 361cb0ac91aSSascha Wildner.Fn atomic_fetchadd 362cb0ac91aSSascha Wildneroperations were added in 363cb0ac91aSSascha Wildner.Fx 6.0 . 364d42a763bSAaron LI.Pp 365d42a763bSAaron LIThe relaxed variants of 366d42a763bSAaron LI.Fn atomic_load 367d42a763bSAaron LIand 368d42a763bSAaron LI.Fn atomic_store 369d42a763bSAaron LIwere added in 370d42a763bSAaron LI.Fx 12.0 371d42a763bSAaron LIand 372d42a763bSAaron LI.Dx 6.5 . 373