From af33caf036a49b2f88a9cc4f671498270ec2e3cd Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Thu, 18 Apr 2024 19:15:52 +0200 Subject: [PATCH] vkd3d-common: Introduce vkd3d_atomic_exchange_ptr(). --- include/private/vkd3d_common.h | 29 +++++++++++++++++++++++++ libs/vkd3d/resource.c | 2 +- libs/vkd3d/vkd3d_private.h | 39 ++-------------------------------- 3 files changed, 32 insertions(+), 38 deletions(-) diff --git a/include/private/vkd3d_common.h b/include/private/vkd3d_common.h index 3e853b06..4b7da0a1 100644 --- a/include/private/vkd3d_common.h +++ b/include/private/vkd3d_common.h @@ -442,6 +442,17 @@ static inline bool vkd3d_atomic_compare_exchange_u32(uint32_t volatile *x, uint3 #endif } +static inline bool vkd3d_atomic_compare_exchange_ptr(void * volatile *x, void *expected, void *val) +{ +#if HAVE_SYNC_BOOL_COMPARE_AND_SWAP + return __sync_bool_compare_and_swap(x, expected, val); +#elif defined(_WIN32) + return InterlockedCompareExchangePointer(x, val, expected) == expected; +#else +# error "vkd3d_atomic_compare_exchange_ptr() not implemented for this platform" +#endif +} + static inline uint32_t vkd3d_atomic_exchange_u32(uint32_t volatile *x, uint32_t val) { #if HAVE_ATOMIC_EXCHANGE_N @@ -460,6 +471,24 @@ static inline uint32_t vkd3d_atomic_exchange_u32(uint32_t volatile *x, uint32_t #endif } +static inline void *vkd3d_atomic_exchange_ptr(void * volatile *x, void *val) +{ +#if HAVE_ATOMIC_EXCHANGE_N + return __atomic_exchange_n(x, val, __ATOMIC_SEQ_CST); +#elif defined(_WIN32) + return InterlockedExchangePointer(x, val); +#else + void *expected; + + do + { + expected = *x; + } while (!vkd3d_atomic_compare_exchange_ptr(x, expected, val)); + + return expected; +#endif +} + struct vkd3d_mutex { #ifdef _WIN32 diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c index e3d1661a..7a2f464c 100644 --- a/libs/vkd3d/resource.c +++ b/libs/vkd3d/resource.c @@ -2473,7 +2473,7 @@ void vkd3d_view_decref(void *view, struct d3d12_device *device) static inline void d3d12_desc_replace(struct d3d12_desc *dst, void *view, struct d3d12_device *device) { - if ((view = vkd3d_atomic_exchange_pointer(&dst->s.u.object, view))) + if ((view = vkd3d_atomic_exchange_ptr(&dst->s.u.object, view))) vkd3d_view_decref(view, device); } diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index efe049a2..4d0c4a3c 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -197,49 +197,14 @@ struct vkd3d_instance unsigned int refcount; }; -#ifdef _WIN32 - -union vkd3d_thread_handle -{ - void *handle; -}; - -static inline void *vkd3d_atomic_exchange_pointer(void * volatile *x, void *val) -{ - return InterlockedExchangePointer(x, val); -} - -#else /* _WIN32 */ - -#include - union vkd3d_thread_handle { +#ifndef _WIN32 pthread_t pthread; +#endif void *handle; }; -# if HAVE_ATOMIC_EXCHANGE_N -static inline void *vkd3d_atomic_exchange_pointer(void * volatile *x, void *val) -{ - return __atomic_exchange_n(x, val, __ATOMIC_SEQ_CST); -} -# elif HAVE_SYNC_BOOL_COMPARE_AND_SWAP -static inline void *vkd3d_atomic_exchange_pointer(void * volatile *x, void *val) -{ - void *p; - do - { - p = *x; - } while (!__sync_bool_compare_and_swap(x, p, val)); - return p; -} -# else -# error "vkd3d_atomic_exchange() not implemented for this platform" -# endif - -#endif /* _WIN32 */ - HRESULT vkd3d_create_thread(struct vkd3d_instance *instance, PFN_vkd3d_thread thread_main, void *data, union vkd3d_thread_handle *thread); HRESULT vkd3d_join_thread(struct vkd3d_instance *instance, union vkd3d_thread_handle *thread);