#include #include #include #define TYPEDEF_ATOMIC2(type, atomic_type) \ typedef struct { \ type __v; \ } atomic_type #define TYPEDEF_ATOMIC1(type) \ typedef struct { \ type __v; \ } atomic_ ## type TYPEDEF_ATOMIC2(uint16_t, atomic_flag); TYPEDEF_ATOMIC2(unsigned char, atomic_uchar); TYPEDEF_ATOMIC2(signed char, atomic_schar); TYPEDEF_ATOMIC2(unsigned short, atomic_ushort); TYPEDEF_ATOMIC2(unsigned int, atomic_uint); TYPEDEF_ATOMIC2(unsigned long, atomic_ulong); TYPEDEF_ATOMIC1(bool); TYPEDEF_ATOMIC1(char); TYPEDEF_ATOMIC1(short); TYPEDEF_ATOMIC1(int); TYPEDEF_ATOMIC1(long); TYPEDEF_ATOMIC1(wchar_t); TYPEDEF_ATOMIC1(int_least8_t); TYPEDEF_ATOMIC1(uint_least8_t); TYPEDEF_ATOMIC1(int_least16_t); TYPEDEF_ATOMIC1(uint_least16_t); TYPEDEF_ATOMIC1(int_least32_t); TYPEDEF_ATOMIC1(uint_least32_t); TYPEDEF_ATOMIC1(int_least64_t); TYPEDEF_ATOMIC1(uint_least64_t); TYPEDEF_ATOMIC1(int_fast8_t); TYPEDEF_ATOMIC1(uint_fast8_t); TYPEDEF_ATOMIC1(int_fast16_t); TYPEDEF_ATOMIC1(uint_fast16_t); TYPEDEF_ATOMIC1(int_fast32_t); TYPEDEF_ATOMIC1(uint_fast32_t); TYPEDEF_ATOMIC1(int_fast64_t); TYPEDEF_ATOMIC1(uint_fast64_t); TYPEDEF_ATOMIC1(intptr_t); TYPEDEF_ATOMIC1(uintptr_t); TYPEDEF_ATOMIC1(size_t); TYPEDEF_ATOMIC1(ptrdiff_t); TYPEDEF_ATOMIC1(intmax_t); TYPEDEF_ATOMIC1(uintmax_t); #undef TYPEDEF_ATOMIC1 #undef TYPEDEF_ATOMIC2 typedef enum { 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 } memory_order; #define ATOMIC_BOOL_LOCK_FREE __atomic_always_lock_free(sizeof(bool), 0) #define ATOMIC_CHAR_LOCK_FREE __atomic_always_lock_free(sizeof(char), 0) #define ATOMIC_WCHAR_LOCK_FREE __atomic_always_lock_free(sizeof(wchar_t), 0) #define ATOMIC_SHORT_LOCK_FREE __atomic_always_lock_free(sizeof(short), 0) #define ATOMIC_INT_LOCK_FREE __atomic_always_lock_free(sizeof(int), 0) #define ATOMIC_LONG_LOCK_FREE __atomic_always_lock_free(sizeof(long), 0) #define ATOMIC_LLONG_LOCK_FREE __atomic_always_lock_free(sizeof(long long), 0) #define ATOMIC_POINTER_LOCK_FREE __atomic_always_lock_free(sizeof(void *), 0) #define ATOMIC_FLAG_INIT { 0 } #define ATOMIC_VAR_INIT(/* C */ value) { (value) } /* void */ #define atomic_init(/* volatile A * */ obj, /* C */ value) do { \ volatile typeof(obj) __ptr = (obj); \ __ptr = (value); \ } while(0) /* void */ #define atomic_thread_fence(/* memory_order */ order) \ __atomic_thread_fence(order) /* void */ #define atomic_signal_fence(/* memory_order */ order) \ __atomic_signal_fence(order) /* bool */ #define atomic_is_lock_free(/* const volatile A * */ obj) \ __atomic_is_lock_free(sizeof(obj), &(obj)->__v) /* void */ #define atomic_store_explicit(/* volatile A * */ obj, \ /* C */ desired, \ /* memory_order */ order) \ __atomic_store(&(obj)->__v, (desired), (order)) /* void */ #define atomic_store(/* volatile A * */ obj, \ /* C */ desired) \ atomic_store_explicit((obj), (desired), memory_order_seq_cst) /* C */ #define atomic_load_explicit(/* volatile A * */ obj, \ /* memory_order */ order) ({ \ typeof((obj)->__v) __ret; \ __atomic_load((obj), &__ret, (order)) \ __ret; \ }) /* C */ #define atomic_load(/* volatile A * */ obj) \ atomic_load_explicit((obj), memory_order_seq_cst) /* C */ #define atomic_exchange_explicit(/* volatile A * */ obj, \ /* C */ desired, \ /* memory_order */ order) \ ({ \ __typeof__((obj)->__v) __ret; \ switch(sizeof((obj)->__v)) { \ case 1: \ __atomic_exchange_1(&(obj)->__v, (desired), &__ret, (order)); \ break; \ case 2: \ __atomic_exchange_1(&(obj)->__v, (desired), &__ret, (order)); \ break; \ case 2: \ __atomic_exchange_1(&(obj)->__v, (desired), &__ret, (order)); \ break; \