14d8a7eabSEd Schouten.\" Copyright (c) 2011 Ed Schouten <ed@FreeBSD.org> 24d8a7eabSEd Schouten.\" All rights reserved. 34d8a7eabSEd Schouten.\" 44d8a7eabSEd Schouten.\" Redistribution and use in source and binary forms, with or without 54d8a7eabSEd Schouten.\" modification, are permitted provided that the following conditions 64d8a7eabSEd Schouten.\" are met: 74d8a7eabSEd Schouten.\" 1. Redistributions of source code must retain the above copyright 84d8a7eabSEd Schouten.\" notice, this list of conditions and the following disclaimer. 94d8a7eabSEd Schouten.\" 2. Redistributions in binary form must reproduce the above copyright 104d8a7eabSEd Schouten.\" notice, this list of conditions and the following disclaimer in the 114d8a7eabSEd Schouten.\" documentation and/or other materials provided with the distribution. 124d8a7eabSEd Schouten.\" 134d8a7eabSEd Schouten.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 144d8a7eabSEd Schouten.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 154d8a7eabSEd Schouten.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 164d8a7eabSEd Schouten.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 174d8a7eabSEd Schouten.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 184d8a7eabSEd Schouten.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 194d8a7eabSEd Schouten.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 204d8a7eabSEd Schouten.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 214d8a7eabSEd Schouten.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 224d8a7eabSEd Schouten.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 234d8a7eabSEd Schouten.\" SUCH DAMAGE. 244d8a7eabSEd Schouten.\" 254d8a7eabSEd Schouten.Dd December 27, 2011 264d8a7eabSEd Schouten.Dt ATOMIC_VAR_INIT 3 274d8a7eabSEd Schouten.Os 284d8a7eabSEd Schouten.Sh NAME 294d8a7eabSEd Schouten.Nm ATOMIC_VAR_INIT , 304d8a7eabSEd Schouten.Nm atomic_init , 314d8a7eabSEd Schouten.Nm atomic_load , 324d8a7eabSEd Schouten.Nm atomic_store , 334d8a7eabSEd Schouten.Nm atomic_exchange , 344d8a7eabSEd Schouten.Nm atomic_compare_exchange_strong , 354d8a7eabSEd Schouten.Nm atomic_compare_exchange_weak , 364d8a7eabSEd Schouten.Nm atomic_fetch_add , 374d8a7eabSEd Schouten.Nm atomic_fetch_and , 384d8a7eabSEd Schouten.Nm atomic_fetch_or , 394d8a7eabSEd Schouten.Nm atomic_fetch_sub , 404d8a7eabSEd Schouten.Nm atomic_fetch_xor , 414d8a7eabSEd Schouten.Nm atomic_is_lock_free 424d8a7eabSEd Schouten.Nd type-generic atomic operations 434d8a7eabSEd Schouten.Sh SYNOPSIS 444d8a7eabSEd Schouten.In stdatomic.h 454d8a7eabSEd Schouten.Pp 464d8a7eabSEd Schouten_Atomic(T) 474d8a7eabSEd Schouten.Fa v 484d8a7eabSEd Schouten= ATOMIC_VAR_INIT(c); 494d8a7eabSEd Schouten.Ft void 504d8a7eabSEd Schouten.Fn atomic_init "_Atomic(T) *object" "T value" 514d8a7eabSEd Schouten.Ft T 524d8a7eabSEd Schouten.Fn atomic_load "_Atomic(T) *object" 534d8a7eabSEd Schouten.Ft T 544d8a7eabSEd Schouten.Fn atomic_load_explicit "_Atomic(T) *object" "memory_order order" 554d8a7eabSEd Schouten.Ft void 564d8a7eabSEd Schouten.Fn atomic_store "_Atomic(T) *object" "T desired" 574d8a7eabSEd Schouten.Ft void 584d8a7eabSEd Schouten.Fn atomic_store_explicit "_Atomic(T) *object" "T desired" "memory_order order" 594d8a7eabSEd Schouten.Ft T 604d8a7eabSEd Schouten.Fn atomic_exchange "_Atomic(T) *object" "T desired" 614d8a7eabSEd Schouten.Ft T 624d8a7eabSEd Schouten.Fn atomic_exchange_explicit "_Atomic(T) *object" "T desired" "memory_order order" 634d8a7eabSEd Schouten.Ft _Bool 644d8a7eabSEd Schouten.Fn atomic_compare_exchange_strong "_Atomic(T) *object" "T *expected" "T desired" 654d8a7eabSEd Schouten.Ft _Bool 664d8a7eabSEd Schouten.Fn atomic_compare_exchange_strong_explicit "_Atomic(T) *object" "T *expected" "T desired" "memory_order success" "memory_order failure" 674d8a7eabSEd Schouten.Ft _Bool 684d8a7eabSEd Schouten.Fn atomic_compare_exchange_weak "_Atomic(T) *object" "T *expected" "T desired" 694d8a7eabSEd Schouten.Ft _Bool 704d8a7eabSEd Schouten.Fn atomic_compare_exchange_weak_explicit "_Atomic(T) *object" "T *expected" "T desired" "memory_order success" "memory_order failure" 714d8a7eabSEd Schouten.Ft T 724d8a7eabSEd Schouten.Fn atomic_fetch_add "_Atomic(T) *object" "T operand" 734d8a7eabSEd Schouten.Ft T 744d8a7eabSEd Schouten.Fn atomic_fetch_add_explicit "_Atomic(T) *object" "T operand" "memory_order order" 754d8a7eabSEd Schouten.Ft T 764d8a7eabSEd Schouten.Fn atomic_fetch_and "_Atomic(T) *object" "T operand" 774d8a7eabSEd Schouten.Ft T 784d8a7eabSEd Schouten.Fn atomic_fetch_and_explicit "_Atomic(T) *object" "T operand" "memory_order order" 794d8a7eabSEd Schouten.Ft T 804d8a7eabSEd Schouten.Fn atomic_fetch_or "_Atomic(T) *object" "T operand" 814d8a7eabSEd Schouten.Ft T 824d8a7eabSEd Schouten.Fn atomic_fetch_or_explicit "_Atomic(T) *object" "T operand" "memory_order order" 834d8a7eabSEd Schouten.Ft T 844d8a7eabSEd Schouten.Fn atomic_fetch_sub "_Atomic(T) *object" "T operand" 854d8a7eabSEd Schouten.Ft T 864d8a7eabSEd Schouten.Fn atomic_fetch_sub_explicit "_Atomic(T) *object" "T operand" "memory_order order" 874d8a7eabSEd Schouten.Ft T 884d8a7eabSEd Schouten.Fn atomic_fetch_xor "_Atomic(T) *object" "T operand" 894d8a7eabSEd Schouten.Ft T 904d8a7eabSEd Schouten.Fn atomic_fetch_xor_explicit "_Atomic(T) *object" "T operand" "memory_order order" 914d8a7eabSEd Schouten.Ft _Bool 924d8a7eabSEd Schouten.Fn atomic_is_lock_free "const _Atomic(T) *object" 934d8a7eabSEd Schouten.Sh DESCRIPTION 944d8a7eabSEd SchoutenThe header 954d8a7eabSEd Schouten.In stdatomic.h 964d8a7eabSEd Schoutenprovides type-generic macros for atomic operations. 974d8a7eabSEd SchoutenAtomic operations can be used by multithreaded programs to provide 984d8a7eabSEd Schoutenshared variables between threads that in most cases may be modified 994d8a7eabSEd Schoutenwithout acquiring locks. 1004d8a7eabSEd Schouten.Pp 1014d8a7eabSEd SchoutenAtomic variables are declared using the 1024d8a7eabSEd Schouten.Fn _Atomic 1034d8a7eabSEd Schoutentype specifier. 1044d8a7eabSEd SchoutenThese variables are not type-compatible with their non-atomic 1054d8a7eabSEd Schoutencounterparts. 1064d8a7eabSEd SchoutenDepending on the compiler used, atomic variables may be opaque and can 1074d8a7eabSEd Schoutentherefore only be influenced using the macros described. 1084d8a7eabSEd Schouten.Pp 1094d8a7eabSEd SchoutenThe 1104d8a7eabSEd Schouten.Fn atomic_init 1114d8a7eabSEd Schoutenmacro initializes the atomic variable 1124d8a7eabSEd Schouten.Fa object 1134d8a7eabSEd Schoutenwith a 1144d8a7eabSEd Schouten.Fa value . 1154d8a7eabSEd SchoutenAtomic variables can be initialized while being declared using 1164d8a7eabSEd Schouten.Fn ATOMIC_VAR_INIT . 1174d8a7eabSEd Schouten.Pp 1184d8a7eabSEd SchoutenThe 1194d8a7eabSEd Schouten.Fn atomic_load 1204d8a7eabSEd Schoutenmacro returns the value of atomic variable 1214d8a7eabSEd Schouten.Fa object . 1224d8a7eabSEd SchoutenThe 1234d8a7eabSEd Schouten.Fn atomic_store 1244d8a7eabSEd Schoutenmacro sets the atomic variable 1254d8a7eabSEd Schouten.Fa object 1264d8a7eabSEd Schoutento its 1274d8a7eabSEd Schouten.Fa desired 1284d8a7eabSEd Schoutenvalue. 1294d8a7eabSEd Schouten.Pp 1304d8a7eabSEd SchoutenThe 1314d8a7eabSEd Schouten.Fn atomic_exchange 1324d8a7eabSEd Schoutenmacro combines the behaviour of 1334d8a7eabSEd Schouten.Fn atomic_load 1344d8a7eabSEd Schoutenand 1354d8a7eabSEd Schouten.Fn atomic_store . 1364d8a7eabSEd SchoutenIt sets the atomic variable 1374d8a7eabSEd Schouten.Fa object 1384d8a7eabSEd Schoutento its desired 1394d8a7eabSEd Schouten.Fa value 140a3fb6da9SGlen Barberand returns the original contents of the atomic variable. 1414d8a7eabSEd Schouten.Pp 1424d8a7eabSEd SchoutenThe 1434d8a7eabSEd Schouten.Fn atomic_compare_exchange_strong 1444d8a7eabSEd Schoutenmacro stores a 1454d8a7eabSEd Schouten.Fa desired 1464d8a7eabSEd Schoutenvalue into atomic variable 1474d8a7eabSEd Schouten.Fa object , 1484d8a7eabSEd Schoutenonly if the atomic variable is equal to its 1494d8a7eabSEd Schouten.Fa expected 1504d8a7eabSEd Schoutenvalue. 1514d8a7eabSEd SchoutenUpon success, the macro returns 1524d8a7eabSEd Schouten.Dv true . 1534d8a7eabSEd SchoutenUpon failure, the 1544d8a7eabSEd Schouten.Fa desired 1554d8a7eabSEd Schoutenvalue is overwritten with the value of the atomic variable and 1564d8a7eabSEd Schouten.Dv false 1574d8a7eabSEd Schoutenis returned. 1584d8a7eabSEd SchoutenThe 1594d8a7eabSEd Schouten.Fn atomic_compare_exchange_weak 1604d8a7eabSEd Schoutenmacro is identical to 1614d8a7eabSEd Schouten.Fn atomic_compare_exchange_strong , 1624d8a7eabSEd Schoutenbut is allowed to fail even if atomic variable 1634d8a7eabSEd Schouten.Fa object 1644d8a7eabSEd Schoutenis equal to its 1654d8a7eabSEd Schouten.Fa expected 1664d8a7eabSEd Schoutenvalue. 1674d8a7eabSEd Schouten.Pp 1684d8a7eabSEd SchoutenThe 1694d8a7eabSEd Schouten.Fn atomic_fetch_add 1704d8a7eabSEd Schoutenmacro adds the value 1714d8a7eabSEd Schouten.Fa operand 1724d8a7eabSEd Schoutento atomic variable 1734d8a7eabSEd Schouten.Fa object 1744d8a7eabSEd Schoutenand returns the original contents of the atomic variable. 1754d8a7eabSEd Schouten.Pp 1764d8a7eabSEd SchoutenThe 1774d8a7eabSEd Schouten.Fn atomic_fetch_and 1784d8a7eabSEd Schoutenmacro applies the 1794d8a7eabSEd Schouten.Em and 1804d8a7eabSEd Schoutenoperator to atomic variable 1814d8a7eabSEd Schouten.Fa object 1824d8a7eabSEd Schoutenand 1834d8a7eabSEd Schouten.Fa operand 1844d8a7eabSEd Schoutenand stores the value into 1854d8a7eabSEd Schouten.Fa object , 1864d8a7eabSEd Schoutenwhile returning the original contents of the atomic variable. 1874d8a7eabSEd Schouten.Pp 1884d8a7eabSEd SchoutenThe 1894d8a7eabSEd Schouten.Fn atomic_fetch_or 1904d8a7eabSEd Schoutenmacro applies the 1914d8a7eabSEd Schouten.Em or 1924d8a7eabSEd Schoutenoperator to atomic variable 1934d8a7eabSEd Schouten.Fa object 1944d8a7eabSEd Schoutenand 1954d8a7eabSEd Schouten.Fa operand 1964d8a7eabSEd Schoutenand stores the value into 1974d8a7eabSEd Schouten.Fa object , 1984d8a7eabSEd Schoutenwhile returning the original contents of the atomic variable. 1994d8a7eabSEd Schouten.Pp 2004d8a7eabSEd SchoutenThe 2014d8a7eabSEd Schouten.Fn atomic_fetch_sub 2024d8a7eabSEd Schoutenmacro subtracts the value 2034d8a7eabSEd Schouten.Fa operand 204a3fb6da9SGlen Barberfrom atomic variable 2054d8a7eabSEd Schouten.Fa object 2064d8a7eabSEd Schoutenand returns the original contents of the atomic variable. 2074d8a7eabSEd Schouten.Pp 2084d8a7eabSEd SchoutenThe 2094d8a7eabSEd Schouten.Fn atomic_fetch_xor 2104d8a7eabSEd Schoutenmacro applies the 2114d8a7eabSEd Schouten.Em xor 2124d8a7eabSEd Schoutenoperator to atomic variable 2134d8a7eabSEd Schouten.Fa object 2144d8a7eabSEd Schoutenand 2154d8a7eabSEd Schouten.Fa operand 2164d8a7eabSEd Schoutenand stores the value into 2174d8a7eabSEd Schouten.Fa object , 2184d8a7eabSEd Schoutenwhile returning the original contents of the atomic variable. 2194d8a7eabSEd Schouten.Pp 2204d8a7eabSEd SchoutenThe 2214d8a7eabSEd Schouten.Fn atomic_is_lock_free 2224d8a7eabSEd Schoutenmacro returns whether atomic variable 2234d8a7eabSEd Schouten.Fa object 2244d8a7eabSEd Schoutenuses locks when using atomic operations. 2254d8a7eabSEd Schouten.Sh BARRIERS 2264d8a7eabSEd SchoutenThe atomic operations described previously are implemented in such a way 2274d8a7eabSEd Schoutenthat they disallow both the compiler and the executing processor to 2284d8a7eabSEd Schoutenre-order any nearby memory operations across the atomic operation. 2294d8a7eabSEd SchoutenIn certain cases this behaviour may cause suboptimal performance. 2304d8a7eabSEd SchoutenTo mitigate this, every atomic operation has an 2314d8a7eabSEd Schouten.Fn _explicit 2324d8a7eabSEd Schoutenversion that allows the re-ordering to be configured. 2334d8a7eabSEd Schouten.Pp 2344d8a7eabSEd SchoutenThe 2354d8a7eabSEd Schouten.Fa order 2364d8a7eabSEd Schoutenparameter of these 2374d8a7eabSEd Schouten.Fn _explicit 2384d8a7eabSEd Schoutenmacros can have one of the following values. 2394d8a7eabSEd Schouten.Bl -tag -width memory_order_relaxed 2404d8a7eabSEd Schouten.It Dv memory_order_relaxed 2414d8a7eabSEd SchoutenNo operation orders memory. 2424d8a7eabSEd Schouten.It Dv memory_order_consume 2434d8a7eabSEd SchoutenPerform consume operation. 2444d8a7eabSEd Schouten.It Dv memory_order_acquire 2454d8a7eabSEd SchoutenAcquire fence. 2464d8a7eabSEd Schouten.It Dv memory_order_release 2474d8a7eabSEd SchoutenRelease fence. 2484d8a7eabSEd Schouten.It Dv memory_order_acq_rel 2494d8a7eabSEd SchoutenAcquire and release fence. 2504d8a7eabSEd Schouten.It Dv memory_order_seq_cst 2514d8a7eabSEd SchoutenSequentially consistent acquire and release fence. 2524d8a7eabSEd Schouten.El 2534d8a7eabSEd Schouten.Pp 2544d8a7eabSEd SchoutenThe previously described macros are identical to the 2554d8a7eabSEd Schouten.Fn _explicit 2564d8a7eabSEd Schoutenmacros, when 2574d8a7eabSEd Schouten.Fa order 2584d8a7eabSEd Schoutenis 2594d8a7eabSEd Schouten.Dv memory_order_seq_cst . 2604d8a7eabSEd Schouten.Sh COMPILER SUPPORT 2614d8a7eabSEd SchoutenThese atomic operations are typically implemented by the compiler, as 2624d8a7eabSEd Schoutenthey must be implemented type-generically and must often use special 2634d8a7eabSEd Schoutenhardware instructions. 2644d8a7eabSEd SchoutenAs this interface has not been adopted by most compilers yet, the 2654d8a7eabSEd Schouten.In stdatomic.h 2664d8a7eabSEd Schoutenheader implements these macros on top of existing compiler intrinsics to 2674d8a7eabSEd Schoutenprovide forward compatibility. 2684d8a7eabSEd Schouten.Pp 2694d8a7eabSEd SchoutenThis means that certain aspects of the interface, such as support for 2704d8a7eabSEd Schoutendifferent barrier types may simply be ignored. 2714d8a7eabSEd SchoutenWhen using GCC, all atomic operations are executed as if they are using 2724d8a7eabSEd Schouten.Dv memory_order_seq_cst . 2734d8a7eabSEd Schouten.Pp 2744d8a7eabSEd SchoutenInstead of using the atomic operations provided by this interface, 275cabdddaeSUlrich Spörlein.St -isoC-2011 2764d8a7eabSEd Schoutenallows the atomic variables to be modified directly using built-in 2774d8a7eabSEd Schoutenlanguage operators. 2784d8a7eabSEd SchoutenThis behaviour cannot be emulated for older compilers. 2794d8a7eabSEd SchoutenTo prevent unintended non-atomic access to these variables, this header 2804d8a7eabSEd Schoutenfile places the atomic variable in a structure when using an older 2814d8a7eabSEd Schoutencompiler. 282669ab20fSEd Schouten.Pp 283669ab20fSEd SchoutenWhen using GCC on architectures on which it lacks support for built-in 284669ab20fSEd Schoutenatomic intrinsics, these macros may emit function calls to fallback 285669ab20fSEd Schoutenroutines. 286669ab20fSEd SchoutenThese fallback routines are only implemented for 32-bits and 64-bits 287669ab20fSEd Schoutendatatypes, if supported by the CPU. 2884d8a7eabSEd Schouten.Sh SEE ALSO 2894d8a7eabSEd Schouten.Xr pthread 3 , 2904d8a7eabSEd Schouten.Xr atomic 9 2914d8a7eabSEd Schouten.Sh STANDARDS 2924d8a7eabSEd SchoutenThese macros attempt to conform to 293cabdddaeSUlrich Spörlein.St -isoC-2011 . 2944d8a7eabSEd Schouten.Sh HISTORY 2954d8a7eabSEd SchoutenThese macros appeared in 2964d8a7eabSEd Schouten.Fx 10.0 . 2974d8a7eabSEd Schouten.Sh AUTHORS 298*6342c823SBaptiste Daroussin.An \&Ed Schouten Aq Mt ed@FreeBSD.org 299a63d6c94SBaptiste Daroussin.An David Chisnall Aq Mt theraven@FreeBSD.org 300