diff --git a/include/stdatomic.h b/include/stdatomic.h index 2d423d1a..58b75173 100644 --- a/include/stdatomic.h +++ b/include/stdatomic.h @@ -94,6 +94,8 @@ typedef struct { #define atomic_init(object, desired) \ atomic_store_explicit(object, desired, __ATOMIC_RELAXED) +#define __atomic_store_n(ptr, val, order) \ + (*(ptr) = (val), __atomic_store((ptr), &(typeof(*(ptr))){val}, (order))) #define atomic_store_explicit(object, desired, order) \ ({ __typeof__ (object) ptr = (object); \ __typeof__ (*ptr) tmp = (desired); \ @@ -102,6 +104,10 @@ typedef struct { #define atomic_store(object, desired) \ atomic_store_explicit (object, desired, __ATOMIC_SEQ_CST) +#define __atomic_load_n(ptr, order) \ + ({ typeof(*(ptr)) __val; \ + __atomic_load((ptr), &__val, (order)); \ + __val; }) #define atomic_load_explicit(object, order) \ ({ __typeof__ (object) ptr = (object); \ __typeof__ (*ptr) tmp; \ @@ -119,7 +125,10 @@ typedef struct { }) #define atomic_exchange(object, desired) \ atomic_exchange_explicit (object, desired, __ATOMIC_SEQ_CST) - +#define __atomic_compare_exchange_n(ptr, expected, desired, weak, success, failure) \ + ({ typeof(*(ptr)) __desired = (desired); \ + __atomic_compare_exchange((ptr), (expected), &__desired, \ + (weak), (success), (failure)); }) #define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \ ({ __typeof__ (object) ptr = (object); \ __typeof__ (*ptr) tmp = desired; \ @@ -128,7 +137,6 @@ typedef struct { #define atomic_compare_exchange_strong(object, expected, desired) \ atomic_compare_exchange_strong_explicit (object, expected, desired, \ __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) - #define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \ ({ __typeof__ (object) ptr = (object); \ __typeof__ (*ptr) tmp = desired; \ diff --git a/tests/tests2/136_atomic_gcc_style.c b/tests/tests2/136_atomic_gcc_style.c new file mode 100644 index 00000000..520146b7 --- /dev/null +++ b/tests/tests2/136_atomic_gcc_style.c @@ -0,0 +1,75 @@ +#include +#include +#include +#include + +int main() { + // Test 1: Basic functionality of __atomic_store_n and __atomic_load_n + { + int atomic_var = 0; + __atomic_store_n(&atomic_var, 42, __ATOMIC_SEQ_CST); + int loaded = __atomic_load_n(&atomic_var, __ATOMIC_SEQ_CST); + assert(loaded == 42); + } + + // Test 2: Successful exchange with __atomic_compare_exchange_n + { + int atomic_var = 100; + int expected = 100; + bool success = __atomic_compare_exchange_n( + &atomic_var, &expected, 200, + false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST + ); + assert(success); + assert(atomic_var == 200); + assert(expected == 100); // expected remains unchanged on success + } + + // Test 3: Failed exchange with __atomic_compare_exchange_n (update expected) + { + int atomic_var = 100; + int expected = 99; + bool success = __atomic_compare_exchange_n( + &atomic_var, &expected, 200, + false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST + ); + assert(!success); + assert(atomic_var == 100); + assert(expected == 100); // expected updated to current value on failure + } + + // Test 4: Weak version (spurious failure handling) + { + int atomic_var = 50; + int expected = 50; + for (int i = 0; i < 10; i++) { + if (__atomic_compare_exchange_n( + &atomic_var, &expected, 60, + true, __ATOMIC_RELAXED, __ATOMIC_RELAXED + )) { + break; + } + } + assert(atomic_var == 60); + } + + // Test 5: Pointer type operations + { + int value = 100; + int* atomic_ptr = &value; + int* new_ptr = NULL; + __atomic_store_n(&atomic_ptr, new_ptr, __ATOMIC_RELEASE); + int* loaded_ptr = __atomic_load_n(&atomic_ptr, __ATOMIC_ACQUIRE); + assert(loaded_ptr == NULL); + } + + // Test 6: Relaxed memory ordering + { + int atomic_var = 0; + __atomic_store_n(&atomic_var, 10, __ATOMIC_RELAXED); + assert(__atomic_load_n(&atomic_var, __ATOMIC_RELAXED) == 10); + } + + printf("All atomic tests passed!\n"); + return 0; +} diff --git a/tests/tests2/136_atomic_gcc_style.expect b/tests/tests2/136_atomic_gcc_style.expect new file mode 100644 index 00000000..0c7cc001 --- /dev/null +++ b/tests/tests2/136_atomic_gcc_style.expect @@ -0,0 +1 @@ +All atomic tests passed!