summaryrefslogtreecommitdiff
path: root/static/freebsd/man9/atomic.9 3.html
diff options
context:
space:
mode:
Diffstat (limited to 'static/freebsd/man9/atomic.9 3.html')
-rw-r--r--static/freebsd/man9/atomic.9 3.html613
1 files changed, 0 insertions, 613 deletions
diff --git a/static/freebsd/man9/atomic.9 3.html b/static/freebsd/man9/atomic.9 3.html
deleted file mode 100644
index fc10c6fe..00000000
--- a/static/freebsd/man9/atomic.9 3.html
+++ /dev/null
@@ -1,613 +0,0 @@
-<table class="head">
- <tr>
- <td class="head-ltitle">ATOMIC(9)</td>
- <td class="head-vol">Kernel Developer's Manual</td>
- <td class="head-rtitle">ATOMIC(9)</td>
- </tr>
-</table>
-<div class="manual-text">
-<section class="Sh">
-<h1 class="Sh" id="NAME"><a class="permalink" href="#NAME">NAME</a></h1>
-<p class="Pp"><code class="Nm">atomic_add</code>,
- <code class="Nm">atomic_clear</code>, <code class="Nm">atomic_cmpset</code>,
- <code class="Nm">atomic_fcmpset</code>,
- <code class="Nm">atomic_fetchadd</code>,
- <code class="Nm">atomic_interrupt_fence</code>,
- <code class="Nm">atomic_load</code>,
- <code class="Nm">atomic_readandclear</code>,
- <code class="Nm">atomic_set</code>, <code class="Nm">atomic_subtract</code>,
- <code class="Nm">atomic_store</code>,
- <code class="Nm">atomic_thread_fence</code> &#x2014; <span class="Nd">atomic
- operations</span></p>
-</section>
-<section class="Sh">
-<h1 class="Sh" id="SYNOPSIS"><a class="permalink" href="#SYNOPSIS">SYNOPSIS</a></h1>
-<p class="Pp"><code class="In">#include
- &lt;<a class="In">machine/atomic.h</a>&gt;</code></p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">atomic_add_[acq_|rel_]&lt;type&gt;</code>(<var class="Fa" style="white-space: nowrap;">volatile
- &lt;type&gt; *p</var>,
- <var class="Fa" style="white-space: nowrap;">&lt;type&gt; v</var>);</p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">atomic_clear_[acq_|rel_]&lt;type&gt;</code>(<var class="Fa" style="white-space: nowrap;">volatile
- &lt;type&gt; *p</var>,
- <var class="Fa" style="white-space: nowrap;">&lt;type&gt; v</var>);</p>
-<p class="Pp"><var class="Ft">int</var>
- <br/>
- <code class="Fn">atomic_cmpset_[acq_|rel_]&lt;type&gt;</code>(<var class="Fa">volatile
- &lt;type&gt; *dst</var>, <var class="Fa">&lt;type&gt; old</var>,
- <var class="Fa">&lt;type&gt; new</var>);</p>
-<p class="Pp"><var class="Ft">int</var>
- <br/>
- <code class="Fn">atomic_fcmpset_[acq_|rel_]&lt;type&gt;</code>(<var class="Fa">volatile
- &lt;type&gt; *dst</var>, <var class="Fa">&lt;type&gt; *old</var>,
- <var class="Fa">&lt;type&gt; new</var>);</p>
-<p class="Pp"><var class="Ft">&lt;type&gt;</var>
- <br/>
- <code class="Fn">atomic_fetchadd_&lt;type&gt;</code>(<var class="Fa" style="white-space: nowrap;">volatile
- &lt;type&gt; *p</var>,
- <var class="Fa" style="white-space: nowrap;">&lt;type&gt; v</var>);</p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">atomic_interrupt_fence</code>(<var class="Fa" style="white-space: nowrap;">void</var>);</p>
-<p class="Pp"><var class="Ft">&lt;type&gt;</var>
- <br/>
- <code class="Fn">atomic_load_[acq_]&lt;type&gt;</code>(<var class="Fa" style="white-space: nowrap;">const
- volatile &lt;type&gt; *p</var>);</p>
-<p class="Pp"><var class="Ft">&lt;type&gt;</var>
- <br/>
- <code class="Fn">atomic_readandclear_&lt;type&gt;</code>(<var class="Fa" style="white-space: nowrap;">volatile
- &lt;type&gt; *p</var>);</p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">atomic_set_[acq_|rel_]&lt;type&gt;</code>(<var class="Fa" style="white-space: nowrap;">volatile
- &lt;type&gt; *p</var>,
- <var class="Fa" style="white-space: nowrap;">&lt;type&gt; v</var>);</p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">atomic_subtract_[acq_|rel_]&lt;type&gt;</code>(<var class="Fa" style="white-space: nowrap;">volatile
- &lt;type&gt; *p</var>,
- <var class="Fa" style="white-space: nowrap;">&lt;type&gt; v</var>);</p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">atomic_store_[rel_]&lt;type&gt;</code>(<var class="Fa" style="white-space: nowrap;">volatile
- &lt;type&gt; *p</var>,
- <var class="Fa" style="white-space: nowrap;">&lt;type&gt; v</var>);</p>
-<p class="Pp"><var class="Ft">&lt;type&gt;</var>
- <br/>
- <code class="Fn">atomic_swap_&lt;type&gt;</code>(<var class="Fa" style="white-space: nowrap;">volatile
- &lt;type&gt; *p</var>,
- <var class="Fa" style="white-space: nowrap;">&lt;type&gt; v</var>);</p>
-<p class="Pp"><var class="Ft">int</var>
- <br/>
- <code class="Fn">atomic_testandclear_&lt;type&gt;</code>(<var class="Fa" style="white-space: nowrap;">volatile
- &lt;type&gt; *p</var>, <var class="Fa" style="white-space: nowrap;">u_int
- v</var>);</p>
-<p class="Pp"><var class="Ft">int</var>
- <br/>
- <code class="Fn">atomic_testandset_&lt;type&gt;</code>(<var class="Fa" style="white-space: nowrap;">volatile
- &lt;type&gt; *p</var>, <var class="Fa" style="white-space: nowrap;">u_int
- v</var>);</p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">atomic_thread_fence_[acq|acq_rel|rel|seq_cst]</code>(<var class="Fa" style="white-space: nowrap;">void</var>);</p>
-</section>
-<section class="Sh">
-<h1 class="Sh" id="DESCRIPTION"><a class="permalink" href="#DESCRIPTION">DESCRIPTION</a></h1>
-<p class="Pp">Atomic operations are commonly used to implement reference counts
- and as building blocks for synchronization primitives, such as mutexes.</p>
-<p class="Pp" id="atomically">All of these operations are performed
- <a class="permalink" href="#atomically"><i class="Em">atomically</i></a>
- across multiple threads and in the presence of interrupts, meaning that they
- are performed in an indivisible manner from the perspective of concurrently
- running threads and interrupt handlers.</p>
-<p class="Pp">On all architectures supported by <span class="Ux">FreeBSD</span>,
- ordinary loads and stores of integers in cache-coherent memory are
- inherently atomic if the integer is naturally aligned and its size does not
- exceed the processor's word size. However, such loads and stores may be
- elided from the program by the compiler, whereas atomic operations are
- always performed.</p>
-<p class="Pp">When atomic operations are performed on cache-coherent memory, all
- operations on the same location are totally ordered.</p>
-<p class="Pp" id="torn">When an atomic load is performed on a location in
- cache-coherent memory, it reads the entire value that was defined by the
- last atomic store to each byte of the location. An atomic load will never
- return a value out of thin air. When an atomic store is performed on a
- location, no other thread or interrupt handler will observe a
- <a class="permalink" href="#torn"><i class="Em">torn write</i></a>, or
- partial modification of the location.</p>
-<p class="Pp">Except as noted below, the semantics of these operations are
- almost identical to the semantics of similarly named C11 atomic
- operations.</p>
-<section class="Ss">
-<h2 class="Ss" id="Types"><a class="permalink" href="#Types">Types</a></h2>
-<p class="Pp">Most atomic operations act upon a specific
- <var class="Fa">type</var>. That type is indicated in the function name. In
- contrast to C11 atomic operations, <span class="Ux">FreeBSD</span>'s atomic
- operations are performed on ordinary integer types. The available types
- are:</p>
-<p class="Pp"></p>
-<div class="Bd-indent">
-<dl class="Bl-tag Bl-compact">
- <dt id="int"><a class="permalink" href="#int"><code class="Li">int</code></a></dt>
- <dd>unsigned integer</dd>
- <dt id="long"><a class="permalink" href="#long"><code class="Li">long</code></a></dt>
- <dd>unsigned long integer</dd>
- <dt id="ptr"><a class="permalink" href="#ptr"><code class="Li">ptr</code></a></dt>
- <dd>unsigned integer the size of a pointer</dd>
- <dt id="32"><a class="permalink" href="#32"><code class="Li">32</code></a></dt>
- <dd>unsigned 32-bit integer</dd>
- <dt id="64"><a class="permalink" href="#64"><code class="Li">64</code></a></dt>
- <dd>unsigned 64-bit integer</dd>
-</dl>
-</div>
-<p class="Pp" id="atomic_add_int">For example, the function to atomically add
- two integers is called
- <a class="permalink" href="#atomic_add_int"><code class="Fn">atomic_add_int</code></a>().</p>
-<p class="Pp">Certain architectures also provide operations for types smaller
- than &#x201C;<code class="Li">int</code>&#x201D;.</p>
-<p class="Pp"></p>
-<div class="Bd-indent">
-<dl class="Bl-tag Bl-compact">
- <dt id="char"><a class="permalink" href="#char"><code class="Li">char</code></a></dt>
- <dd>unsigned character</dd>
- <dt id="short"><a class="permalink" href="#short"><code class="Li">short</code></a></dt>
- <dd>unsigned short integer</dd>
- <dt id="8"><a class="permalink" href="#8"><code class="Li">8</code></a></dt>
- <dd>unsigned 8-bit integer</dd>
- <dt id="16"><a class="permalink" href="#16"><code class="Li">16</code></a></dt>
- <dd>unsigned 16-bit integer</dd>
-</dl>
-</div>
-<p class="Pp">These types must not be used in machine-independent code.</p>
-</section>
-<section class="Ss">
-<h2 class="Ss" id="Acquire_and_Release_Operations"><a class="permalink" href="#Acquire_and_Release_Operations">Acquire
- and Release Operations</a></h2>
-<p class="Pp">By default, a thread's accesses to different memory locations
- might not be performed in
- <a class="permalink" href="#program"><i class="Em" id="program">program
- order</i></a>, that is, the order in which the accesses appear in the source
- code. To optimize the program's execution, both the compiler and processor
- might reorder the thread's accesses. However, both ensure that their
- reordering of the accesses is not visible to the thread. Otherwise, the
- traditional memory model that is expected by single-threaded programs would
- be violated. Nonetheless, other threads in a multithreaded program, such as
- the <span class="Ux">FreeBSD</span> kernel, might observe the reordering.
- Moreover, in some cases, such as the implementation of synchronization
- between threads, arbitrary reordering might result in the incorrect
- execution of the program. To constrain the reordering that both the compiler
- and processor might perform on a thread's accesses, a programmer can use
- atomic operations with <i class="Em">acquire</i> and
- <i class="Em">release</i> semantics.</p>
-<p class="Pp" id="relaxed">Atomic operations on memory have up to three
- variants. The first, or
- <a class="permalink" href="#relaxed"><i class="Em">relaxed</i></a> variant,
- performs the operation without imposing any ordering constraints on accesses
- to other memory locations. This variant is the default. The second variant
- has acquire semantics, and the third variant has release semantics.</p>
-<p class="Pp" id="atomic_subtract_acq_int">An atomic operation can only have
- <i class="Em">acquire</i> semantics if it performs a load from memory. When
- an atomic operation has acquire semantics, a load performed as part of the
- operation must have completed before any subsequent load or store (by
- program order) is performed. Conversely, acquire semantics do not require
- that prior loads or stores have completed before a load from the atomic
- operation is performed. To denote acquire semantics, the suffix
- &#x201C;<code class="Li">_acq</code>&#x201D; is inserted into the function
- name immediately prior to the
- &#x201C;<code class="Li">_</code>&#x27E8;<var class="Fa">type</var>&#x27E9;&#x201D;
- suffix. For example, to subtract two integers ensuring that the load of the
- value from memory is completed before any subsequent loads and stores are
- performed, use
- <a class="permalink" href="#atomic_subtract_acq_int"><code class="Fn">atomic_subtract_acq_int</code></a>().</p>
-<p class="Pp" id="atomic_add_rel_long">An atomic operation can only have
- <i class="Em">release</i> semantics if it performs a store to memory. When
- an atomic operation has release semantics, all prior loads or stores (by
- program order) must have completed before a store executed as part of the
- operation that is performed. Conversely, release semantics do not require
- that a store from the atomic operation must have completed before any
- subsequent load or store is performed. To denote release semantics, the
- suffix &#x201C;<code class="Li">_rel</code>&#x201D; is inserted into the
- function name immediately prior to the
- &#x201C;<code class="Li">_</code>&#x27E8;<var class="Fa">type</var>&#x27E9;&#x201D;
- suffix. For example, to add two long integers ensuring that all prior loads
- and stores are completed before the store of the result is performed, use
- <a class="permalink" href="#atomic_add_rel_long"><code class="Fn">atomic_add_rel_long</code></a>().</p>
-<p class="Pp" id="synchronizes">When a release operation by one thread
- <a class="permalink" href="#synchronizes"><i class="Em">synchronizes
- with</i></a> an acquire operation by another thread, usually meaning that
- the acquire operation reads the value written by the release operation, then
- the effects of all prior stores by the releasing thread must become visible
- to subsequent loads by the acquiring thread. Moreover, the effects of all
- stores (by other threads) that were visible to the releasing thread must
- also become visible to the acquiring thread. These rules only apply to the
- synchronizing threads. Other threads might observe these stores in a
- different order.</p>
-<p class="Pp">In effect, atomic operations with acquire and release semantics
- establish one-way barriers to reordering that enable the implementations of
- synchronization primitives to express their ordering requirements without
- also imposing unnecessary ordering. For example, for a critical section
- guarded by a mutex, an acquire operation when the mutex is locked and a
- release operation when the mutex is unlocked will prevent any loads or
- stores from moving outside of the critical section. However, they will not
- prevent the compiler or processor from moving loads or stores into the
- critical section, which does not violate the semantics of a mutex.</p>
-</section>
-<section class="Ss">
-<h2 class="Ss" id="Architecture-dependent_caveats_for_compare-and-swap"><a class="permalink" href="#Architecture-dependent_caveats_for_compare-and-swap">Architecture-dependent
- caveats for compare-and-swap</a></h2>
-<p class="Pp">The
- <a class="permalink" href="#atomic__f_cmpset__type_"><code class="Fn" id="atomic__f_cmpset__type_">atomic_[f]cmpset_&lt;type&gt;</code></a>()
- operations, specifically those without explicitly specified memory ordering,
- are defined as relaxed. Consequently, a thread's accesses to memory
- locations different from that of the atomic operation can be reordered in
- relation to the atomic operation.</p>
-<p class="Pp" id="amd64">However, the implementation on the
- <a class="permalink" href="#amd64"><b class="Sy">amd64</b></a> and
- <a class="permalink" href="#i386"><b class="Sy" id="i386">i386</b></a>
- architectures provide sequentially consistent semantics. In particular, the
- reordering mentioned above cannot occur.</p>
-<p class="Pp" id="arm64/aarch64">On the
- <a class="permalink" href="#arm64/aarch64"><b class="Sy">arm64/aarch64</b></a>
- architecture, the operation may include either acquire semantics on the
- constituent load or release semantics on the constituent store. This means
- that accesses to other locations in program order before the atomic, might
- be observed as executed after the load that is the part of the atomic
- operation (but not after the store from the operation due to release).
- Similarly, accesses after the atomic might be observed as executed before
- the store.</p>
-</section>
-<section class="Ss">
-<h2 class="Ss" id="Thread_Fence_Operations"><a class="permalink" href="#Thread_Fence_Operations">Thread
- Fence Operations</a></h2>
-<p class="Pp">Alternatively, a programmer can use atomic thread fence operations
- to constrain the reordering of accesses. In contrast to other atomic
- operations, fences do not, themselves, access memory.</p>
-<p class="Pp" id="atomic_thread_fence_acq">When a fence has acquire semantics,
- all prior loads (by program order) must have completed before any subsequent
- load or store is performed. Thus, an acquire fence is a two-way barrier for
- load operations. To denote acquire semantics, the suffix
- &#x201C;<code class="Li">_acq</code>&#x201D; is appended to the function
- name, for example,
- <a class="permalink" href="#atomic_thread_fence_acq"><code class="Fn">atomic_thread_fence_acq</code></a>().</p>
-<p class="Pp" id="atomic_thread_fence_rel">When a fence has release semantics,
- all prior loads or stores (by program order) must have completed before any
- subsequent store operation is performed. Thus, a release fence is a two-way
- barrier for store operations. To denote release semantics, the suffix
- &#x201C;<code class="Li">_rel</code>&#x201D; is appended to the function
- name, for example,
- <a class="permalink" href="#atomic_thread_fence_rel"><code class="Fn">atomic_thread_fence_rel</code></a>().</p>
-<p class="Pp" id="atomic_thread_fence_acq_rel">Although
- <a class="permalink" href="#atomic_thread_fence_acq_rel"><code class="Fn">atomic_thread_fence_acq_rel</code></a>()
- implements both acquire and release semantics, it is not a full barrier. For
- example, a store prior to the fence (in program order) may be completed
- after a load subsequent to the fence. In contrast,
- <a class="permalink" href="#atomic_thread_fence_seq_cst"><code class="Fn" id="atomic_thread_fence_seq_cst">atomic_thread_fence_seq_cst</code></a>()
- implements a full barrier. Neither loads nor stores may cross this barrier
- in either direction.</p>
-<p class="Pp">In C11, a release fence by one thread synchronizes with an acquire
- fence by another thread when an atomic load that is prior to the acquire
- fence (by program order) reads the value written by an atomic store that is
- subsequent to the release fence. In contrast, in
- <span class="Ux">FreeBSD</span>, because of the atomicity of ordinary,
- naturally aligned loads and stores, fences can also be synchronized by
- ordinary loads and stores. This simplifies the implementation and use of
- some synchronization primitives in <span class="Ux">FreeBSD</span>.</p>
-<p class="Pp">Since neither a compiler nor a processor can foresee which
- (atomic) load will read the value written by an (atomic) store, the ordering
- constraints imposed by fences must be more restrictive than acquire loads
- and release stores. Essentially, this is why fences are two-way
- barriers.</p>
-<p class="Pp">Although fences impose more restrictive ordering than acquire
- loads and release stores, by separating access from ordering, they can
- sometimes facilitate more efficient implementations of synchronization
- primitives. For example, they can be used to avoid executing a memory
- barrier until a memory access shows that some condition is satisfied.</p>
-</section>
-<section class="Ss">
-<h2 class="Ss" id="Interrupt_Fence_Operations"><a class="permalink" href="#Interrupt_Fence_Operations">Interrupt
- Fence Operations</a></h2>
-<p class="Pp">The
- <a class="permalink" href="#atomic_interrupt_fence"><code class="Fn" id="atomic_interrupt_fence">atomic_interrupt_fence</code></a>()
- function establishes ordering between its call location and any interrupt
- handler executing on the same CPU. It is modeled after the similar C11
- function
- <a class="permalink" href="#atomic_signal_fence"><code class="Fn" id="atomic_signal_fence">atomic_signal_fence</code></a>(),
- and adapted for the kernel environment.</p>
-</section>
-<section class="Ss">
-<h2 class="Ss" id="Multiple_Processors"><a class="permalink" href="#Multiple_Processors">Multiple
- Processors</a></h2>
-<p class="Pp">In multiprocessor systems, the atomicity of the atomic operations
- on memory depends on support for cache coherence in the underlying
- architecture. In general, cache coherence on the default memory type,
- <code class="Dv">VM_MEMATTR_DEFAULT</code>, is guaranteed by all
- architectures that are supported by <span class="Ux">FreeBSD</span>. For
- example, cache coherence is guaranteed on write-back memory by the amd64 and
- i386 architectures. However, on some architectures, cache coherence might
- not be enabled on all memory types. To determine if cache coherence is
- enabled for a non-default memory type, consult the architecture's
- documentation.</p>
-</section>
-<section class="Ss">
-<h2 class="Ss" id="Semantics"><a class="permalink" href="#Semantics">Semantics</a></h2>
-<p class="Pp">This section describes the semantics of each operation using a C
- like notation.</p>
-<dl class="Bl-hang">
- <dt id="atomic_add"><a class="permalink" href="#atomic_add"><code class="Fn">atomic_add</code></a>(<var class="Fa">p</var>,
- <var class="Fa">v</var>)</dt>
- <dd>
- <div class="Bd Li">
- <pre>*p += v;</pre>
- </div>
- </dd>
- <dt id="atomic_clear"><a class="permalink" href="#atomic_clear"><code class="Fn">atomic_clear</code></a>(<var class="Fa">p</var>,
- <var class="Fa">v</var>)</dt>
- <dd>
- <div class="Bd Li">
- <pre>*p &amp;= ~v;</pre>
- </div>
- </dd>
- <dt><code class="Fn">atomic_cmpset</code>(<var class="Fa">dst</var>,
- <var class="Fa">old</var>, <var class="Fa">new</var>)</dt>
- <dd>
- <div class="Bd Li">
- <pre>if (*dst == old) {
- *dst = new;
- return (1);
-} else
- return (0);</pre>
- </div>
- </dd>
-</dl>
-<p class="Pp" id="atomic_cmpset">Some architectures do not implement the
- <a class="permalink" href="#atomic_cmpset"><code class="Fn">atomic_cmpset</code></a>()
- functions for the types &#x201C;<code class="Li">char</code>&#x201D;,
- &#x201C;<code class="Li">short</code>&#x201D;,
- &#x201C;<code class="Li">8</code>&#x201D;, and
- &#x201C;<code class="Li">16</code>&#x201D;.</p>
-<dl class="Bl-hang">
- <dt><code class="Fn">atomic_fcmpset</code>(<var class="Fa">dst</var>,
- <var class="Fa">*old</var>, <var class="Fa">new</var>)</dt>
- <dd></dd>
-</dl>
-<p class="Pp" id="Compare">On architectures implementing
- <a class="permalink" href="#Compare"><i class="Em">Compare And Swap</i></a>
- operation in hardware, the functionality can be described as</p>
-<div class="Bd Bd-indent Li">
-<pre>if (*dst == *old) {
- *dst = new;
- return (1);
-} else {
- *old = *dst;
- return (0);
-}</pre>
-</div>
-On architectures which provide
- <a class="permalink" href="#Load"><i class="Em" id="Load">Load Linked/Store
- Conditional</i></a> primitive, the write to <code class="Dv">*dst</code> might
- also fail for several reasons, most important of which is a parallel write to
- <code class="Dv">*dst</code> cache line by other CPU. In this case
- <a class="permalink" href="#atomic_fcmpset"><code class="Fn" id="atomic_fcmpset">atomic_fcmpset</code></a>()
- function also returns <code class="Dv">false</code>, despite
-<div class="Bd Bd-indent"><code class="Li">*old == *dst</code></div>
-.
-<p class="Pp" id="atomic_fcmpset~2">Some architectures do not implement the
- <a class="permalink" href="#atomic_fcmpset~2"><code class="Fn">atomic_fcmpset</code></a>()
- functions for the types &#x201C;<code class="Li">char</code>&#x201D;,
- &#x201C;<code class="Li">short</code>&#x201D;,
- &#x201C;<code class="Li">8</code>&#x201D;, and
- &#x201C;<code class="Li">16</code>&#x201D;.</p>
-<dl class="Bl-hang">
- <dt><code class="Fn">atomic_fetchadd</code>(<var class="Fa">p</var>,
- <var class="Fa">v</var>)</dt>
- <dd>
- <div class="Bd Li">
- <pre>tmp = *p;
-*p += v;
-return (tmp);</pre>
- </div>
- </dd>
-</dl>
-<p class="Pp" id="atomic_fetchadd">The
- <a class="permalink" href="#atomic_fetchadd"><code class="Fn">atomic_fetchadd</code></a>()
- functions are only implemented for the types
- &#x201C;<code class="Li">int</code>&#x201D;,
- &#x201C;<code class="Li">long</code>&#x201D; and
- &#x201C;<code class="Li">32</code>&#x201D; and do not have any variants with
- memory barriers at this time.</p>
-<dl class="Bl-hang">
- <dt id="atomic_load"><a class="permalink" href="#atomic_load"><code class="Fn">atomic_load</code></a>(<var class="Fa">p</var>)</dt>
- <dd>
- <div class="Bd Li">
- <pre>return (*p);</pre>
- </div>
- </dd>
- <dt><code class="Fn">atomic_readandclear</code>(<var class="Fa">p</var>)</dt>
- <dd>
- <div class="Bd Li">
- <pre>tmp = *p;
-*p = 0;
-return (tmp);</pre>
- </div>
- </dd>
-</dl>
-<p class="Pp" id="atomic_readandclear">The
- <a class="permalink" href="#atomic_readandclear"><code class="Fn">atomic_readandclear</code></a>()
- functions are not implemented for the types
- &#x201C;<code class="Li">char</code>&#x201D;,
- &#x201C;<code class="Li">short</code>&#x201D;,
- &#x201C;<code class="Li">ptr</code>&#x201D;,
- &#x201C;<code class="Li">8</code>&#x201D;, and
- &#x201C;<code class="Li">16</code>&#x201D; and do not have any variants with
- memory barriers at this time.</p>
-<dl class="Bl-hang">
- <dt id="atomic_set"><a class="permalink" href="#atomic_set"><code class="Fn">atomic_set</code></a>(<var class="Fa">p</var>,
- <var class="Fa">v</var>)</dt>
- <dd>
- <div class="Bd Li">
- <pre>*p |= v;</pre>
- </div>
- </dd>
- <dt id="atomic_subtract"><a class="permalink" href="#atomic_subtract"><code class="Fn">atomic_subtract</code></a>(<var class="Fa">p</var>,
- <var class="Fa">v</var>)</dt>
- <dd>
- <div class="Bd Li">
- <pre>*p -= v;</pre>
- </div>
- </dd>
- <dt id="atomic_store"><a class="permalink" href="#atomic_store"><code class="Fn">atomic_store</code></a>(<var class="Fa">p</var>,
- <var class="Fa">v</var>)</dt>
- <dd>
- <div class="Bd Li">
- <pre>*p = v;</pre>
- </div>
- </dd>
- <dt><code class="Fn">atomic_swap</code>(<var class="Fa">p</var>,
- <var class="Fa">v</var>)</dt>
- <dd>
- <div class="Bd Li">
- <pre>tmp = *p;
-*p = v;
-return (tmp);</pre>
- </div>
- </dd>
-</dl>
-<p class="Pp" id="atomic_swap">The
- <a class="permalink" href="#atomic_swap"><code class="Fn">atomic_swap</code></a>()
- functions are not implemented for the types
- &#x201C;<code class="Li">char</code>&#x201D;,
- &#x201C;<code class="Li">short</code>&#x201D;,
- &#x201C;<code class="Li">ptr</code>&#x201D;,
- &#x201C;<code class="Li">8</code>&#x201D;, and
- &#x201C;<code class="Li">16</code>&#x201D; and do not have any variants with
- memory barriers at this time.</p>
-<dl class="Bl-hang">
- <dt id="atomic_testandclear"><a class="permalink" href="#atomic_testandclear"><code class="Fn">atomic_testandclear</code></a>(<var class="Fa">p</var>,
- <var class="Fa">v</var>)</dt>
- <dd>
- <div class="Bd Li">
- <pre>bit = 1 &lt;&lt; (v % (sizeof(*p) * NBBY));
-tmp = (*p &amp; bit) != 0;
-*p &amp;= ~bit;
-return (tmp);</pre>
- </div>
- </dd>
-</dl>
-<dl class="Bl-hang">
- <dt><code class="Fn">atomic_testandset</code>(<var class="Fa">p</var>,
- <var class="Fa">v</var>)</dt>
- <dd>
- <div class="Bd Li">
- <pre>bit = 1 &lt;&lt; (v % (sizeof(*p) * NBBY));
-tmp = (*p &amp; bit) != 0;
-*p |= bit;
-return (tmp);</pre>
- </div>
- </dd>
-</dl>
-<p class="Pp" id="atomic_testandset">The
- <a class="permalink" href="#atomic_testandset"><code class="Fn">atomic_testandset</code></a>()
- and
- <a class="permalink" href="#atomic_testandclear~2"><code class="Fn" id="atomic_testandclear~2">atomic_testandclear</code></a>()
- functions are only implemented for the types
- &#x201C;<code class="Li">int</code>&#x201D;,
- &#x201C;<code class="Li">long</code>&#x201D;, &#x201C;ptr&#x201D;,
- &#x201C;<code class="Li">32</code>&#x201D;, and
- &#x201C;<code class="Li">64</code>&#x201D; and generally do not have any
- variants with memory barriers at this time except for
- <a class="permalink" href="#atomic_testandset_acq_long"><code class="Fn" id="atomic_testandset_acq_long">atomic_testandset_acq_long</code></a>().</p>
-<p class="Pp">The type &#x201C;<code class="Li">64</code>&#x201D; is currently
- not implemented for some of the atomic operations on the arm, i386, and
- powerpc architectures.</p>
-</section>
-</section>
-<section class="Sh">
-<h1 class="Sh" id="RETURN_VALUES"><a class="permalink" href="#RETURN_VALUES">RETURN
- VALUES</a></h1>
-<p class="Pp">The <code class="Fn">atomic_cmpset</code>() function returns the
- result of the compare operation. The
- <code class="Fn">atomic_fcmpset</code>() function returns
- <code class="Dv">true</code> if the operation succeeded. Otherwise it
- returns <code class="Dv">false</code> and sets <var class="Va">*old</var> to
- the found value. The <code class="Fn">atomic_fetchadd</code>(),
- <code class="Fn">atomic_load</code>(),
- <code class="Fn">atomic_readandclear</code>(), and
- <code class="Fn">atomic_swap</code>() functions return the value at the
- specified address. The <code class="Fn">atomic_testandset</code>() and
- <code class="Fn">atomic_testandclear</code>() function returns the result of
- the test operation.</p>
-</section>
-<section class="Sh">
-<h1 class="Sh" id="EXAMPLES"><a class="permalink" href="#EXAMPLES">EXAMPLES</a></h1>
-<p class="Pp">This example uses the
- <code class="Fn">atomic_cmpset_acq_ptr</code>() and
- <code class="Fn">atomic_set_ptr</code>() functions to obtain a sleep mutex
- and handle recursion. Since the <var class="Va">mtx_lock</var> member of a
- <var class="Vt">struct mtx</var> is a pointer, the
- &#x201C;<code class="Li">ptr</code>&#x201D; type is used.</p>
-<div class="Bd Pp Li">
-<pre>/* Try to obtain mtx_lock once. */
-#define _obtain_lock(mp, tid) \
- atomic_cmpset_acq_ptr(&amp;(mp)-&gt;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)-&gt;mtx_lock &amp; MTX_FLAGMASK) != _tid) \
- _mtx_lock_sleep((mp), _tid, (opts), (file), (line));\
- else { \
- atomic_set_ptr(&amp;(mp)-&gt;mtx_lock, MTX_RECURSE); \
- (mp)-&gt;mtx_recurse++; \
- } \
- } \
-} while (0)</pre>
-</div>
-</section>
-<section class="Sh">
-<h1 class="Sh" id="HISTORY"><a class="permalink" href="#HISTORY">HISTORY</a></h1>
-<p class="Pp">The <code class="Fn">atomic_add</code>(),
- <code class="Fn">atomic_clear</code>(),
- <code class="Fn">atomic_set</code>(), and
- <code class="Fn">atomic_subtract</code>() operations were introduced in
- <span class="Ux">FreeBSD 3.0</span>. Initially, these operations were
- defined on the types &#x201C;<code class="Li">char</code>&#x201D;,
- &#x201C;<code class="Li">short</code>&#x201D;,
- &#x201C;<code class="Li">int</code>&#x201D;, and
- &#x201C;<code class="Li">long</code>&#x201D;.</p>
-<p class="Pp">The <code class="Fn">atomic_cmpset</code>(),
- <code class="Fn">atomic_load_acq</code>(),
- <code class="Fn">atomic_readandclear</code>(), and
- <code class="Fn">atomic_store_rel</code>() operations were added in
- <span class="Ux">FreeBSD 5.0</span>. Simultaneously, the acquire and release
- variants were introduced, and support was added for operation on the types
- &#x201C;<code class="Li">8</code>&#x201D;,
- &#x201C;<code class="Li">16</code>&#x201D;,
- &#x201C;<code class="Li">32</code>&#x201D;,
- &#x201C;<code class="Li">64</code>&#x201D;, and
- &#x201C;<code class="Li">ptr</code>&#x201D;.</p>
-<p class="Pp">The <code class="Fn">atomic_fetchadd</code>() operation was added
- in <span class="Ux">FreeBSD 6.0</span>.</p>
-<p class="Pp">The <code class="Fn">atomic_swap</code>() and
- <code class="Fn">atomic_testandset</code>() operations were added in
- <span class="Ux">FreeBSD 10.0</span>.</p>
-<p class="Pp">The <code class="Fn">atomic_testandclear</code>() and
- <code class="Fn">atomic_thread_fence</code>() operations were added in
- <span class="Ux">FreeBSD 11.0</span>.</p>
-<p class="Pp">The relaxed variants of <code class="Fn">atomic_load</code>() and
- <code class="Fn">atomic_store</code>() were added in
- <span class="Ux">FreeBSD 12.0</span>.</p>
-<p class="Pp">The <code class="Fn">atomic_interrupt_fence</code>() operation was
- added in <span class="Ux">FreeBSD 13.0</span>.</p>
-</section>
-</div>
-<table class="foot">
- <tr>
- <td class="foot-date">December 16, 2024</td>
- <td class="foot-os">FreeBSD 15.0</td>
- </tr>
-</table>