1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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>
|