From cd2b91c62ea74f6448a8a5cff5dd316f8e692e97 Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Sun, 4 Apr 2021 15:52:15 +0900 Subject: [PATCH] atomic: Add support for WIN32 atomic operations Windows provides atomic operation APIs so use it --- src/cairo-atomic-private.h | 61 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/src/cairo-atomic-private.h b/src/cairo-atomic-private.h index 46761856f..70d4b79d6 100644 --- a/src/cairo-atomic-private.h +++ b/src/cairo-atomic-private.h @@ -279,6 +279,67 @@ typedef int64_t cairo_atomic_intptr_t; #endif +#if !defined(HAS_ATOMIC_OPS) && defined(_WIN32) +#include + +#define HAS_ATOMIC_OPS 1 + +typedef int32_t cairo_atomic_int_t; + +#if SIZEOF_VOID_P==SIZEOF_INT +typedef unsigned int cairo_atomic_intptr_t; +#elif SIZEOF_VOID_P==SIZEOF_LONG +typedef unsigned long cairo_atomic_intptr_t; +#elif SIZEOF_VOID_P==SIZEOF_LONG_LONG +typedef unsigned long long cairo_atomic_intptr_t; +#else +#error No matching integer pointer type +#endif + +static cairo_always_inline cairo_atomic_int_t +_cairo_atomic_int_get (cairo_atomic_int_t *x) +{ + MemoryBarrier (); + return *x; +} + +# define _cairo_atomic_int_get_relaxed(x) *(x) +# define _cairo_atomic_int_set_relaxed(x, val) *(x) = (val) + +# define _cairo_atomic_int_inc(x) ((void) InterlockedIncrement (x)) +# define _cairo_atomic_int_dec(x) ((void) InterlockedDecrement (x)) +# define _cairo_atomic_int_dec_and_test(x) (InterlockedDecrement (x) == 0) + +static cairo_always_inline cairo_bool_t +_cairo_atomic_int_cmpxchg (cairo_atomic_int_t *x, + cairo_atomic_int_t oldv, + cairo_atomic_int_t newv) +{ + return InterlockedCompareExchange (x, newv, oldv) == oldv; +} + +static cairo_always_inline void * +_cairo_atomic_ptr_get (void **x) +{ + MemoryBarrier (); + return *x; +} + +static cairo_always_inline cairo_bool_t +_cairo_atomic_ptr_cmpxchg (void **x, void *oldv, void *newv) +{ + return InterlockedCompareExchangePointer (x, newv, oldv) == oldv; +} + +static cairo_always_inline void * +_cairo_atomic_ptr_cmpxchg_return_old (void **x, void *oldv, void *newv) +{ + return InterlockedCompareExchangePointer (x, newv, oldv); +} + +#endif /* !defined(HAS_ATOMIC_OPS) && defined(_WIN32) */ + + #ifndef HAS_ATOMIC_OPS #if SIZEOF_VOID_P==SIZEOF_INT