From e085dae6367ded4c6c743e7aed58d996015d2f5d Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Tue, 29 Oct 2024 16:31:41 -0700 Subject: [PATCH] pass over atomic operations - use cast to volatile trick for atomic loads on x64 windows - removed unnecessary includes on windows - upgraded clang and gcc code paths to use modern atomics Removed WIN32_LEAN_AND_MEAN because we were already compiling without it and there is code path in os_gfx_win32.c that relies on including full windows.h --- src/base/base_core.h | 65 +++++++++++++++++-------------- src/linker/base_ext/base_core.h | 10 ----- src/os/core/win32/os_core_win32.h | 1 - 3 files changed, 36 insertions(+), 40 deletions(-) diff --git a/src/base/base_core.h b/src/base/base_core.h index 04c9ad4f..8a5fba19 100644 --- a/src/base/base_core.h +++ b/src/base/base_core.h @@ -172,42 +172,49 @@ //////////////////////////////// //~ rjf: Atomic Operations -#if OS_WINDOWS -# include -# include -# include +#if COMPILER_MSVC # include # if ARCH_X64 -# define ins_atomic_u64_eval(x) InterlockedAdd64((volatile __int64 *)(x), 0) -# define ins_atomic_u64_inc_eval(x) InterlockedIncrement64((volatile __int64 *)(x)) -# define ins_atomic_u64_dec_eval(x) InterlockedDecrement64((volatile __int64 *)(x)) -# define ins_atomic_u64_eval_assign(x,c) InterlockedExchange64((volatile __int64 *)(x),(c)) -# define ins_atomic_u64_add_eval(x,c) InterlockedAdd64((volatile __int64 *)(x), c) +# define ins_atomic_u64_eval(x) *((volatile U64 *)(x)) +# define ins_atomic_u64_inc_eval(x) InterlockedIncrement64((volatile __int64 *)(x)) +# define ins_atomic_u64_dec_eval(x) InterlockedDecrement64((volatile __int64 *)(x)) +# define ins_atomic_u64_eval_assign(x,c) InterlockedExchange64((volatile __int64 *)(x),(c)) +# define ins_atomic_u64_add_eval(x,c) InterlockedAdd64((volatile __int64 *)(x), c) # define ins_atomic_u64_eval_cond_assign(x,k,c) InterlockedCompareExchange64((volatile __int64 *)(x),(k),(c)) -# define ins_atomic_u32_eval(x,c) InterlockedAdd((volatile LONG *)(x), 0) -# define ins_atomic_u32_eval_assign(x,c) InterlockedExchange((volatile LONG *)(x),(c)) +# define ins_atomic_u32_eval(x) *((volatile U32 *)(x)) +# define ins_atomic_u32_inc_eval(x) InterlockedIncrement((volatile LONG *)x) +# define ins_atomic_u32_eval_assign(x,c) InterlockedExchange((volatile LONG *)(x),(c)) # define ins_atomic_u32_eval_cond_assign(x,k,c) InterlockedCompareExchange((volatile LONG *)(x),(k),(c)) -# define ins_atomic_ptr_eval_assign(x,c) (void*)ins_atomic_u64_eval_assign((volatile __int64 *)(x), (__int64)(c)) +# define ins_atomic_u32_add_eval(x,c) InterlockedAdd((volatile LONG *)(x), c) # else -# error Atomic intrinsics not defined for this operating system / architecture combination. -# endif -#elif OS_LINUX -# if ARCH_X64 -# define ins_atomic_u64_eval(x) __sync_fetch_and_add((volatile U64 *)(x), 0) -# define ins_atomic_u64_inc_eval(x) __sync_fetch_and_add((volatile U64 *)(x), 1) -# define ins_atomic_u64_dec_eval(x) __sync_fetch_and_sub((volatile U64 *)(x), 1) -# define ins_atomic_u64_eval_assign(x,c) __sync_lock_test_and_set((volatile U64 *)(x),(c)) -# define ins_atomic_u64_add_eval(x,c) __sync_fetch_and_add((volatile U64 *)(x), c) -# define ins_atomic_u64_eval_cond_assign(x,k,c) __sync_val_compare_and_swap((volatile U64 *)(x),(c),(k)) -# define ins_atomic_u32_eval(x,c) __sync_fetch_and_add((volatile U32 *)(x), 0) -# define ins_atomic_u32_eval_assign(x,c) __sync_lock_test_and_set((volatile U32 *)(x),(c)) -# define ins_atomic_u32_eval_cond_assign(x,k,c) __sync_val_compare_and_swap((volatile U32 *)(x),(c),(k)) -# define ins_atomic_ptr_eval_assign(x,c) (void*)ins_atomic_u64_eval_assign((volatile U64 *)(x), (U64)(c)) -# else -# error Atomic intrinsics not defined for this operating system / architecture combination. +# error Atomic intrinsics not defined for this compiler / architecture combination. # endif +#elif COMPILER_CLANG || COMPILER_GCC +# define ins_atomic_u64_eval(x) __atomic_load_n(x, __ATOMIC_SEQ_CST) +# define ins_atomic_u64_inc_eval(x) (__atomic_fetch_add((volatile U64 *)(x), 1, __ATOMIC_SEQ_CST) + 1) +# define ins_atomic_u64_dec_eval(x) (__atomic_fetch_sub((volatile U64 *)(x), 1, __ATOMIC_SEQ_CST) - 1) +# define ins_atomic_u64_eval_assign(x,c) __atomic_exchange_n(x, c, __ATOMIC_SEQ_CST) +# define ins_atomic_u64_add_eval(x,c) (__atomic_fetch_add((volatile U64 *)(x), c, __ATOMIC_SEQ_CST) + (c)) +# define ins_atomic_u64_eval_cond_assign(x,k,c) ({ U64 _new = (c); __atomic_compare_exchange_n((volatile U64 *)(x),&_new,(k),0,__ATOMIC_SEQ_CST,__ATOMIC_SEQ_CST); _new; }) +# define ins_atomic_u32_eval(x) __atomic_load_n(x, __ATOMIC_SEQ_CST) +# define ins_atomic_u32_inc_eval(x) (__atomic_fetch_add((volatile U32 *)(x), 1, __ATOMIC_SEQ_CST) + 1) +# define ins_atomic_u32_add_eval(x,c) (__atomic_fetch_add((volatile U32 *)(x), c, __ATOMIC_SEQ_CST) + (c)) +# define ins_atomic_u32_eval_assign(x,c) __atomic_exchange_n(x, c, __ATOMIC_SEQ_CST) +# define ins_atomic_u32_eval_cond_assign(x,k,c) ({ U32 _new = (c); __atomic_compare_exchange_n((volatile U32 *)(x),&_new,(k),0,__ATOMIC_SEQ_CST,__ATOMIC_SEQ_CST); _new; }) #else -# error Atomic intrinsics not defined for this operating system. +# error Atomic intrinsics not defined for this compiler / architecture. +#endif + +#if ARCH_64BIT +# define ins_atomic_ptr_eval_cond_assign(x,k,c) (void*)ins_atomic_u64_eval_cond_assign((volatile U64 *)(x), (U64)(k), (U64)(c)) +# define ins_atomic_ptr_eval_assign(x,c) (void*)ins_atomic_u64_eval_assign((volatile U64 *)(x), (U64)(c)) +# define ins_atomic_ptr_eval(x) (void*)ins_atomic_u64_eval((volatile U64 *)x) +#elif ARCH_32BIT +# define ins_atomic_ptr_eval_cond_assign(x,k,c) (void*)ins_atomic_u32_eval_cond_assign((volatile U32 *)(x), (U32)(k), (U32)(c)) +# define ins_atomic_ptr_eval_assign(x,c) (void*)ins_atomic_u32_eval_assign((volatile U32 *)(x), (U32)(c)) +# define ins_atomic_ptr_eval(x) (void*)ins_atomic_u32_eval((volatile U32 *)x) +#else +# error Atomic intrinsics for pointers not defined for this achitecture. #endif //////////////////////////////// diff --git a/src/linker/base_ext/base_core.h b/src/linker/base_ext/base_core.h index d931bcfb..a5c736eb 100644 --- a/src/linker/base_ext/base_core.h +++ b/src/linker/base_ext/base_core.h @@ -23,16 +23,6 @@ #define BitExtract(x, count, shift) (((x) >> (shift)) & ((1 << (count)) - 1)) -//////////////////////////////// - -#if OS_WINDOWS -# define ins_atomic_ptr_eval_cond_assign(x,k,c) InterlockedCompareExchangePointer((volatile PVOID *)(x),(k),(c)) -# define ins_atomic_u32_add_eval(x,c) InterlockedAdd((volatile LONG *)(x), c) -# define ins_atomic_u32_inc_eval(x) InterlockedIncrement((volatile LONG *)x) -#else -# error "atomics are not defined for this system" -#endif - //////////////////////////////// // Linked List Helpers diff --git a/src/os/core/win32/os_core_win32.h b/src/os/core/win32/os_core_win32.h index a8c031fd..9a8f0d12 100644 --- a/src/os/core/win32/os_core_win32.h +++ b/src/os/core/win32/os_core_win32.h @@ -7,7 +7,6 @@ //////////////////////////////// //~ rjf: Includes / Libraries -#define WIN32_LEAN_AND_MEAN #include #include #include