diff options
| author | David Faulkner <[email protected]> | 2026-08-07 23:40:47 -0500 |
|---|---|---|
| committer | David Faulkner <[email protected]> | 2026-08-07 23:40:47 -0500 |
| commit | b3e9e62599532050fc776c5e8f076915b56c2235 (patch) | |
| tree | af252346106a61b18cc6fc6fdbd32e962d096f1c /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.c | 162 |
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; +} |
