From 1563b80852b62c0450cbc094679492e14a05296e Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 16 Nov 2020 12:43:05 +0100 Subject: [PATCH] include: Fix various issues with atomic CAS. - fail/success memory orders exist for a reason, we can't e.g. do release on fail since it's a read-only operation - silence some warnings about pointer->integer casts - fix linker errors on mingw by marking functions as static Signed-off-by: Philip Rebohle --- include/private/vkd3d_atomic.h | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/include/private/vkd3d_atomic.h b/include/private/vkd3d_atomic.h index 5c2f04ec..ec65157c 100644 --- a/include/private/vkd3d_atomic.h +++ b/include/private/vkd3d_atomic.h @@ -108,11 +108,12 @@ FORCEINLINE uint32_t vkd3d_atomic_uint32_decrement(uint32_t *target, vkd3d_memor return result; } -FORCEINLINE uint32_t vkd3d_atomic_uint32_compare_exchange(uint32_t* target, uint32_t expected, uint32_t desired, vkd3d_memory_order order) +FORCEINLINE uint32_t vkd3d_atomic_uint32_compare_exchange(uint32_t* target, uint32_t expected, uint32_t desired, + vkd3d_memory_order success_order, vkd3d_memory_order fail_order) { uint32_t result; /* InterlockedCompareExchange has desired (ExChange) first, then expected (Comperand) */ - vkd3d_atomic_choose_intrinsic(order, result, InterlockedCompareExchange, /* no suffix */, (LONG*)target, desired, expected); + vkd3d_atomic_choose_intrinsic(success_order, result, InterlockedCompareExchange, /* no suffix */, (LONG*)target, desired, expected); return result; } @@ -156,11 +157,12 @@ FORCEINLINE uint64_t vkd3d_atomic_uint64_decrement(uint64_t *target, vkd3d_memor return result; } -FORCEINLINE uint64_t vkd3d_atomic_uint64_compare_exchange(uint64_t* target, uint64_t expected, uint64_t desired, vkd3d_memory_order order) +FORCEINLINE uint64_t vkd3d_atomic_uint64_compare_exchange(uint64_t* target, uint64_t expected, uint64_t desired, + vkd3d_memory_order success_order, vkd3d_memory_order fail_order) { uint64_t result; /* InterlockedCompareExchange has desired (ExChange) first, then expected (Comperand) */ - vkd3d_atomic_choose_intrinsic(order, result, InterlockedCompareExchange, 64, (LONG64*)target, desired, expected); + vkd3d_atomic_choose_intrinsic(success_order, result, InterlockedCompareExchange, 64, (LONG64*)target, desired, expected); return result; } @@ -187,10 +189,11 @@ typedef enum # define vkd3d_atomic_uint32_exchange_explicit(target, value, order) vkd3d_atomic_generic_exchange_explicit(target, value, order) # define vkd3d_atomic_uint32_increment(target, order) vkd3d_atomic_generic_increment(target, order) # define vkd3d_atomic_uint32_decrement(target, order) vkd3d_atomic_generic_decrement(target, order) -FORCEINLINE uint32_t vkd3d_atomic_uint32_compare_exchange(uint32_t* target, uint32_t expected, uint32_t desired, vkd3d_memory_order order) +static inline uint32_t vkd3d_atomic_uint32_compare_exchange(uint32_t* target, uint32_t expected, uint32_t desired, + vkd3d_memory_order success_order, vkd3d_memory_order fail_order) { /* Expected is written to with the old value in the case that *target != expected */ - __atomic_compare_exchange_n(target, &expected, desired, 0, order, order); + __atomic_compare_exchange_n(target, &expected, desired, 0, success_order, fail_order); return expected; } @@ -199,21 +202,22 @@ FORCEINLINE uint32_t vkd3d_atomic_uint32_compare_exchange(uint32_t* target, uint # define vkd3d_atomic_uint64_exchange_explicit(target, value, order) vkd3d_atomic_generic_exchange_explicit(target, value, order) # define vkd3d_atomic_uint64_increment(target, order) vkd3d_atomic_generic_increment(target, order) # define vkd3d_atomic_uint64_decrement(target, order) vkd3d_atomic_generic_decrement(target, order) -FORCEINLINE uint64_t vkd3d_atomic_uint64_compare_exchange(uint64_t* target, uint64_t expected, uint64_t desired, vkd3d_memory_order order) +static inline uint64_t vkd3d_atomic_uint64_compare_exchange(uint64_t* target, uint64_t expected, uint64_t desired, + vkd3d_memory_order success_order, vkd3d_memory_order fail_order) { /* Expected is written to with the old value in the case that *target != expected */ - __atomic_compare_exchange_n(target, &expected, desired, 0, order, order); + __atomic_compare_exchange_n(target, &expected, desired, 0, success_order, fail_order); return expected; } # ifndef __MINGW32__ # define InterlockedIncrement(target) vkd3d_atomic_uint32_increment(target, vkd3d_memory_order_seq_cst) # define InterlockedDecrement(target) vkd3d_atomic_uint32_decrement(target, vkd3d_memory_order_seq_cst) -# define InterlockedCompareExchange(target, desired, expected) vkd3d_atomic_uint32_compare_exchange(target, expected, desired, vkd3d_memory_order_seq_cst) +# define InterlockedCompareExchange(target, desired, expected) vkd3d_atomic_uint32_compare_exchange(target, expected, desired, vkd3d_memory_order_seq_cst, vkd3d_memory_order_acquire) # define InterlockedIncrement64(target) vkd3d_atomic_uint64_increment(target, vkd3d_memory_order_seq_cst) # define InterlockedDecrement64(target) vkd3d_atomic_uint64_decrement(target, vkd3d_memory_order_seq_cst) -# define InterlockedCompareExchange64(target, desired, expected) vkd3d_atomic_uint64_compare_exchange(target, expected, desired, vkd3d_memory_order_seq_cst) +# define InterlockedCompareExchange64(target, desired, expected) vkd3d_atomic_uint64_compare_exchange(target, expected, desired, vkd3d_memory_order_seq_cst, vkd3d_memory_order_acquire) # endif #else @@ -228,14 +232,16 @@ FORCEINLINE uint64_t vkd3d_atomic_uint64_compare_exchange(uint64_t* target, uint # define vkd3d_atomic_ptr_exchange_explicit(target, value, order) ((void *)vkd3d_atomic_uint64_exchange_explicit((uint64_t *)target, value, order)) # define vkd3d_atomic_ptr_increment(target, order) ((void *)vkd3d_atomic_uint64_increment((uint64_t *)target, order)) # define vkd3d_atomic_ptr_decrement(target, order) ((void *)vkd3d_atomic_uint64_decrement((uint64_t *)target, order)) -# define vkd3d_atomic_ptr_compare_exchange(target, expected, desired, order) ((void *)vkd3d_atomic_uint64_compare_exchange((uint64_t *)target, expected, desired, order)) +# define vkd3d_atomic_ptr_compare_exchange(target, expected, desired, success_order, fail_order) \ + ((void *)vkd3d_atomic_uint64_compare_exchange((uint64_t *)target, (uint64_t)expected, (uint64_t)desired, success_order, fail_order)) #else # define vkd3d_atomic_ptr_load_explicit(target, order) ((void *)vkd3d_atomic_uint32_load_explicit((uint32_t *)target, order)) # define vkd3d_atomic_ptr_store_explicit(target, value, order) ((void *)vkd3d_atomic_uint32_store_explicit((uint32_t *)target, value, order)) # define vkd3d_atomic_ptr_exchange_explicit(target, value, order) ((void *)vkd3d_atomic_uint32_exchange_explicit((uint32_t *)target, value, order)) # define vkd3d_atomic_ptr_increment(target, order) ((void *)vkd3d_atomic_uint32_increment((uint32_t *)target, order)) # define vkd3d_atomic_ptr_decrement(target, order) ((void *)vkd3d_atomic_uint32_decrement((uint32_t *)target, order)) -# define vkd3d_atomic_ptr_compare_exchange(target, expected, desired, order) ((void *)vkd3d_atomic_uint32_compare_exchange((uint32_t *)target, expected, desired, order)) +# define vkd3d_atomic_ptr_compare_exchange(target, expected, desired, success_order, fail_order) \ + ((void *)vkd3d_atomic_uint32_compare_exchange((uint32_t *)target, (uint32_t)expected, (uint32_t)desired, success_order, fail_order)) #endif #endif