#pragma once #include #include #include // No atomic qualifier. #define _Atomic volatile typedef _Atomic bool atomic_bool; typedef _Atomic bool atomic_flag; typedef _Atomic unsigned char atomic_uchar; typedef _Atomic int atomic_int; typedef _Atomic unsigned int atomic_uint; typedef _Atomic size_t atomic_size_t; typedef _Atomic uintptr_t atomic_uintptr_t; typedef _Atomic long atomic_long; typedef _Atomic unsigned long atomic_ulong; typedef _Atomic uint32_t atomic_uint32_t; #define ATOMIC_FLAG_INIT false typedef enum { memory_order_relaxed, memory_order_consume, memory_order_acquire, memory_order_release, memory_order_acq_rel, memory_order_seq_cst, } memory_order; extern __cregister volatile uint16_t IER; static inline uint16_t __ier_disable(void) { const uint16_t mask = IER; IER = 0; return mask; } static inline void __ier_restore(uint16_t mask) { IER = mask; } #define atomic_load(p) (*(p)) #define atomic_load_explicit(p, mo) atomic_load(p) #define atomic_store(p, v) (*(p) = (v)) #define atomic_store_explicit(p, v, mo) atomic_store(p, v) #define atomic_exchange_explicit(p, v, mo) \ ({ \ const uint16_t mask = __ier_disable(); \ const __typeof__(*(p)) o = *(p); \ *(p) = (v); \ __ier_restore(mask); \ o; \ }) #define atomic_fetch_add_explicit(p, v, mo) \ ({ \ const uint16_t mask = __ier_disable(); \ const __typeof__(*(p)) o = *(p); \ *(p) += (v); \ __ier_restore(mask); \ o; \ }) #define atomic_fetch_sub_explicit(p, v, mo) \ ({ \ const uint16_t mask = __ier_disable(); \ const __typeof__(*(p)) o = *(p); \ *(p) -= (v); \ __ier_restore(mask); \ o; \ }) #define atomic_fetch_or_explicit(p, v, mo) \ ({ \ const uint16_t mask = __ier_disable(); \ const __typeof__(*(p)) o = *(p); \ *(p) |= (v); \ __ier_restore(mask); \ o; \ }) #define atomic_fetch_and_explicit(p, v, mo) \ ({ \ const uint16_t mask = __ier_disable(); \ const __typeof__(*(p)) o = *(p); \ *(p) &= (v); \ __ier_restore(mask); \ o; \ }) #define atomic_compare_exchange_strong_explicit(p, e, v, mos, mof) \ ({ \ const uint16_t mask = __ier_disable(); \ const __typeof__(v) o = *(p); \ const bool equal = o == *(e); \ if (equal) \ { \ *(p) = (v); \ } \ else \ { \ *(e) = o; \ } \ __ier_restore(mask); \ equal; \ }) #define atomic_compare_exchange_weak_explicit \ atomic_compare_exchange_strong_explicit #define atomic_flag_test_and_set_explicit(p, mo) \ ({ \ const uint16_t mask = __ier_disable(); \ const bool o = *(p); \ *(p) = true; \ __ier_restore(mask); \ o; \ }) #define atomic_flag_clear_explicit(p, mo) ({ *(p) = false; })