← Back to davo.co
summaryrefslogtreecommitdiffstats
path: root/volatile_atomic.c
diff options
context:
space:
mode:
authorDavid Faulkner <[email protected]>2026-08-07 23:40:47 -0500
committerDavid Faulkner <[email protected]>2026-08-07 23:40:47 -0500
commitb3e9e62599532050fc776c5e8f076915b56c2235 (patch)
treeaf252346106a61b18cc6fc6fdbd32e962d096f1c /volatile_atomic.c
Import official C23 code examples for Modern C (Jens Gustedt, 2024)HEADupstream-importmain
- Add official C source files, Makefile, c23-fallback.h, and LICENSE - Update README.md with study mirror notice
Diffstat (limited to 'volatile_atomic.c')
-rw-r--r--volatile_atomic.c162
1 files changed, 162 insertions, 0 deletions
diff --git a/volatile_atomic.c b/volatile_atomic.c
new file mode 100644
index 0000000..ecff3c5
--- /dev/null
+++ b/volatile_atomic.c
@@ -0,0 +1,162 @@
+#include <stdatomic.h>
+
+/**
+ ** @brief A simple accumulation in a loop
+ **
+ ** Any decent optimizer should be able to figure out that the return
+ ** value is @c 100 and that the only side effect is to store the
+ ** value @c 10 into @c *count.
+ **/
+unsigned accu(unsigned*restrict count) {
+ unsigned ret = 0;
+ unsigned tmp = 0;
+ (*count) = 0;
+ while (tmp < 9) {
+ tmp = (*count)++;
+ ret += 2*tmp +1;
+ }
+ return ret;
+}
+
+/**
+ ** @brief @c volatile qualification
+ **
+ ** @c volatile forces all stores to be effected. So this has side
+ ** effects of storing @f$0, \ldots, 10@f$ into @c *count.
+ **/
+unsigned accuv(unsigned volatile*restrict count) {
+ unsigned ret = 0;
+ unsigned tmp = 0;
+ (*count) = 0;
+ while (tmp < 9) {
+ tmp = (*count)++;
+ ret += 2*tmp +1;
+ }
+ return ret;
+}
+
+/**
+ ** @brief @c _Atomic specification
+ **
+ ** Here, because it is not @c volatile, none of the side effects
+ ** would have to be made visible before returning. Only there is an
+ ** ambiguous phrase in the C standard:
+ **
+ ** <quote>
+ ** Atomic read-modify-write operations shall always read the last
+ ** value (in the modification order) stored before the write
+ ** associated with the read-modify-write operation.
+ ** </quote>
+ **
+ ** This can be read that for read-modify-write operations the read
+ ** and write operations *must* be effected.
+ **/
+unsigned accua(_Atomic(unsigned)*restrict count) {
+ unsigned ret = 0;
+ unsigned tmp = 0;
+ (*count) = 0;
+ while (tmp < 9) {
+ tmp = (*count)++;
+ ret += 2*tmp +1;
+ }
+ return ret;
+}
+
+unsigned accuav(_Atomic(unsigned) volatile*restrict count) {
+ unsigned ret = 0;
+ unsigned tmp = 0;
+ (*count) = 0;
+ while (tmp < 9) {
+ tmp = (*count)++;
+ ret += 2*tmp +1;
+ }
+ return ret;
+}
+
+unsigned accuar(_Atomic(unsigned)*restrict count) {
+ unsigned ret = 0;
+ unsigned tmp = 0;
+ atomic_store_explicit(count, 0, memory_order_relaxed);
+ while (tmp < 9) {
+ tmp = atomic_fetch_add_explicit(count, 1u, memory_order_relaxed);
+ ret += 2*tmp +1;
+ }
+ return ret;
+}
+
+unsigned accuavr(_Atomic(unsigned) volatile*restrict count) {
+ unsigned ret = 0;
+ unsigned tmp = 0;
+ atomic_store_explicit(count, 0, memory_order_relaxed);
+ while (tmp < 9) {
+ tmp = atomic_fetch_add_explicit(count, 1u, memory_order_relaxed);
+ ret += 2*tmp +1;
+ }
+ return ret;
+}
+
+unsigned accut(unsigned*restrict count) {
+ unsigned ret = 0;
+ unsigned tmp = 0;
+ (*count) = 0;
+ while (tmp < 10) {
+ ret += 2*tmp +1;
+ (*count) = ++tmp;
+ }
+ return ret;
+}
+
+unsigned accutv(unsigned volatile*restrict count) {
+ unsigned ret = 0;
+ unsigned tmp = 0;
+ (*count) = 0;
+ while (tmp < 10) {
+ ret += 2*tmp +1;
+ (*count) = ++tmp;
+ }
+ return ret;
+}
+
+unsigned accuta(_Atomic(unsigned)*restrict count) {
+ unsigned ret = 0;
+ unsigned tmp = 0;
+ (*count) = 0;
+ while (tmp < 10) {
+ ret += 2*tmp +1;
+ (*count) = ++tmp;
+ }
+ return ret;
+}
+
+unsigned accutav(_Atomic(unsigned) volatile*restrict count) {
+ unsigned ret = 0;
+ unsigned tmp = 0;
+ (*count) = 0;
+ while (tmp < 10) {
+ ret += 2*tmp +1;
+ (*count) = ++tmp;
+ }
+ return ret;
+}
+
+unsigned accutar(_Atomic(unsigned)*restrict count) {
+ unsigned ret = 0;
+ unsigned tmp = 0;
+ atomic_store_explicit(count, 0, memory_order_relaxed);
+ while (tmp < 10) {
+ ret += 2*tmp +1;
+ atomic_store_explicit(count, ++tmp, memory_order_relaxed);
+ }
+ return ret;
+}
+
+unsigned accutavr(_Atomic(unsigned) volatile*restrict count) {
+ unsigned ret = 0;
+ unsigned tmp = 0;
+ atomic_store_explicit(count, 0, memory_order_relaxed);
+ while (tmp < 10) {
+ ret += 2*tmp +1;
+ atomic_store_explicit(count, ++tmp, memory_order_relaxed);
+ }
+ return ret;
+}