1.\" Copyright (c) 2011 Ed Schouten <ed@FreeBSD.org> 2.\" All rights reserved. 3.\" 4.\" Redistribution and use in source and binary forms, with or without 5.\" modification, are permitted provided that the following conditions 6.\" are met: 7.\" 1. Redistributions of source code must retain the above copyright 8.\" notice, this list of conditions and the following disclaimer. 9.\" 2. Redistributions in binary form must reproduce the above copyright 10.\" notice, this list of conditions and the following disclaimer in the 11.\" documentation and/or other materials provided with the distribution. 12.\" 13.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23.\" SUCH DAMAGE. 24.\" 25.Dd December 27, 2011 26.Dt ATOMIC_VAR_INIT 3 27.Os 28.Sh NAME 29.Nm ATOMIC_VAR_INIT , 30.Nm atomic_init , 31.Nm atomic_load , 32.Nm atomic_store , 33.Nm atomic_exchange , 34.Nm atomic_compare_exchange_strong , 35.Nm atomic_compare_exchange_weak , 36.Nm atomic_fetch_add , 37.Nm atomic_fetch_and , 38.Nm atomic_fetch_or , 39.Nm atomic_fetch_sub , 40.Nm atomic_fetch_xor , 41.Nm atomic_is_lock_free 42.Nd type-generic atomic operations 43.Sh SYNOPSIS 44.In stdatomic.h 45.Pp 46_Atomic(T) 47.Fa v 48= ATOMIC_VAR_INIT(c); 49.Ft void 50.Fn atomic_init "_Atomic(T) *object" "T value" 51.Ft T 52.Fn atomic_load "_Atomic(T) *object" 53.Ft T 54.Fn atomic_load_explicit "_Atomic(T) *object" "memory_order order" 55.Ft void 56.Fn atomic_store "_Atomic(T) *object" "T desired" 57.Ft void 58.Fn atomic_store_explicit "_Atomic(T) *object" "T desired" "memory_order order" 59.Ft T 60.Fn atomic_exchange "_Atomic(T) *object" "T desired" 61.Ft T 62.Fn atomic_exchange_explicit "_Atomic(T) *object" "T desired" "memory_order order" 63.Ft _Bool 64.Fn atomic_compare_exchange_strong "_Atomic(T) *object" "T *expected" "T desired" 65.Ft _Bool 66.Fn atomic_compare_exchange_strong_explicit "_Atomic(T) *object" "T *expected" "T desired" "memory_order success" "memory_order failure" 67.Ft _Bool 68.Fn atomic_compare_exchange_weak "_Atomic(T) *object" "T *expected" "T desired" 69.Ft _Bool 70.Fn atomic_compare_exchange_weak_explicit "_Atomic(T) *object" "T *expected" "T desired" "memory_order success" "memory_order failure" 71.Ft T 72.Fn atomic_fetch_add "_Atomic(T) *object" "T operand" 73.Ft T 74.Fn atomic_fetch_add_explicit "_Atomic(T) *object" "T operand" "memory_order order" 75.Ft T 76.Fn atomic_fetch_and "_Atomic(T) *object" "T operand" 77.Ft T 78.Fn atomic_fetch_and_explicit "_Atomic(T) *object" "T operand" "memory_order order" 79.Ft T 80.Fn atomic_fetch_or "_Atomic(T) *object" "T operand" 81.Ft T 82.Fn atomic_fetch_or_explicit "_Atomic(T) *object" "T operand" "memory_order order" 83.Ft T 84.Fn atomic_fetch_sub "_Atomic(T) *object" "T operand" 85.Ft T 86.Fn atomic_fetch_sub_explicit "_Atomic(T) *object" "T operand" "memory_order order" 87.Ft T 88.Fn atomic_fetch_xor "_Atomic(T) *object" "T operand" 89.Ft T 90.Fn atomic_fetch_xor_explicit "_Atomic(T) *object" "T operand" "memory_order order" 91.Ft _Bool 92.Fn atomic_is_lock_free "const _Atomic(T) *object" 93.Sh DESCRIPTION 94The header 95.In stdatomic.h 96provides type-generic macros for atomic operations. 97Atomic operations can be used by multithreaded programs to provide 98shared variables between threads that in most cases may be modified 99without acquiring locks. 100.Pp 101Atomic variables are declared using the 102.Fn _Atomic 103type specifier. 104These variables are not type-compatible with their non-atomic 105counterparts. 106Depending on the compiler used, atomic variables may be opaque and can 107therefore only be influenced using the macros described. 108.Pp 109The 110.Fn atomic_init 111macro initializes the atomic variable 112.Fa object 113with a 114.Fa value . 115Atomic variables can be initialized while being declared using 116.Fn ATOMIC_VAR_INIT . 117.Pp 118The 119.Fn atomic_load 120macro returns the value of atomic variable 121.Fa object . 122The 123.Fn atomic_store 124macro sets the atomic variable 125.Fa object 126to its 127.Fa desired 128value. 129.Pp 130The 131.Fn atomic_exchange 132macro combines the behaviour of 133.Fn atomic_load 134and 135.Fn atomic_store . 136It sets the atomic variable 137.Fa object 138to its desired 139.Fa value 140and returns the original contents of the atomic variable. 141.Pp 142The 143.Fn atomic_compare_exchange_strong 144macro stores a 145.Fa desired 146value into atomic variable 147.Fa object , 148only if the atomic variable is equal to its 149.Fa expected 150value. 151Upon success, the macro returns 152.Dv true . 153Upon failure, the 154.Fa desired 155value is overwritten with the value of the atomic variable and 156.Dv false 157is returned. 158The 159.Fn atomic_compare_exchange_weak 160macro is identical to 161.Fn atomic_compare_exchange_strong , 162but is allowed to fail even if atomic variable 163.Fa object 164is equal to its 165.Fa expected 166value. 167.Pp 168The 169.Fn atomic_fetch_add 170macro adds the value 171.Fa operand 172to atomic variable 173.Fa object 174and returns the original contents of the atomic variable. 175.Pp 176The 177.Fn atomic_fetch_and 178macro applies the 179.Em and 180operator to atomic variable 181.Fa object 182and 183.Fa operand 184and stores the value into 185.Fa object , 186while returning the original contents of the atomic variable. 187.Pp 188The 189.Fn atomic_fetch_or 190macro applies the 191.Em or 192operator to atomic variable 193.Fa object 194and 195.Fa operand 196and stores the value into 197.Fa object , 198while returning the original contents of the atomic variable. 199.Pp 200The 201.Fn atomic_fetch_sub 202macro subtracts the value 203.Fa operand 204from atomic variable 205.Fa object 206and returns the original contents of the atomic variable. 207.Pp 208The 209.Fn atomic_fetch_xor 210macro applies the 211.Em xor 212operator to atomic variable 213.Fa object 214and 215.Fa operand 216and stores the value into 217.Fa object , 218while returning the original contents of the atomic variable. 219.Pp 220The 221.Fn atomic_is_lock_free 222macro returns whether atomic variable 223.Fa object 224uses locks when using atomic operations. 225.Sh BARRIERS 226The atomic operations described previously are implemented in such a way 227that they disallow both the compiler and the executing processor to 228re-order any nearby memory operations across the atomic operation. 229In certain cases this behaviour may cause suboptimal performance. 230To mitigate this, every atomic operation has an 231.Fn _explicit 232version that allows the re-ordering to be configured. 233.Pp 234The 235.Fa order 236parameter of these 237.Fn _explicit 238macros can have one of the following values. 239.Bl -tag -width memory_order_relaxed 240.It Dv memory_order_relaxed 241No operation orders memory. 242.It Dv memory_order_consume 243Perform consume operation. 244.It Dv memory_order_acquire 245Acquire fence. 246.It Dv memory_order_release 247Release fence. 248.It Dv memory_order_acq_rel 249Acquire and release fence. 250.It Dv memory_order_seq_cst 251Sequentially consistent acquire and release fence. 252.El 253.Pp 254The previously described macros are identical to the 255.Fn _explicit 256macros, when 257.Fa order 258is 259.Dv memory_order_seq_cst . 260.Sh COMPILER SUPPORT 261These atomic operations are typically implemented by the compiler, as 262they must be implemented type-generically and must often use special 263hardware instructions. 264As this interface has not been adopted by most compilers yet, the 265.In stdatomic.h 266header implements these macros on top of existing compiler intrinsics to 267provide forward compatibility. 268.Pp 269This means that certain aspects of the interface, such as support for 270different barrier types may simply be ignored. 271When using GCC, all atomic operations are executed as if they are using 272.Dv memory_order_seq_cst . 273.Pp 274Instead of using the atomic operations provided by this interface, 275.St -isoC-2011 276allows the atomic variables to be modified directly using built-in 277language operators. 278This behaviour cannot be emulated for older compilers. 279To prevent unintended non-atomic access to these variables, this header 280file places the atomic variable in a structure when using an older 281compiler. 282.Pp 283When using GCC on architectures on which it lacks support for built-in 284atomic intrinsics, these macros may emit function calls to fallback 285routines. 286These fallback routines are only implemented for 32-bits and 64-bits 287datatypes, if supported by the CPU. 288.Sh SEE ALSO 289.Xr pthread 3 , 290.Xr atomic 9 291.Sh STANDARDS 292These macros attempt to conform to 293.St -isoC-2011 . 294.Sh HISTORY 295These macros appeared in 296.Fx 10.0 . 297.Sh AUTHORS 298.An \&Ed Schouten Aq Mt ed@FreeBSD.org 299.An David Chisnall Aq Mt theraven@FreeBSD.org 300