xref: /freebsd/share/man/man3/ATOMIC_VAR_INIT.3 (revision fa9896e082a1046ff4fbc75fcba4d18d1f2efc19)
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