diff options
| author | Craig Jennings <c@cjennings.net> | 2024-04-07 13:41:34 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2024-04-07 13:41:34 -0500 |
| commit | 754bbf7a25a8dda49b5d08ef0d0443bbf5af0e36 (patch) | |
| tree | f1190704f78f04a2b0b4c977d20fe96a828377f1 /devdocs/c/language%2Fatomic.html | |
new repository
Diffstat (limited to 'devdocs/c/language%2Fatomic.html')
| -rw-r--r-- | devdocs/c/language%2Fatomic.html | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/devdocs/c/language%2Fatomic.html b/devdocs/c/language%2Fatomic.html new file mode 100644 index 00000000..5b8daa7a --- /dev/null +++ b/devdocs/c/language%2Fatomic.html @@ -0,0 +1,77 @@ + <h1 id="firstHeading" class="firstHeading">Atomic types</h1> <h3 id="Syntax"> Syntax</h3> <table class="t-sdsc-begin"> <tr class="t-sdsc"> <td> <code>_Atomic</code> <code>(</code> <span class="t-spar">type-name</span> <code>)</code> </td> <td> (1) </td> <td> <span class="t-mark-rev t-since-c11">(since C11)</span> </td> +</tr> <tr class="t-sdsc"> <td> <code>_Atomic</code> <span class="t-spar">type-name</span> </td> <td> (2) </td> <td> <span class="t-mark-rev t-since-c11">(since C11)</span> </td> +</tr> +</table> <div class="t-li1"> +<span class="t-li">1)</span> Use as a type specifier; this designates a new atomic type</div> <div class="t-li1"> +<span class="t-li">2)</span> Use as a type qualifier; this designates the atomic version of <span class="t-spar">type-name</span>. In this role, it may be mixed with <a href="const" title="c/language/const">const</a>, <a href="volatile" title="c/language/volatile">volatile</a>, and <a href="restrict" title="c/language/restrict">restrict</a>, although unlike other qualifiers, the atomic version of <span class="t-spar">type-name</span> may have a different size, alignment, and object representation.</div> <table class="t-par-begin"> <tr class="t-par"> <td> <span class="t-spar">type-name</span> </td> <td> - </td> <td> any type other than array or function. For <span class="t-v">(1)</span>, <span class="t-spar">type-name</span> also cannot be atomic or cvr-qualified </td> +</tr> +</table> <p>The header <code><stdatomic.h></code> defines <a href="../thread#Atomic_operations" title="c/thread">37 convenience type aliases</a>, from <a href="../thread#Atomic_operations" title="c/thread"><code>atomic_bool</code></a> to <a href="../thread#Atomic_operations" title="c/thread"><code>atomic_uintmax_t</code></a>, which simplify the use of this keyword with built-in and library types.</p> +<div class="c source-c"><pre data-language="c">_Atomic const int * p1; // p is a pointer to an atomic const int +const atomic_int * p2; // same +const _Atomic(int) * p3; // same</pre></div> <p>If the macro constant <code>__STDC_NO_ATOMICS__</code> is defined by the compiler, the keyword <code>_Atomic</code> is not provided.</p> +<h3 id="Explanation"> Explanation</h3> <p>Objects of atomic types are the only objects that are free from <a href="memory_model" title="c/language/memory model">data races</a>; that is, they may be modified by two threads concurrently or modified by one and read by another.</p> +<p>Each atomic object has its own associated <i>modification order</i>, which is a total order of modifications made to that object. If, from some thread's point of view, modification <code>A</code> of some atomic M <a href="../atomic/memory_order" title="c/atomic/memory order">happens-before</a> modification <code>B</code> of the same atomic M, then in the modification order of M, A occurs before B.</p> +<p>Note that although each atomic object has its own modification order, there is no single total order; different threads may observe modifications to different atomic objects in different orders.</p> +<p>There are four coherences that are guaranteed for all atomic operations:</p> +<ul> +<li> <b>write-write coherence</b>: If an operation A that modifies an atomic object M <i>happens-before</i> an operation B that modifies M, then A appears earlier than B in the modification order of M. </li> +<li> <b>read-read coherence</b>: If a value computation A of an atomic object M happens before a value computation B of M, and A takes its value from a side effect X on M, then the value computed by B is either the value stored by X or is the value stored by a side effect Y on M, where Y appears later than X in the modification order of M. </li> +<li> <b>read-write coherence</b>: If a value computation A of an atomic object M <i>happens-before</i> an operation B on M, then A takes its value from a side effect X on M, where X appears before B in the modification order of M. </li> +<li> <b>write-read coherence</b>: If a side effect X on an atomic object M <i>happens-before</i> a value computation B of M, then the evaluation B takes its value from X or from a side effect Y that appears after X in the modification order of M. </li> +</ul> <p>Some atomic operations are also synchronization operations; they may have additional release semantics, acquire semantics, or sequentially-consistent semantics. See <code><a href="../atomic/memory_order" title="c/atomic/memory order">memory_order</a></code>.</p> +<p>Built-in <a href="operator_incdec" title="c/language/operator incdec">increment and decrement operators</a> and <a href="operator_assignment" title="c/language/operator assignment">compound assignment</a> are read-modify-write atomic operations with total sequentially consistent ordering (as if using <code><a href="../atomic/memory_order" title="c/atomic/memory order">memory_order_seq_cst</a></code>). If less strict synchronization semantics are desired, the <a href="../thread#Atomic_operations" title="c/thread">standard library functions</a> may be used instead.</p> +<p>Atomic properties are only meaningful for <a href="value_category" title="c/language/value category">lvalue expressions</a>. Lvalue-to-rvalue conversion (which models a memory read from an atomic location to a CPU register) strips atomicity along with other qualifiers.</p> +<h3 id="Notes"> Notes</h3> <p>Accessing a member of an atomic struct/union is undefined behavior.</p> +<p>The library type <code><a href="http://en.cppreference.com/w/c/program/sig_atomic_t"><span class="kw499">sig_atomic_t</span></a></code> does not provide inter-thread synchronization or memory ordering, only atomicity.</p> +<p>The <a href="volatile" title="c/language/volatile">volatile</a> types do not provide inter-thread synchronization, memory ordering, or atomicity.</p> +<p>Implementations are recommended to ensure that the representation of <code>_Atomic(T)</code> in C is same as that of <code>std::atomic<T></code> in C++ for every possible type <code>T</code>. The mechanisms used to ensure atomicity and memory ordering should be compatible.</p> +<h3 id="Keywords"> Keywords</h3> <p><a href="../keyword/_atomic" title="c/keyword/ Atomic"><code>_Atomic</code></a></p> +<h3 id="Example"> Example</h3> <div class="t-example"> <div class="c source-c"><pre data-language="c">#include <stdio.h> +#include <threads.h> +#include <stdatomic.h> + +atomic_int acnt; +int cnt; + +int f(void* thr_data) +{ + for(int n = 0; n < 1000; ++n) { + ++cnt; + ++acnt; + // for this example, relaxed memory order is sufficient, e.g. + // atomic_fetch_add_explicit(&acnt, 1, memory_order_relaxed); + } + return 0; +} + +int main(void) +{ + thrd_t thr[10]; + for(int n = 0; n < 10; ++n) + thrd_create(&thr[n], f, NULL); + for(int n = 0; n < 10; ++n) + thrd_join(thr[n], NULL); + + printf("The atomic counter is %u\n", acnt); + printf("The non-atomic counter is %u\n", cnt); +}</pre></div> <p>Possible output:</p> +<div class="text source-text"><pre data-language="c">The atomic counter is 10000 +The non-atomic counter is 8644</pre></div> </div> <h3 id="References"> References</h3> <ul> +<li> C17 standard (ISO/IEC 9899:2018): </li> +<ul> +<li> 6.7.2.4 Atomic type specifiers (p: 87) </li> +<li> 7.17 Atomics <stdatomic.h> (p: 200-209) </li> +</ul> +<li> C11 standard (ISO/IEC 9899:2011): </li> +<ul> +<li> 6.7.2.4 Atomic type specifiers (p: 121) </li> +<li> 7.17 Atomics <stdatomic.h> (p: 273-286) </li> +</ul> +</ul> <h3 id="See_also"> See also</h3> <table class="t-dsc-begin"> <tr class="t-dsc"> <td colspan="2"> <span><a href="../thread" title="c/thread">C documentation</a></span> for <code>thread (Concurrency support library)</code> </td> +</tr> <tr class="t-dsc"> <td colspan="2"> <span><a href="https://en.cppreference.com/w/cpp/atomic/atomic" title="cpp/atomic/atomic">C++ documentation</a></span> for <code>atomic</code> </td> +</tr> </table> <div class="_attribution"> + <p class="_attribution-p"> + © cppreference.com<br>Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.<br> + <a href="https://en.cppreference.com/w/c/language/atomic" class="_attribution-link">https://en.cppreference.com/w/c/language/atomic</a> + </p> +</div> |
