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