From e23dabed154a8495f3ac1ff3cc9d04fa1c207893 Mon Sep 17 00:00:00 2001 From: owenewans Date: Fri, 16 Oct 2026 02:33:12 +0000 Subject: [PATCH] stdatomic: fix store argument evaluation and signal fence macros - remove the non-atomic write and repeated argument evaluation from __atomic_store_n - remove the recursive atomic_signal_fence macro - add tests for stores and signal fences tested with make test on linux x86_64 --- include/stdatomic.h | 4 +-- tests/tests2/151_atomic_header.c | 45 +++++++++++++++++++++++++++ tests/tests2/151_atomic_header.expect | 5 +++ 3 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 tests/tests2/151_atomic_header.c create mode 100644 tests/tests2/151_atomic_header.expect diff --git a/include/stdatomic.h b/include/stdatomic.h index 85932a51..b460171d 100644 --- a/include/stdatomic.h +++ b/include/stdatomic.h @@ -85,7 +85,8 @@ typedef struct { atomic_store_explicit(object, desired, __ATOMIC_RELAXED) #define __atomic_store_n(ptr, val, order) \ - (*(ptr) = (val), __atomic_store((ptr), &(typeof(*(ptr))){val}, (order))) + ({ __typeof__ ((void)0, *(ptr)) __val = (val); \ + __atomic_store((ptr), &__val, (order)); }) #define atomic_store_explicit(object, desired, order) \ ({ __typeof__ (object) ptr = (object); \ __typeof__ (*ptr) tmp = (desired); \ @@ -160,7 +161,6 @@ extern void atomic_thread_fence (memory_order); #define __atomic_thread_fence(order) atomic_thread_fence (order) extern void atomic_signal_fence (memory_order); #define __atomic_signal_fence(order) atomic_signal_fence(order) -#define atomic_signal_fence(order) __atomic_signal_fence (order) extern bool __atomic_is_lock_free(size_t size, void *ptr); #define atomic_is_lock_free(OBJ) __atomic_is_lock_free (sizeof (*(OBJ)), (OBJ)) diff --git a/tests/tests2/151_atomic_header.c b/tests/tests2/151_atomic_header.c new file mode 100644 index 00000000..91e947fc --- /dev/null +++ b/tests/tests2/151_atomic_header.c @@ -0,0 +1,45 @@ +#include +#include + +static int value_calls; +static int order_calls; + +static int next_value(void) +{ + ++value_calls; + return 42; +} + +static int next_order(void) +{ + ++order_calls; + return __ATOMIC_SEQ_CST; +} + +int main(void) +{ + int values[2] = {7, 8}; + int index = 0; + int value = 1; + volatile int vol = 0; + int *pointer = &value; + void (*signal_fence)(memory_order) = &atomic_signal_fence; + + __atomic_store_n(&values[index++], next_value(), next_order()); + printf("%d %d %d %d %d\n", index, value_calls, order_calls, + values[0], values[1]); + __atomic_store_n(&value, value + 1, __ATOMIC_RELAXED); + printf("%d\n", value); + __atomic_store_n(&vol, 13, __ATOMIC_RELEASE); + printf("%d\n", __atomic_load_n(&vol, __ATOMIC_ACQUIRE)); + __atomic_store_n(&pointer, &values[0], __ATOMIC_RELEASE); + printf("%d\n", *__atomic_load_n(&pointer, __ATOMIC_ACQUIRE)); + + atomic_signal_fence(memory_order_acquire); + __atomic_signal_fence(__ATOMIC_RELEASE); + signal_fence(memory_order_seq_cst); + atomic_thread_fence(memory_order_seq_cst); + __atomic_thread_fence(__ATOMIC_SEQ_CST); + puts("ok"); + return 0; +} diff --git a/tests/tests2/151_atomic_header.expect b/tests/tests2/151_atomic_header.expect new file mode 100644 index 00000000..2af7585f --- /dev/null +++ b/tests/tests2/151_atomic_header.expect @@ -0,0 +1,5 @@ +1 1 1 42 8 +2 +13 +42 +ok