summaryrefslogtreecommitdiff
path: root/devdocs/c/atomic%2Fatomic_fetch_add.html
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2024-04-07 13:41:34 -0500
committerCraig Jennings <c@cjennings.net>2024-04-07 13:41:34 -0500
commit754bbf7a25a8dda49b5d08ef0d0443bbf5af0e36 (patch)
treef1190704f78f04a2b0b4c977d20fe96a828377f1 /devdocs/c/atomic%2Fatomic_fetch_add.html
new repository
Diffstat (limited to 'devdocs/c/atomic%2Fatomic_fetch_add.html')
-rw-r--r--devdocs/c/atomic%2Fatomic_fetch_add.html53
1 files changed, 53 insertions, 0 deletions
diff --git a/devdocs/c/atomic%2Fatomic_fetch_add.html b/devdocs/c/atomic%2Fatomic_fetch_add.html
new file mode 100644
index 00000000..8bfa2a40
--- /dev/null
+++ b/devdocs/c/atomic%2Fatomic_fetch_add.html
@@ -0,0 +1,53 @@
+ <h1 id="firstHeading" class="firstHeading">atomic_fetch_add, atomic_fetch_add_explicit</h1> <table class="t-dcl-begin"> <tr class="t-dsc-header"> <th> Defined in header <code>&lt;stdatomic.h&gt;</code> </th> <th> </th> <th> </th> </tr> <tr class="t-dcl t-since-c11"> <td> <pre data-language="c">C atomic_fetch_add( volatile A* obj, M arg );</pre>
+</td> <td> (1) </td> <td> <span class="t-mark-rev t-since-c11">(since C11)</span> </td> </tr> <tr class="t-dcl t-since-c11"> <td> <pre data-language="c">C atomic_fetch_add_explicit( volatile A* obj, M arg, memory_order order );</pre>
+</td> <td> (2) </td> <td> <span class="t-mark-rev t-since-c11">(since C11)</span> </td> </tr> </table> <p>Atomically replaces the value pointed by <code>obj</code> with the result of addition of <code>arg</code> to the old value of <code>obj</code>, and returns the value <code>obj</code> held previously. The operation is read-modify-write operation. The first version orders memory accesses according to <code><a href="memory_order" title="c/atomic/memory order">memory_order_seq_cst</a></code>, the second version orders memory accesses according to <code>order</code>.</p>
+<p>This is a <a href="../language/generic" title="c/language/generic">generic function</a> defined for all <a href="../language/atomic" title="c/language/atomic">atomic object types</a> <code>A</code>. The argument is pointer to a volatile atomic type to accept addresses of both non-volatile and <a href="../language/volatile" title="c/language/volatile">volatile</a> (e.g. memory-mapped I/O) atomic objects, and volatile semantic is preserved when applying this operation to volatile atomic objects. <code>M</code> is either the non-atomic type corresponding to <code>A</code> if <code>A</code> is atomic integer type, or <code><a href="../types/ptrdiff_t" title="c/types/ptrdiff t">ptrdiff_t</a></code> if <code>A</code> is atomic pointer type.</p>
+<p>It is unspecified whether the name of a generic function is a macro or an identifier declared with external linkage. If a macro definition is suppressed in order to access an actual function (e.g. parenthesized like <code>(atomic_fetch_add)(...)</code>), or a program defines an external identifier with the name of a generic function, the behavior is undefined.</p>
+<p>For signed integer types, arithmetic is defined to use two’s complement representation. There are no undefined results. For pointer types, the result may be an undefined address, but the operations otherwise have no undefined behavior.</p>
+<h3 id="Parameters"> Parameters</h3> <table class="t-par-begin"> <tr class="t-par"> <td> obj </td> <td> - </td> <td> pointer to the atomic object to modify </td>
+</tr> <tr class="t-par"> <td> arg </td> <td> - </td> <td> the value to add to the value stored in the atomic object </td>
+</tr> <tr class="t-par"> <td> order </td> <td> - </td> <td> the memory synchronization ordering for this operation: all values are permitted </td>
+</tr>
+</table> <h3 id="Return_value"> Return value</h3> <p>The value held previously by the atomic object pointed to by <code>obj</code>.</p>
+<h3 id="Example"> Example</h3> <div class="t-example"> <div class="c source-c"><pre data-language="c">#include &lt;stdio.h&gt;
+#include &lt;threads.h&gt;
+#include &lt;stdatomic.h&gt;
+
+atomic_int acnt;
+int cnt;
+
+int f(void* thr_data)
+{
+ for(int n = 0; n &lt; 1000; ++n) {
+ atomic_fetch_add_explicit(&amp;acnt, 1, memory_order_relaxed); // atomic
+ ++cnt; // undefined behavior, in practice some updates missed
+ }
+ return 0;
+}
+
+int main(void)
+{
+ thrd_t thr[10];
+ for(int n = 0; n &lt; 10; ++n)
+ thrd_create(&amp;thr[n], f, NULL);
+ for(int n = 0; n &lt; 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 9511</pre></div> </div> <h3 id="References"> References</h3> <ul>
+<li> C17 standard (ISO/IEC 9899:2018): </li>
+<ul><li> 7.17.7.5 The atomic_fetch and modify generic functions (p: 208) </li></ul>
+<li> C11 standard (ISO/IEC 9899:2011): </li>
+<ul><li> 7.17.7.5 The atomic_fetch and modify generic functions (p: 284-285) </li></ul>
+</ul> <h3 id="See_also"> See also</h3> <table class="t-dsc-begin"> <tr class="t-dsc"> <td> <div><a href="atomic_fetch_sub" title="c/atomic/atomic fetch sub"> <span class="t-lines"><span>atomic_fetch_sub</span><span>atomic_fetch_sub_explicit</span></span></a></div>
+<div><span class="t-lines"><span><span class="t-mark-rev t-since-c11">(C11)</span></span></span></div> </td> <td> atomic subtraction <br> <span class="t-mark">(function)</span> </td>
+</tr> <tr class="t-dsc"> <td colspan="2"> <span><a href="https://en.cppreference.com/w/cpp/atomic/atomic_fetch_add" title="cpp/atomic/atomic fetch add">C++ documentation</a></span> for <code>atomic_fetch_add, atomic_fetch_add_explicit</code> </td>
+</tr> </table> <div class="_attribution">
+ <p class="_attribution-p">
+ &copy; cppreference.com<br>Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.<br>
+ <a href="https://en.cppreference.com/w/c/atomic/atomic_fetch_add" class="_attribution-link">https://en.cppreference.com/w/c/atomic/atomic_fetch_add</a>
+ </p>
+</div>