|  | #pragma once | 
|  | /** | 
|  | * This file implements the C11 and C++23 C atomics interfaces.  On targets | 
|  | * without hardware atomics, these will all lower to calls into the atomics | 
|  | * shared library.  You must link either atomics or atomics_fixed (if you use | 
|  | * only fixed-width atomics) into your firmware image. | 
|  | * | 
|  | * *WARNING*: The C++ atomics interface is more efficient for non-primitive | 
|  | * types but is *not* guaranteed to be interoperable with the C version. | 
|  | * Interoperable code should use only primitive types in atomics. | 
|  | */ | 
|  |  | 
|  | #ifdef __cplusplus | 
|  | #	include <atomic> | 
|  | #	define _Atomic(T) std::atomic<T> | 
|  | #else | 
|  | #	include <stddef.h> | 
|  | #	include <stdint.h> | 
|  | enum memory_order | 
|  | { | 
|  | memory_order_relaxed = __ATOMIC_RELAXED, | 
|  | memory_order_consume = __ATOMIC_CONSUME, | 
|  | memory_order_acquire = __ATOMIC_ACQUIRE, | 
|  | memory_order_release = __ATOMIC_RELEASE, | 
|  | memory_order_acq_rel = __ATOMIC_ACQ_REL, | 
|  | memory_order_seq_cst = __ATOMIC_SEQ_CST, | 
|  | }; | 
|  |  | 
|  | typedef _Atomic(_Bool) atomic_flag; | 
|  |  | 
|  | #	define ATOMIC_FLAG_INIT false | 
|  |  | 
|  | // Clang thinks that all atomics are too big, so ignore it. | 
|  | __clang_ignored_warning_push("-Watomic-alignment") | 
|  |  | 
|  | __always_inline static inline _Bool | 
|  | atomic_flag_test_and_set_explicit(volatile atomic_flag *obj, | 
|  | enum memory_order     order) | 
|  | { | 
|  | return __c11_atomic_exchange(obj, 1, order); | 
|  | } | 
|  |  | 
|  | __always_inline static inline _Bool | 
|  | atomic_flag_test_and_set(volatile atomic_flag *obj) | 
|  | { | 
|  | return atomic_flag_test_and_set_explicit(obj, memory_order_seq_cst); | 
|  | } | 
|  |  | 
|  | __always_inline static inline _Bool | 
|  | atomic_flag_test_and_clear_explicit(volatile atomic_flag *obj, | 
|  | enum memory_order     order) | 
|  | { | 
|  | return __c11_atomic_exchange(obj, 0, order); | 
|  | } | 
|  |  | 
|  | __always_inline static inline _Bool | 
|  | atomic_flag_test_and_clear(volatile atomic_flag *obj) | 
|  | { | 
|  | return atomic_flag_test_and_clear_explicit(obj, memory_order_seq_cst); | 
|  | } | 
|  |  | 
|  | __clang_ignored_warning_pop() | 
|  |  | 
|  | // The functions in the following block are mapped directly to builtins. | 
|  | #	define atomic_init(obj, value) __c11_atomic_init(obj, value) | 
|  | #	define atomic_compare_exchange_strong_explicit(                           \ | 
|  | object, expected, desired, success, failure)                             \ | 
|  | __c11_atomic_compare_exchange_strong(                                  \ | 
|  | object, expected, desired, success, failure) | 
|  | #	define atomic_compare_exchange_weak_explicit(                             \ | 
|  | object, expected, desired, success, failure)                             \ | 
|  | __c11_atomic_compare_exchange_weak(                                    \ | 
|  | object, expected, desired, success, failure) | 
|  | #	define atomic_exchange_explicit(object, desired, order)                   \ | 
|  | __c11_atomic_exchange(object, desired, order) | 
|  | #	define atomic_fetch_add_explicit(object, operand, order)                  \ | 
|  | __c11_atomic_fetch_add(object, operand, order) | 
|  | #	define atomic_fetch_and_explicit(object, operand, order)                  \ | 
|  | __c11_atomic_fetch_and(object, operand, order) | 
|  | #	define atomic_fetch_or_explicit(object, operand, order)                   \ | 
|  | __c11_atomic_fetch_or(object, operand, order) | 
|  | #	define atomic_fetch_sub_explicit(object, operand, order)                  \ | 
|  | __c11_atomic_fetch_sub(object, operand, order) | 
|  | #	define atomic_fetch_xor_explicit(object, operand, order)                  \ | 
|  | __c11_atomic_fetch_xor(object, operand, order) | 
|  | #	define atomic_load_explicit(object, order) __c11_atomic_load(object, order) | 
|  | #	define atomic_store_explicit(object, desired, order)                      \ | 
|  | __c11_atomic_store(object, desired, order) | 
|  |  | 
|  | // The functions in the following block are convenience wrappers around the | 
|  | // previous block | 
|  |  | 
|  | #	define atomic_compare_exchange_strong(object, expected, desired)          \ | 
|  | atomic_compare_exchange_strong_explicit(object,                        \ | 
|  | expected,                      \ | 
|  | desired,                       \ | 
|  | memory_order_seq_cst,          \ | 
|  | memory_order_seq_cst) | 
|  | #	define atomic_compare_exchange_weak(object, expected, desired)            \ | 
|  | atomic_compare_exchange_weak_explicit(object,                          \ | 
|  | expected,                        \ | 
|  | desired,                         \ | 
|  | memory_order_seq_cst,            \ | 
|  | memory_order_seq_cst) | 
|  | #	define atomic_exchange(object, desired)                                   \ | 
|  | atomic_exchange_explicit(object, desired, memory_order_seq_cst) | 
|  | #	define atomic_fetch_add(object, operand)                                  \ | 
|  | atomic_fetch_add_explicit(object, operand, memory_order_seq_cst) | 
|  | #	define atomic_fetch_and(object, operand)                                  \ | 
|  | atomic_fetch_and_explicit(object, operand, memory_order_seq_cst) | 
|  | #	define atomic_fetch_or(object, operand)                                   \ | 
|  | atomic_fetch_or_explicit(object, operand, memory_order_seq_cst) | 
|  | #	define atomic_fetch_sub(object, operand)                                  \ | 
|  | atomic_fetch_sub_explicit(object, operand, memory_order_seq_cst) | 
|  | #	define atomic_fetch_xor(object, operand)                                  \ | 
|  | atomic_fetch_xor_explicit(object, operand, memory_order_seq_cst) | 
|  | #	define atomic_load(object)                                                \ | 
|  | atomic_load_explicit(object, memory_order_seq_cst) | 
|  | #	define atomic_store(object, desired)                                      \ | 
|  | atomic_store_explicit(object, desired, memory_order_seq_cst) | 
|  | #endif | 
|  |  | 
|  | typedef _Atomic(_Bool)              atomic_bool; | 
|  | typedef _Atomic(char)               atomic_char; | 
|  | typedef _Atomic(signed char)        atomic_schar; | 
|  | typedef _Atomic(unsigned char)      atomic_uchar; | 
|  | typedef _Atomic(short)              atomic_short; | 
|  | typedef _Atomic(unsigned short)     atomic_ushort; | 
|  | typedef _Atomic(int)                atomic_int; | 
|  | typedef _Atomic(unsigned int)       atomic_uint; | 
|  | typedef _Atomic(long)               atomic_long; | 
|  | typedef _Atomic(unsigned long)      atomic_ulong; | 
|  | typedef _Atomic(long long)          atomic_llong; | 
|  | typedef _Atomic(unsigned long long) atomic_ullong; | 
|  | typedef _Atomic(int_least8_t)       atomic_int_least8_t; | 
|  | typedef _Atomic(uint_least8_t)      atomic_uint_least8_t; | 
|  | typedef _Atomic(int_least16_t)      atomic_int_least16_t; | 
|  | typedef _Atomic(uint_least16_t)     atomic_uint_least16_t; | 
|  | typedef _Atomic(int_least32_t)      atomic_int_least32_t; | 
|  | typedef _Atomic(uint_least32_t)     atomic_uint_least32_t; | 
|  | typedef _Atomic(int_least64_t)      atomic_int_least64_t; | 
|  | typedef _Atomic(uint_least64_t)     atomic_uint_least64_t; | 
|  | typedef _Atomic(int_fast8_t)        atomic_int_fast8_t; | 
|  | typedef _Atomic(uint_fast8_t)       atomic_uint_fast8_t; | 
|  | typedef _Atomic(int_fast16_t)       atomic_int_fast16_t; | 
|  | typedef _Atomic(uint_fast16_t)      atomic_uint_fast16_t; | 
|  | typedef _Atomic(int_fast32_t)       atomic_int_fast32_t; | 
|  | typedef _Atomic(uint_fast32_t)      atomic_uint_fast32_t; | 
|  | typedef _Atomic(int_fast64_t)       atomic_int_fast64_t; | 
|  | typedef _Atomic(uint_fast64_t)      atomic_uint_fast64_t; | 
|  | typedef _Atomic(intptr_t)           atomic_intptr_t; | 
|  | typedef _Atomic(uintptr_t)          atomic_uintptr_t; | 
|  | typedef _Atomic(size_t)             atomic_size_t; | 
|  | typedef _Atomic(ptrdiff_t)          atomic_ptrdiff_t; |