From 3ff56f4a3c03412e9ddf0e4c60c93a3db9e6481a Mon Sep 17 00:00:00 2001 From: Ryan Pavlik Date: Wed, 15 Jul 2020 13:01:00 -0500 Subject: [PATCH] inc/xrt: Add Windows implementations of atomic intrinsics. --- src/xrt/include/xrt/xrt_compiler.h | 48 ++++++++++++++++++++++++++---- src/xrt/include/xrt/xrt_defines.h | 6 ++-- 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/src/xrt/include/xrt/xrt_compiler.h b/src/xrt/include/xrt/xrt_compiler.h index 990e02d86..e80c0fc0c 100644 --- a/src/xrt/include/xrt/xrt_compiler.h +++ b/src/xrt/include/xrt/xrt_compiler.h @@ -17,6 +17,18 @@ #include #include +#ifdef _MSC_VER +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif // !WIN32_LEAN_AND_MEAN +#ifndef NOMINMAX +#define NOMINMAX +#endif // !NOMINMAX + +#include +// for atomic intrinsics +#include +#endif // _MSC_VER /*! * Array size helper. @@ -71,7 +83,6 @@ #elif defined(__clang__) || defined(__GNUC__) #define XRT_DEBUGBREAK() __builtin_trap() #elif defined(_MSC_VER) -#include #define XRT_DEBUGBREAK() __debugbreak() #else #error "compiler not supported" @@ -79,14 +90,41 @@ +typedef volatile int32_t xrt_atomic_s32_t; + +static inline int32_t +xrt_atomic_s32_inc_return(xrt_atomic_s32_t *p) +{ #if defined(__GNUC__) -#define xrt_atomic_inc_return(v) __sync_add_and_fetch((v), 1) -#define xrt_atomic_dec_return(v) __sync_sub_and_fetch((v), 1) -#define xrt_atomic_cmpxchg(v, old, _new) \ - __sync_val_compare_and_swap((v), (old), (_new)) + return __sync_add_and_fetch(p, 1); +#elif defined(_MSC_VER) + return InterlockedIncrement((volatile LONG *)p); #else #error "compiler not supported" #endif +} +static inline int32_t +xrt_atomic_s32_dec_return(xrt_atomic_s32_t *p) +{ +#if defined(__GNUC__) + return __sync_sub_and_fetch(p, 1); +#elif defined(_MSC_VER) + return InterlockedDecrement((volatile LONG *)p); +#else +#error "compiler not supported" +#endif +} +static inline int32_t +xrt_atomic_s32_cmpxchg(xrt_atomic_s32_t *p, int32_t old_, int32_t new_) +{ +#if defined(__GNUC__) + return __sync_val_compare_and_swap(p, old_, new_); +#elif defined(_MSC_VER) + return InterlockedCompareExchange((volatile LONG *)p, old_, new_); +#else +#error "compiler not supported" +#endif +} /*! * Get the holder from a pointer to a field. diff --git a/src/xrt/include/xrt/xrt_defines.h b/src/xrt/include/xrt/xrt_defines.h index 25e3f644c..24c29185f 100644 --- a/src/xrt/include/xrt/xrt_defines.h +++ b/src/xrt/include/xrt/xrt_defines.h @@ -28,7 +28,7 @@ extern "C" { */ struct xrt_reference { - uint32_t count; + xrt_atomic_s32_t count; }; /*! @@ -617,14 +617,14 @@ union xrt_output_value { static inline bool xrt_reference_dec(struct xrt_reference *xref) { - int count = xrt_atomic_dec_return(&xref->count); + int32_t count = xrt_atomic_s32_dec_return(&xref->count); return count == 0; } static inline void xrt_reference_inc(struct xrt_reference *xref) { - xrt_atomic_inc_return(&xref->count); + xrt_atomic_s32_inc_return(&xref->count); }