Last active
June 22, 2023 13:52
-
-
Save mu578/b7bd9ebd2131c02d73d25f1a6f927751 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// C11 Clang Atomic support | |
# if defined(__clang__) | |
# if __has_feature(c_atomic) | |
# define HAVE_CLANG_ATOMICS 1 | |
# endif | |
# endif | |
# if defined(__GNUC__) && !defined(HAVE_CLANG_ATOMICS) | |
# if __GNUC_PREREQ__(4, 7) | |
# define HAVE_GNUC_ATOMICS 1 | |
# endif | |
# endif | |
// Possible _Atomic keyword | |
// # define _Atomic(T) struct { volatile T value; } | |
# if defined(HAVE_GNUC_ATOMICS) | |
# define _Atomic(T) struct { volatile T value; } | |
# define __c11_atomic_store(obj, desired, order) __atomic_store_n(&(obj)->value, desired, order) | |
# define __c11_atomic_load(obj, order) __atomic_load_n(&(obj)->value, order) | |
# define __c11_atomic_exchange(obj, desired, order) __atomic_exchange_n(&(obj)->value, desired, order) | |
# define __c11_atomic_compare_exchange_strong(obj, expected, desired, success, fail) __atomic_compare_exchange_n(&(obj)->value, expected, desired, 0, success, fail) | |
# define __c11_atomic_compare_exchange_weak(obj, expected, desired, success, fail) __atomic_compare_exchange_n(&(obj)->value, expected, desired, 1, success, fail) | |
# define __c11_atomic_fetch_add(obj, value, order) __atomic_fetch_add(&(obj)->value, value, order) | |
# define __c11_atomic_fetch_sub(obj, value, order) __atomic_fetch_sub(&(obj)->value, value, order) | |
# define __c11_atomic_fetch_or(obj, value, order) __atomic_fetch_or(&(obj)->value, value, order) | |
# define __c11_atomic_fetch_xor(obj, value, order) __atomic_fetch_xor(&(obj)->value, value, order) | |
# define __c11_atomic_fetch_and(obj, value, order) __atomic_fetch_and(&(obj)->value, value, order) | |
# define __c11_atomic_init(obj, desired) do { (obj)->value = (desired); } while (0) | |
# define HAVE_CLANG_ATOMICS 1 | |
# elif defined(__GNUC__) && !defined(HAVE_CLANG_ATOMICS) | |
# define _Atomic(T) struct { volatile T value; } | |
# define __c11_atomic_store(obj, desired, order) do { __sync_synchronize(); (obj)->value = (desired); __sync_synchronize(); } while (0) | |
# define __c11_atomic_load(obj, order) __sync_fetch_and_add(&(obj)->value, 0) | |
# if defined(__clang__) | |
# if __has_builtin(__sync_swap) | |
# define __c11_atomic_exchange(obj, desired, order) __sync_swap(&(obj)->value, desired) | |
# endif | |
# endif | |
# if !defined(__c11_atomic_exchange) | |
# define __c11_atomic_exchange(obj, desired, order) __extension__ ({ __typeof__((obj)->value) v; v = __sync_lock_test_and_set(&(obj)->value, desired); __sync_synchronize(); v; }) | |
# endif | |
# define __c11_atomic_compare_exchange_strong(obj, expected, desired, success, fail) __extension__ ({ _Bool r; v = __sync_val_compare_and_swap(&(obj)->value, *(expected), desired); r = *(expected) == v; *(expected) = v; r; }) | |
# define __c11_atomic_compare_exchange_weak(obj, expected, desired, success, fail) __extension__ ({ _Bool r; v = __sync_val_compare_and_swap(&(obj)->value, *(expected), desired); r = *(expected) == v; *(expected) = v; r; }) | |
# define __c11_atomic_fetch_add(obj, value, order) __sync_fetch_and_add(&(obj)->value, value) | |
# define __c11_atomic_fetch_sub(obj, value, order) __sync_fetch_and_sub(&(obj)->value, value) | |
# define __c11_atomic_fetch_or(obj, value, order) __sync_fetch_and_or(&(obj)->value, value) | |
# define __c11_atomic_fetch_xor(obj, value, order) __sync_fetch_and_xor(&(obj)->value, value) | |
# define __c11_atomic_init(obj, desired) do { (obj)->value = (desired); } while (0) | |
# define HAVE_CLANG_ATOMICS 1 | |
# endif | |
# if defined(HAVE_CLANG_ATOMICS) | |
// void atomic_store (volatile A * obj, C desired); | |
// void atomic_store_explicit (volatile A * obj, C desired, memory_order order); | |
# define atomic_store(obj, desired) __c11_atomic_store(obj, desired, __ATOMIC_SEQ_CST) | |
# define atomic_store_explicit(obj, desired, order) __c11_atomic_store(obj, desired, order) | |
// C atomic_load (const volatile A * obj); | |
// C atomic_load_explicit (const volatile A * obj, memory_order order); | |
# define atomic_load(obj) __c11_atomic_load(obj, __ATOMIC_SEQ_CST) | |
# define atomic_load_explicit(obj, order) __c11_atomic_load(obj, order) | |
// C atomic_exchange (volatile A * obj, C desired); | |
// C atomic_exchange_explicit (volatile A * obj, C desired, memory_order order); | |
# define atomic_exchange(obj, desired) __c11_atomic_exchange(obj, desired, __ATOMIC_SEQ_CST) | |
# define atomic_exchange_explicit(obj, desired, order) __c11_atomic_exchange(obj, desired, order) | |
// _Bool atomic_compare_exchange_strong (volatile A * obj, C * expected, C desired); | |
// _Bool atomic_compare_exchange_strong_explicit (volatile A * obj, C * expected, C desired, memory_order success, memory_order fail); | |
# define atomic_compare_exchange_strong(obj, expected, desired) __c11_atomic_compare_exchange_strong(obj, expected, desired, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) | |
# define atomic_compare_exchange_strong_explicit(obj, expected, desired, success, fail) __c11_atomic_compare_exchange_strong(obj, expected, desired, success, fail) | |
// _Bool atomic_compare_exchange_weak (volatile A * obj, C * expected, C desired); | |
// _Bool atomic_compare_exchange_weak_explicit (volatile A * obj, C * expected, C desired, memory_order success, memory_order fail); | |
# define atomic_compare_exchange_weak(obj, expected, desired) __c11_atomic_compare_exchange_weak(obj, expected, desired, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) | |
# define atomic_compare_exchange_weak_explicit(obj, expected, desired, success, fail) __c11_atomic_compare_exchange_weak(obj, expected, desired, success, fail) | |
// C atomic_fetch_add (volatile A * obj, M value); | |
// C atomic_fetch_add_explicit (volatile A * obj, M value, memory_order order); | |
# define atomic_fetch_add(obj, value) __c11_atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST) | |
# define atomic_fetch_add_explicit(obj, value, order) __c11_atomic_fetch_add(obj, value, order) | |
// C atomic_fetch_sub (volatile A * obj, M value); | |
// C atomic_fetch_sub_explicit (volatile A * obj, M value, memory_order order); | |
# define atomic_fetch_sub(obj, value) __c11_atomic_fetch_sub(obj, value, __ATOMIC_SEQ_CST) | |
# define atomic_fetch_sub_explicit(obj, value, order) __c11_atomic_fetch_sub(obj, value, order) | |
// C atomic_fetch_or (volatile A * obj, M value); | |
// C atomic_fetch_or_explicit (volatile A * obj, M value, memory_order order); | |
# define atomic_fetch_or(obj, value) __c11_atomic_fetch_or(obj, value, __ATOMIC_SEQ_CST) | |
# define atomic_fetch_or_explicit(obj, value, order) __c11_atomic_fetch_or(obj, value, order) | |
// C atomic_fetch_xor (volatile A * obj, M value); | |
// C atomic_fetch_xor_explicit (volatile A * obj, M value, memory_order order); | |
# define atomic_fetch_xor(obj, value) __c11_atomic_fetch_xor(obj, value, __ATOMIC_SEQ_CST) | |
# define atomic_fetch_xor_explicit(obj, value, order) __c11_atomic_fetch_xor(obj, value, order) | |
// C atomic_fetch_and (volatile A * obj, M value); | |
// C atomic_fetch_and_explicit (volatile A * obj, M value, memory_order order); | |
# define atomic_fetch_and(obj, value) __c11_atomic_fetch_and(obj, value, __ATOMIC_SEQ_CST) | |
# define atomic_fetch_and_explicit(obj, value, order) __c11_atomic_fetch_and(obj, value, order) | |
// Possible atomic_flag type. | |
// typedef struct atomic_flag { atomic_bool value; } atomic_flag; | |
// _Bool atomic_flag_test_and_set (volatile atomic_flag * flag); | |
// _Bool atomic_flag_test_and_set_explicit (volatile atomic_flag * flag, memory_order order); | |
# define atomic_flag_test_and_set(flag) __c11_atomic_exchange(&(flag)->value, 1, __ATOMIC_SEQ_CST) | |
# define atomic_flag_test_and_set_explicit(flag, order) __c11_atomic_exchange(&(flag)->value, 1, order) | |
// void atomic_flag_clear (volatile atomic_flag * flag); | |
// void atomic_flag_clear_explicit (volatile atomic_flag * flag, memory_order order); | |
# define atomic_flag_clear(flag) __c11_atomic_store(&(flag)->value, 0, __ATOMIC_SEQ_CST) | |
# define atomic_flag_clear_explicit(flag, order) __c11_atomic_store(&(flag)->value, 0, order) | |
// void atomic_init (volatile A * obj, C desired) | |
# define atomic_init(obj, desired) __c11_atomic_init(obj, desired) | |
# endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment