#ifndef _AL_ATOMIC_H #define _AL_ATOMIC_H #include "lib.h" #include #define AL_ATOMIC_RELAXED c89atomic_memory_order_relaxed #define AL_ATOMIC_CONSUME c89atomic_memory_order_consume #define AL_ATOMIC_ACQUIRE c89atomic_memory_order_acquire #define AL_ATOMIC_RELEASE c89atomic_memory_order_release #define AL_ATOMIC_ACQ_REL c89atomic_memory_order_acq_rel #define AL_ATOMIC_SEQ_CST c89atomic_memory_order_seq_cst #define AL_PASTER_EVALUATOR(X, Y) X##_##Y #define AL_PASTER(X, Y) AL_PASTER_EVALUATOR(X, Y) #define atomic(T) AL_PASTER(_al_atomic, T) #define atomic_load(T) AL_PASTER(_al_atomic_load, T) #define atomic_store(T) AL_PASTER(_al_atomic_store, T) #define atomic_add(T) AL_PASTER(_al_atomic_add, T) #define atomic_compare_and_swap(T) AL_PASTER(_al_atomic_compare_and_swap, T) #define atomic_sub(T) AL_PASTER(_al_atomic_sub, T) // Special case for pointers. #define _al_atomic_load_void(p, order) c89atomic_load_explicit_ptr((volatile void **)p, order) #define _al_atomic_store_void(p, v, order) c89atomic_store_explicit_ptr((volatile void **)p, (void *)v, order) // c89atomic compat. typedef f64 c89atomic_f64; typedef f32 c89atomic_f32; #define AL_ATOMIC_DEFINE(T, C, S) \ typedef c89atomic_##C atomic(T); \ static inline T atomic_load(T)(atomic(T) *a, s32 order) \ { \ return c89atomic_load_explicit_##S(a, order); \ } \ static inline void atomic_store(T)(atomic(T) *a, T value, s32 order) \ { \ c89atomic_store_explicit_##S(a, value, order); \ } \ static inline T atomic_compare_and_swap(T)(atomic(T) *a, T expected, T desired) \ { \ return c89atomic_compare_and_swap_##S(a, expected, desired); \ } #define AL_ATOMIC_DEFINE_EXT(T, C, S) \ static inline T atomic_add(T)(atomic(T) *a, T value, s32 order) \ { \ return c89atomic_fetch_add_explicit_##S(a, value, order); \ } \ static inline T atomic_sub(T)(atomic(T) *a, T value, s32 order) \ { \ return c89atomic_fetch_sub_explicit_##S(a, value, order); \ } #if defined C89ATOMIC_64BIT AL_ATOMIC_DEFINE(size_t, uint64, 64) AL_ATOMIC_DEFINE(ptrdiff_t, int64, i64) #elif defined C89ATOMIC_32BIT AL_ATOMIC_DEFINE(size_t, uint32, 32) AL_ATOMIC_DEFINE(ptrdiff_t, int32, i32) #endif AL_ATOMIC_DEFINE(u64, uint64, 64); AL_ATOMIC_DEFINE_EXT(u64, uint64, 64); AL_ATOMIC_DEFINE(s64, int64, i64); AL_ATOMIC_DEFINE(u32, uint32, 32); AL_ATOMIC_DEFINE_EXT(u32, uint32, 32); AL_ATOMIC_DEFINE(s32, int32, i32); AL_ATOMIC_DEFINE_EXT(s32, int32, i32); AL_ATOMIC_DEFINE(u16, uint16, 16); AL_ATOMIC_DEFINE_EXT(u16, uint16, 16); AL_ATOMIC_DEFINE(s16, int16, i16); AL_ATOMIC_DEFINE(u8, uint8, 8); AL_ATOMIC_DEFINE(s8, int8, i8); AL_ATOMIC_DEFINE(f64, f64, f64); AL_ATOMIC_DEFINE(f32, f32, f32); AL_ATOMIC_DEFINE(bool, bool, 32); static inline f32 _al_atomic_add_f32(atomic(f32) *a, f32 value, s32 order) { (void)a; (void)value; (void)order; al_assert_and_return(0.f); } static inline f32 _al_atomic_sub_f32(atomic(f32) *a, f32 value, s32 order) { (void)a; (void)value; (void)order; al_assert_and_return(0.f); } #endif // _AL_ATOMIC_H