aboutsummaryrefslogtreecommitdiff
path: root/share/man/man9/atomic.9
diff options
context:
space:
mode:
Diffstat (limited to 'share/man/man9/atomic.9')
-rw-r--r--share/man/man9/atomic.9357
1 files changed, 357 insertions, 0 deletions
diff --git a/share/man/man9/atomic.9 b/share/man/man9/atomic.9
new file mode 100644
index 000000000000..0bc567c4b9bf
--- /dev/null
+++ b/share/man/man9/atomic.9
@@ -0,0 +1,357 @@
+.\" Copyright (c) 2000-2001 John H. Baldwin <jhb@FreeBSD.org>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd September 27, 2005
+.Os
+.Dt ATOMIC 9
+.Sh NAME
+.Nm atomic_add ,
+.Nm atomic_clear ,
+.Nm atomic_cmpset ,
+.Nm atomic_fetchadd ,
+.Nm atomic_load ,
+.Nm atomic_readandclear ,
+.Nm atomic_set ,
+.Nm atomic_subtract ,
+.Nm atomic_store
+.Nd atomic operations
+.Sh SYNOPSIS
+.In sys/types.h
+.In machine/atomic.h
+.Ft void
+.Fn atomic_add_[acq_|rel_]<type> "volatile <type> *p" "<type> v"
+.Ft void
+.Fn atomic_clear_[acq_|rel_]<type> "volatile <type> *p" "<type> v"
+.Ft int
+.Fo atomic_cmpset_[acq_|rel_]<type>
+.Fa "volatile <type> *dst"
+.Fa "<type> old"
+.Fa "<type> new"
+.Fc
+.Ft <type>
+.Fn atomic_fetchadd_<type> "volatile <type> *p" "<type> v"
+.Ft <type>
+.Fn atomic_load_acq_<type> "volatile <type> *p"
+.Ft <type>
+.Fn atomic_readandclear_<type> "volatile <type> *p"
+.Ft void
+.Fn atomic_set_[acq_|rel_]<type> "volatile <type> *p" "<type> v"
+.Ft void
+.Fn atomic_subtract_[acq_|rel_]<type> "volatile <type> *p" "<type> v"
+.Ft void
+.Fn atomic_store_rel_<type> "volatile <type> *p" "<type> v"
+.rm LB RB La Ra
+.Sh DESCRIPTION
+Each of the atomic operations is guaranteed to be atomic in the presence of
+interrupts.
+They can be used to implement reference counts or as building blocks for more
+advanced synchronization primitives such as mutexes.
+.Ss Types
+Each atomic operation operates on a specific
+.Fa type .
+The type to use is indicated in the function name.
+The available types that can be used are:
+.Pp
+.Bl -tag -offset indent -width short -compact
+.It Li int
+unsigned integer
+.It Li long
+unsigned long integer
+.It Li ptr
+unsigned integer the size of a pointer
+.It Li 32
+unsigned 32-bit integer
+.It Li 64
+unsigned 64-bit integer
+.El
+.Pp
+For example, the function to atomically add two integers is called
+.Fn atomic_add_int .
+.Pp
+Certain architectures also provide operations for types smaller than
+.Dq Li int .
+.Pp
+.Bl -tag -offset indent -width short -compact
+.It Li char
+unsigned character
+.It Li short
+unsigned short integer
+.It Li 8
+unsigned 8-bit integer
+.It Li 16
+unsigned 16-bit integer
+.El
+.Pp
+These must not be used in MI code because the instructions to implement them
+efficiently may not be available.
+.Ss Memory Barriers
+Memory barriers are used to guarantee the order of data accesses in
+two ways.
+First, they specify hints to the compiler to not re-order or optimize the
+operations.
+Second, on architectures that do not guarantee ordered data accesses,
+special instructions or special variants of instructions are used to indicate
+to the processor that data accesses need to occur in a certain order.
+As a result, most of the atomic operations have three variants in order to
+include optional memory barriers.
+The first form just performs the operation without any explicit barriers.
+The second form uses a read memory barrier, and the third variant uses a write
+memory barrier.
+.Pp
+The second variant of each operation includes a read memory barrier.
+This barrier ensures that the effects of this operation are completed before the
+effects of any later data accesses.
+As a result, the operation is said to have acquire semantics as it acquires a
+pseudo-lock requiring further operations to wait until it has completed.
+To denote this, the suffix
+.Dq Li _acq
+is inserted into the function name immediately prior to the
+.Dq Li _ Ns Aq Fa type
+suffix.
+For example, to subtract two integers ensuring that any later writes will
+happen after the subtraction is performed, use
+.Fn atomic_subtract_acq_int .
+.Pp
+The third variant of each operation includes a write memory barrier.
+This ensures that all effects of all previous data accesses are completed
+before this operation takes place.
+As a result, the operation is said to have release semantics as it releases
+any pending data accesses to be completed before its operation is performed.
+To denote this, the suffix
+.Dq Li _rel
+is inserted into the function name immediately prior to the
+.Dq Li _ Ns Aq Fa type
+suffix.
+For example, to add two long integers ensuring that all previous
+writes will happen first, use
+.Fn atomic_add_rel_long .
+.Pp
+A practical example of using memory barriers is to ensure that data accesses
+that are protected by a lock are all performed while the lock is held.
+To achieve this, one would use a read barrier when acquiring the lock to
+guarantee that the lock is held before any protected operations are performed.
+Finally, one would use a write barrier when releasing the lock to ensure that
+all of the protected operations are completed before the lock is released.
+.Ss Multiple Processors
+The current set of atomic operations do not necessarily guarantee atomicity
+across multiple processors.
+To guarantee atomicity across processors, not only does the individual
+operation need to be atomic on the processor performing the operation, but
+the result of the operation needs to be pushed out to stable storage and the
+caches of all other processors on the system need to invalidate any cache
+lines that include the affected memory region.
+On the
+.Tn i386
+architecture, the cache coherency model requires that the hardware perform
+this task, thus the atomic operations are atomic across multiple processors.
+On the
+.Tn ia64
+architecture, coherency is only guaranteed for pages that are configured to
+using a caching policy of either uncached or write back.
+.Ss Semantics
+This section describes the semantics of each operation using a C like notation.
+.Bl -hang
+.It Fn atomic_add p v
+.Bd -literal -compact
+*p += v;
+.Ed
+.It Fn atomic_clear p v
+.Bd -literal -compact
+*p &= ~v;
+.Ed
+.It Fn atomic_cmpset dst old new
+.Bd -literal -compact
+if (*dst == old) {
+ *dst = new;
+ return 1;
+} else
+ return 0;
+.Ed
+.El
+.Pp
+The
+.Fn atomic_cmpset
+functions are not implemented for the types
+.Dq Li char ,
+.Dq Li short ,
+.Dq Li 8 ,
+and
+.Dq Li 16 .
+.Bl -hang
+.It Fn atomic_fetchadd p v
+.Bd -literal -compact
+tmp = *p;
+*p += v;
+return tmp;
+.Ed
+.El
+.Pp
+The
+.Fn atomic_fetchadd
+functions are only implemented for the types
+.Dq Li int ,
+.Dq Li long
+and
+.Dq Li 32
+and do not have any variants with memory barriers at this time.
+.Bl -hang
+.It Fn atomic_load addr
+.Bd -literal -compact
+return (*addr)
+.Ed
+.El
+.Pp
+The
+.Fn atomic_load
+functions are only provided with acquire memory barriers.
+.Bl -hang
+.It Fn atomic_readandclear addr
+.Bd -literal -compact
+temp = *addr;
+*addr = 0;
+return (temp);
+.Ed
+.El
+.Pp
+The
+.Fn atomic_readandclear
+functions are not implemented for the types
+.Dq Li char ,
+.Dq Li short ,
+.Dq Li ptr ,
+.Dq Li 8 ,
+and
+.Dq Li 16
+and do
+not have any variants with memory barriers at this time.
+.Bl -hang
+.It Fn atomic_set p v
+.Bd -literal -compact
+*p |= v;
+.Ed
+.It Fn atomic_subtract p v
+.Bd -literal -compact
+*p -= v;
+.Ed
+.It Fn atomic_store p v
+.Bd -literal -compact
+*p = v;
+.Ed
+.El
+.Pp
+The
+.Fn atomic_store
+functions are only provided with release memory barriers.
+.Pp
+The type
+.Dq Li 64
+is currently not implemented for any of the atomic operations on the
+.Tn arm ,
+.Tn i386 ,
+and
+.Tn powerpc
+architectures.
+.Sh RETURN VALUES
+The
+.Fn atomic_cmpset
+function
+returns the result of the compare operation.
+The
+.Fn atomic_fetchadd ,
+.Fn atomic_load ,
+and
+.Fn atomic_readandclear
+functions
+return the value at the specified address.
+.Sh EXAMPLES
+This example uses the
+.Fn atomic_cmpset_acq_ptr
+and
+.Fn atomic_set_ptr
+functions to obtain a sleep mutex and handle recursion.
+Since the
+.Va mtx_lock
+member of a
+.Vt "struct mtx"
+is a pointer, the
+.Dq Li ptr
+type is used.
+.Bd -literal
+/* Try to obtain mtx_lock once. */
+#define _obtain_lock(mp, tid) \\
+ atomic_cmpset_acq_ptr(&(mp)->mtx_lock, MTX_UNOWNED, (tid))
+
+/* Get a sleep lock, deal with recursion inline. */
+#define _get_sleep_lock(mp, tid, opts, file, line) do { \\
+ uintptr_t _tid = (uintptr_t)(tid); \\
+ \\
+ if (!_obtain_lock(mp, tid)) { \\
+ if (((mp)->mtx_lock & MTX_FLAGMASK) != _tid) \\
+ _mtx_lock_sleep((mp), _tid, (opts), (file), (line));\\
+ else { \\
+ atomic_set_ptr(&(mp)->mtx_lock, MTX_RECURSE); \\
+ (mp)->mtx_recurse++; \\
+ } \\
+ } \\
+} while (0)
+.Ed
+.Sh HISTORY
+The
+.Fn atomic_add ,
+.Fn atomic_clear ,
+.Fn atomic_set ,
+and
+.Fn atomic_subtract
+operations were first introduced in
+.Fx 3.0 .
+This first set only supported the types
+.Dq Li char ,
+.Dq Li short ,
+.Dq Li int ,
+and
+.Dq Li long .
+The
+.Fn atomic_cmpset ,
+.Fn atomic_load ,
+.Fn atomic_readandclear ,
+and
+.Fn atomic_store
+operations were added in
+.Fx 5.0 .
+The types
+.Dq Li 8 ,
+.Dq Li 16 ,
+.Dq Li 32 ,
+.Dq Li 64 ,
+and
+.Dq Li ptr
+and all of the acquire and release variants
+were added in
+.Fx 5.0
+as well.
+The
+.Fn atomic_fetchadd
+operations were added in
+.Fx 6.0 .