3 commits - meson.build meson-cc-tests/atomic-ops-c11.c src/cairo-atomic.c src/cairo-atomic-private.h src/cairo-freed-pool.c src/cairo-freed-pool-private.h src/cairo-misc.c src/cairo-mutex.c src/cairo-mutex-private.h src/cairo-recording-surface.c src/cairo-reference-count-private.h src/cairo-surface.c src/win32

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri May 31 09:40:41 UTC 2024


 meson-cc-tests/atomic-ops-c11.c     |   12 +
 meson.build                         |    8 +
 src/cairo-atomic-private.h          |  239 ++++++++++++++++++++----------------
 src/cairo-atomic.c                  |   20 +--
 src/cairo-freed-pool-private.h      |    6 
 src/cairo-freed-pool.c              |    3 
 src/cairo-misc.c                    |    4 
 src/cairo-mutex-private.h           |    6 
 src/cairo-mutex.c                   |    4 
 src/cairo-recording-surface.c       |    2 
 src/cairo-reference-count-private.h |    2 
 src/cairo-surface.c                 |    2 
 src/win32/cairo-win32-device.c      |    2 
 13 files changed, 186 insertions(+), 124 deletions(-)

New commits:
commit f0a651e1ac1fe91aeee1789663c13e5333ee1741
Merge: 01a8ca051 87f7c60bf
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Fri May 31 09:40:37 2024 +0000

    Merge branch 'c11-atomics' into 'master'
    
    Add support for C11 atomics
    
    See merge request cairo/cairo!479

commit 87f7c60bf7c20079c34cfc54e4db05920d14db56
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Sat May 27 21:21:47 2023 +0930

    Add support for C11 atomics

diff --git a/meson-cc-tests/atomic-ops-c11.c b/meson-cc-tests/atomic-ops-c11.c
new file mode 100644
index 000000000..4d60e998f
--- /dev/null
+++ b/meson-cc-tests/atomic-ops-c11.c
@@ -0,0 +1,12 @@
+#include <assert.h>
+#include <stdatomic.h>
+
+/* We require lock free atomics for int and pointers as cairo assumes
+ * an int* can be cast to cairo_atomic_int_t*
+ */
+_Static_assert (ATOMIC_INT_LOCK_FREE == 2, "Lock free atomics not supported");
+_Static_assert (ATOMIC_POINTER_LOCK_FREE == 2, "Lock free atomics not supported");
+
+int atomic_add(atomic_int *i) { return atomic_fetch_add_explicit(i, 1, memory_order_seq_cst); }
+int atomic_cmpxchg(atomic_int *i, int j, int k) { return atomic_compare_exchange_strong_explicit (i, &j, k, memory_order_seq_cst, memory_order_seq_cst); }
+int main(void) { return 0; }
diff --git a/meson.build b/meson.build
index 3a5820640..151c46411 100644
--- a/meson.build
+++ b/meson.build
@@ -726,7 +726,11 @@ endforeach
 
 extra_link_args += pthread_link_args
 
-if cc.links(files('meson-cc-tests/atomic-ops-cxx11.c'), name: 'Atomic ops: cxx11')
+# Atomics are an optional feature in C11. Also need to check that C11 atomics are lock free.
+# Windows can't use C11 atomics as some files are compiled with C++.
+if host_machine.system() != 'windows' and cc.links(files('meson-cc-tests/atomic-ops-c11.c'), name: 'Atomic ops: c11')
+  conf.set('HAVE_C11_ATOMIC_PRIMITIVES', 1)
+elif cc.links(files('meson-cc-tests/atomic-ops-cxx11.c'), name: 'Atomic ops: cxx11')
   conf.set('HAVE_CXX11_ATOMIC_PRIMITIVES', 1)
 elif cc.links(files('meson-cc-tests/atomic-ops-gcc-legacy.c'), name: 'Atomic ops: gcc legacy')
   conf.set('HAVE_GCC_LEGACY_ATOMICS', 1)
@@ -734,6 +738,8 @@ elif cc.has_header('atomic_ops.h')
   conf.set('HAVE_LIB_ATOMIC_OPS', 1)
 elif cc.has_header('libkern/OSAtomic.h')
   conf.set('HAVE_OS_ATOMIC_OPS', 1)
+elif host_machine.system() != 'windows'
+  warning('Atomic ops not supported.')
 endif
 
 test_mkdir_c_args = []
diff --git a/src/cairo-atomic-private.h b/src/cairo-atomic-private.h
index dd49e618b..feba95691 100644
--- a/src/cairo-atomic-private.h
+++ b/src/cairo-atomic-private.h
@@ -47,6 +47,92 @@
 
 CAIRO_BEGIN_DECLS
 
+#if HAVE_C11_ATOMIC_PRIMITIVES
+
+#include <stdatomic.h>
+
+#define HAS_ATOMIC_OPS 1
+
+typedef atomic_int cairo_atomic_int_t;
+typedef _Atomic(void *) cairo_atomic_intptr_t;
+
+static cairo_always_inline int
+_cairo_atomic_int_get (cairo_atomic_int_t *x)
+{
+    return atomic_load_explicit (x, memory_order_seq_cst);
+}
+
+static cairo_always_inline int
+_cairo_atomic_int_get_relaxed (cairo_atomic_int_t *x)
+{
+    return atomic_load_explicit (x, memory_order_relaxed);
+}
+
+static cairo_always_inline void
+_cairo_atomic_int_set_relaxed (cairo_atomic_int_t *x, int val)
+{
+    atomic_store_explicit (x, val, memory_order_relaxed);
+}
+
+static cairo_always_inline void *
+_cairo_atomic_ptr_get (cairo_atomic_intptr_t *x)
+{
+    return atomic_load_explicit (x, memory_order_seq_cst);
+}
+
+# define _cairo_atomic_int_inc(x) ((void) atomic_fetch_add_explicit(x, 1, memory_order_seq_cst))
+# define _cairo_atomic_int_dec(x) ((void) atomic_fetch_sub_explicit(x, 1, memory_order_seq_cst))
+# define _cairo_atomic_int_dec_and_test(x) (atomic_fetch_sub_explicit(x, 1, memory_order_seq_cst) == 1)
+
+
+static cairo_always_inline cairo_bool_t
+_cairo_atomic_int_cmpxchg_impl(cairo_atomic_int_t *x,
+			       int                oldv,
+			       int                newv)
+{
+    int expected = oldv;
+    return atomic_compare_exchange_strong_explicit (x, &expected, newv, memory_order_seq_cst, memory_order_seq_cst);
+}
+
+#define _cairo_atomic_int_cmpxchg(x, oldv, newv) \
+  _cairo_atomic_int_cmpxchg_impl(x, oldv, newv)
+
+static cairo_always_inline int
+_cairo_atomic_int_cmpxchg_return_old_impl(cairo_atomic_int_t *x,
+					  int                 oldv,
+					  int                 newv)
+{
+    int expected = oldv;
+    (void) atomic_compare_exchange_strong_explicit (x, &expected, newv, memory_order_seq_cst, memory_order_seq_cst);
+    return expected;
+}
+
+#define _cairo_atomic_int_cmpxchg_return_old(x, oldv, newv) \
+  _cairo_atomic_int_cmpxchg_return_old_impl(x, oldv, newv)
+
+static cairo_always_inline cairo_bool_t
+_cairo_atomic_ptr_cmpxchg_impl(cairo_atomic_intptr_t *x, void *oldv, void *newv)
+{
+    void *expected = oldv;
+    return atomic_compare_exchange_strong_explicit (x, &expected, newv, memory_order_seq_cst, memory_order_seq_cst);
+}
+
+#define _cairo_atomic_ptr_cmpxchg(x, oldv, newv) \
+  _cairo_atomic_ptr_cmpxchg_impl(x, oldv, newv)
+
+static cairo_always_inline void *
+_cairo_atomic_ptr_cmpxchg_return_old_impl(cairo_atomic_intptr_t *x, void *oldv, void *newv)
+{
+    void *expected = oldv;
+    (void) atomic_compare_exchange_strong_explicit (x, &expected, newv, memory_order_seq_cst, memory_order_seq_cst);
+    return expected;
+}
+
+#define _cairo_atomic_ptr_cmpxchg_return_old(x, oldv, newv) \
+  _cairo_atomic_ptr_cmpxchg_return_old_impl(x, oldv, newv)
+
+#endif /* HAVE_C11_ATOMIC_PRIMITIVES */
+
 /* C++11 atomic primitives were designed to be more flexible than the
  * __sync_* family of primitives.  Despite the name, they are available
  * in C as well as C++.  The motivating reason for using them is that
@@ -62,55 +148,54 @@ CAIRO_BEGIN_DECLS
 #define HAS_ATOMIC_OPS 1
 
 typedef int cairo_atomic_int_t;
+typedef intptr_t cairo_atomic_intptr_t;
 
-static cairo_always_inline cairo_atomic_int_t
+static cairo_always_inline int
 _cairo_atomic_int_get (cairo_atomic_int_t *x)
 {
     return __atomic_load_n(x, __ATOMIC_SEQ_CST);
 }
 
-static cairo_always_inline cairo_atomic_int_t
+static cairo_always_inline int
 _cairo_atomic_int_get_relaxed (cairo_atomic_int_t *x)
 {
     return __atomic_load_n(x, __ATOMIC_RELAXED);
 }
 
 static cairo_always_inline void
-_cairo_atomic_int_set_relaxed (cairo_atomic_int_t *x, cairo_atomic_int_t val)
+_cairo_atomic_int_set_relaxed (cairo_atomic_int_t *x, int val)
 {
     __atomic_store_n(x, val, __ATOMIC_RELAXED);
 }
 
 static cairo_always_inline void *
-_cairo_atomic_ptr_get (void **x)
+_cairo_atomic_ptr_get (cairo_atomic_intptr_t *x)
 {
-    return __atomic_load_n(x, __ATOMIC_SEQ_CST);
+    return (void*)__atomic_load_n(x, __ATOMIC_SEQ_CST);
 }
 
 # define _cairo_atomic_int_inc(x) ((void) __atomic_fetch_add(x, 1, __ATOMIC_SEQ_CST))
 # define _cairo_atomic_int_dec(x) ((void) __atomic_fetch_sub(x, 1, __ATOMIC_SEQ_CST))
 # define _cairo_atomic_int_dec_and_test(x) (__atomic_fetch_sub(x, 1, __ATOMIC_SEQ_CST) == 1)
 
-typedef intptr_t cairo_atomic_intptr_t;
-
 static cairo_always_inline cairo_bool_t
 _cairo_atomic_int_cmpxchg_impl(cairo_atomic_int_t *x,
-			       cairo_atomic_int_t oldv,
-			       cairo_atomic_int_t newv)
+			       int                 oldv,
+			       int                 newv)
 {
-    cairo_atomic_int_t expected = oldv;
+    int expected = oldv;
     return __atomic_compare_exchange_n(x, &expected, newv, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
 }
 
 #define _cairo_atomic_int_cmpxchg(x, oldv, newv) \
   _cairo_atomic_int_cmpxchg_impl(x, oldv, newv)
 
-static cairo_always_inline cairo_atomic_int_t
+static cairo_always_inline int
 _cairo_atomic_int_cmpxchg_return_old_impl(cairo_atomic_int_t *x,
-					  cairo_atomic_int_t oldv,
-					  cairo_atomic_int_t newv)
+					  int                 oldv,
+					  int                 newv)
 {
-    cairo_atomic_int_t expected = oldv;
+    int expected = oldv;
     (void) __atomic_compare_exchange_n(x, &expected, newv, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
     return expected;
 }
@@ -119,7 +204,7 @@ _cairo_atomic_int_cmpxchg_return_old_impl(cairo_atomic_int_t *x,
   _cairo_atomic_int_cmpxchg_return_old_impl(x, oldv, newv)
 
 static cairo_always_inline cairo_bool_t
-_cairo_atomic_ptr_cmpxchg_impl(void **x, void *oldv, void *newv)
+_cairo_atomic_ptr_cmpxchg_impl(cairo_atomic_intptr_t *x, void *oldv, void *newv)
 {
     void *expected = oldv;
     return __atomic_compare_exchange_n(x, &expected, newv, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
@@ -129,7 +214,7 @@ _cairo_atomic_ptr_cmpxchg_impl(void **x, void *oldv, void *newv)
   _cairo_atomic_ptr_cmpxchg_impl(x, oldv, newv)
 
 static cairo_always_inline void *
-_cairo_atomic_ptr_cmpxchg_return_old_impl(void **x, void *oldv, void *newv)
+_cairo_atomic_ptr_cmpxchg_return_old_impl(cairo_atomic_intptr_t *x, void *oldv, void *newv)
 {
     void *expected = oldv;
     (void) __atomic_compare_exchange_n(x, &expected, newv, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
@@ -139,38 +224,39 @@ _cairo_atomic_ptr_cmpxchg_return_old_impl(void **x, void *oldv, void *newv)
 #define _cairo_atomic_ptr_cmpxchg_return_old(x, oldv, newv) \
   _cairo_atomic_ptr_cmpxchg_return_old_impl(x, oldv, newv)
 
-#endif
+#endif /* HAVE_CXX11_ATOMIC_PRIMITIVES */
 
 #if HAVE_GCC_LEGACY_ATOMICS
 
 #define HAS_ATOMIC_OPS 1
 
 typedef int cairo_atomic_int_t;
+typedef intptr_t cairo_atomic_intptr_t;
 
-static cairo_always_inline cairo_atomic_int_t
+static cairo_always_inline int
 _cairo_atomic_int_get (cairo_atomic_int_t *x)
 {
     __sync_synchronize ();
     return *x;
 }
 
-static cairo_always_inline cairo_atomic_int_t
+static cairo_always_inline int
 _cairo_atomic_int_get_relaxed (cairo_atomic_int_t *x)
 {
     return *x;
 }
 
 static cairo_always_inline void
-_cairo_atomic_int_set_relaxed (cairo_atomic_int_t *x, cairo_atomic_int_t val)
+_cairo_atomic_int_set_relaxed (cairo_atomic_int_t *x, int val)
 {
     *x = val;
 }
 
 static cairo_always_inline void *
-_cairo_atomic_ptr_get (void **x)
+_cairo_atomic_ptr_get (cairo_atomic_intptr_t *x)
 {
     __sync_synchronize ();
-    return *x;
+    return (void*)*x;
 }
 
 # define _cairo_atomic_int_inc(x) ((void) __sync_fetch_and_add(x, 1))
@@ -179,15 +265,13 @@ _cairo_atomic_ptr_get (void **x)
 # define _cairo_atomic_int_cmpxchg(x, oldv, newv) __sync_bool_compare_and_swap (x, oldv, newv)
 # define _cairo_atomic_int_cmpxchg_return_old(x, oldv, newv) __sync_val_compare_and_swap (x, oldv, newv)
 
-typedef intptr_t cairo_atomic_intptr_t;
-
 # define _cairo_atomic_ptr_cmpxchg(x, oldv, newv) \
     __sync_bool_compare_and_swap ((cairo_atomic_intptr_t*)x, (cairo_atomic_intptr_t)oldv, (cairo_atomic_intptr_t)newv)
 
 # define _cairo_atomic_ptr_cmpxchg_return_old(x, oldv, newv) \
     _cairo_atomic_intptr_to_voidptr (__sync_val_compare_and_swap ((cairo_atomic_intptr_t*)x, (cairo_atomic_intptr_t)oldv, (cairo_atomic_intptr_t)newv))
 
-#endif
+#endif /* HAVE_GCC_LEGACY_ATOMICS */
 
 #if HAVE_LIB_ATOMIC_OPS
 #include <atomic_ops.h>
@@ -219,6 +303,7 @@ typedef intptr_t cairo_atomic_intptr_t;
 #define HAS_ATOMIC_OPS 1
 
 typedef int32_t cairo_atomic_int_t;
+typedef intptr_t cairo_atomic_intptr_t;
 
 # define _cairo_atomic_int_get(x) (OSMemoryBarrier(), *(x))
 # define _cairo_atomic_int_get_relaxed(x) *(x)
@@ -229,8 +314,6 @@ typedef int32_t cairo_atomic_int_t;
 # define _cairo_atomic_int_dec_and_test(x) (OSAtomicDecrement32Barrier (x) == 0)
 # define _cairo_atomic_int_cmpxchg(x, oldv, newv) OSAtomicCompareAndSwap32Barrier(oldv, newv, x)
 
-typedef intptr_t cairo_atomic_intptr_t;
-
 #if SIZEOF_VOID_P==4
 # define _cairo_atomic_ptr_cmpxchg(x, oldv, newv) \
     OSAtomicCompareAndSwap32Barrier((cairo_atomic_intptr_t)oldv, (cairo_atomic_intptr_t)newv, (cairo_atomic_intptr_t *)x)
@@ -245,17 +328,17 @@ typedef intptr_t cairo_atomic_intptr_t;
 
 # define _cairo_atomic_ptr_get(x) (OSMemoryBarrier(), *(x))
 
-#endif
+#endif /* HAVE_OS_ATOMIC_OPS */
 
 #if !defined(HAS_ATOMIC_OPS) && defined(_WIN32)
 #include <windows.h>
 
 #define HAS_ATOMIC_OPS 1
 
-typedef int32_t cairo_atomic_int_t;
-typedef intptr_t cairo_atomic_intptr_t;
+typedef LONG cairo_atomic_int_t;
+typedef PVOID cairo_atomic_intptr_t;
 
-static cairo_always_inline cairo_atomic_int_t
+static cairo_always_inline int
 _cairo_atomic_int_get (cairo_atomic_int_t *x)
 {
     MemoryBarrier ();
@@ -265,33 +348,33 @@ _cairo_atomic_int_get (cairo_atomic_int_t *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 ((LONG*)x))
-# define _cairo_atomic_int_dec(x) ((void) InterlockedDecrement ((LONG*)x))
-# define _cairo_atomic_int_dec_and_test(x) (InterlockedDecrement ((LONG*)x) == 0)
+# 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)
+                           int                 oldv,
+                           int                 newv)
 {
-    return InterlockedCompareExchange ((LONG*)x, (LONG)newv, (LONG)oldv) == oldv;
+    return InterlockedCompareExchange (x, (LONG)newv, (LONG)oldv) == oldv;
 }
 
 static cairo_always_inline void *
-_cairo_atomic_ptr_get (void **x)
+_cairo_atomic_ptr_get (cairo_atomic_intptr_t *x)
 {
     MemoryBarrier ();
-    return *x;
+    return (void *) *x;
 }
 
 static cairo_always_inline cairo_bool_t
-_cairo_atomic_ptr_cmpxchg (void **x, void *oldv, void *newv)
+_cairo_atomic_ptr_cmpxchg (cairo_atomic_intptr_t *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)
+_cairo_atomic_ptr_cmpxchg_return_old (cairo_atomic_intptr_t *x, void *oldv, void *newv)
 {
     return InterlockedCompareExchangePointer (x, newv, oldv);
 }
@@ -312,24 +395,24 @@ _cairo_atomic_int_inc (cairo_atomic_int_t *x);
 cairo_private cairo_bool_t
 _cairo_atomic_int_dec_and_test (cairo_atomic_int_t *x);
 
-cairo_private cairo_atomic_int_t
-_cairo_atomic_int_cmpxchg_return_old_impl (cairo_atomic_int_t *x, cairo_atomic_int_t oldv, cairo_atomic_int_t newv);
+cairo_private int
+_cairo_atomic_int_cmpxchg_return_old_impl (cairo_atomic_int_t *x, int oldv, int newv);
 
 cairo_private void *
-_cairo_atomic_ptr_cmpxchg_return_old_impl (void **x, void *oldv, void *newv);
+_cairo_atomic_ptr_cmpxchg_return_old_impl (cairo_atomic_intptr_t *x, void *oldv, void *newv);
 
 #define _cairo_atomic_int_cmpxchg_return_old(x, oldv, newv) _cairo_atomic_int_cmpxchg_return_old_impl (x, oldv, newv)
 #define _cairo_atomic_ptr_cmpxchg_return_old(x, oldv, newv) _cairo_atomic_ptr_cmpxchg_return_old_impl (x, oldv, newv)
 
 #ifdef ATOMIC_OP_NEEDS_MEMORY_BARRIER
-cairo_private cairo_atomic_int_t
+cairo_private int
 _cairo_atomic_int_get (cairo_atomic_int_t *x);
-cairo_private cairo_atomic_int_t
+cairo_private int
 _cairo_atomic_int_get_relaxed (cairo_atomic_int_t *x);
 void
-_cairo_atomic_int_set_relaxed (cairo_atomic_int_t *x, cairo_atomic_int_t val);
+_cairo_atomic_int_set_relaxed (cairo_atomic_int_t *x, int val);
 cairo_private void*
-_cairo_atomic_ptr_get(void **x);
+_cairo_atomic_ptr_get(cairo_atomic_intptr_t *x);
 #else
 # define _cairo_atomic_int_get(x) (*x)
 # define _cairo_atomic_int_get_relaxed(x) (*x)
@@ -346,10 +429,10 @@ _cairo_atomic_intptr_to_voidptr (cairo_atomic_intptr_t x)
   return (void *) x;
 }
 
-static cairo_always_inline cairo_atomic_int_t
-_cairo_atomic_int_cmpxchg_return_old_fallback(cairo_atomic_int_t *x, cairo_atomic_int_t oldv, cairo_atomic_int_t newv)
+static cairo_always_inline int
+_cairo_atomic_int_cmpxchg_return_old_fallback(cairo_atomic_int_t *x, int oldv, int newv)
 {
-    cairo_atomic_int_t curr;
+    int curr;
 
     do {
         curr = _cairo_atomic_int_get (x);
@@ -359,7 +442,7 @@ _cairo_atomic_int_cmpxchg_return_old_fallback(cairo_atomic_int_t *x, cairo_atomi
 }
 
 static cairo_always_inline void *
-_cairo_atomic_ptr_cmpxchg_return_old_fallback(void **x, void *oldv, void *newv)
+_cairo_atomic_ptr_cmpxchg_return_old_fallback(cairo_atomic_intptr_t *x, void *oldv, void *newv)
 {
     void *curr;
 
diff --git a/src/cairo-atomic.c b/src/cairo-atomic.c
index 3c4d51972..26966d007 100644
--- a/src/cairo-atomic.c
+++ b/src/cairo-atomic.c
@@ -61,10 +61,10 @@ _cairo_atomic_int_dec_and_test (cairo_atomic_int_t *x)
     return ret;
 }
 
-cairo_atomic_int_t
-_cairo_atomic_int_cmpxchg_return_old_impl (cairo_atomic_int_t *x, cairo_atomic_int_t oldv, cairo_atomic_int_t newv)
+int
+_cairo_atomic_int_cmpxchg_return_old_impl (cairo_atomic_int_t *x, int oldv, int newv)
 {
-    cairo_atomic_int_t ret;
+    int ret;
 
     CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
     ret = *x;
@@ -76,24 +76,24 @@ _cairo_atomic_int_cmpxchg_return_old_impl (cairo_atomic_int_t *x, cairo_atomic_i
 }
 
 void *
-_cairo_atomic_ptr_cmpxchg_return_old_impl (void **x, void *oldv, void *newv)
+_cairo_atomic_ptr_cmpxchg_return_old_impl (cairo_atomic_intptr_t *x, void *oldv, void *newv)
 {
     void *ret;
 
     CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
-    ret = *x;
+    ret = (void *) *x;
     if (ret == oldv)
-	*x = newv;
+	*x = (cairo_atomic_intptr_t) newv;
     CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex);
 
     return ret;
 }
 
 #ifdef ATOMIC_OP_NEEDS_MEMORY_BARRIER
-cairo_atomic_int_t
+int
 _cairo_atomic_int_get (cairo_atomic_int_t *x)
 {
-    cairo_atomic_int_t ret;
+    int ret;
 
     CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
     ret = *x;
@@ -102,14 +102,14 @@ _cairo_atomic_int_get (cairo_atomic_int_t *x)
     return ret;
 }
 
-cairo_atomic_int_t
+int
 _cairo_atomic_int_get_relaxed (cairo_atomic_int_t *x)
 {
     return _cairo_atomic_int_get (x);
 }
 
 void
-_cairo_atomic_int_set_relaxed (cairo_atomic_int_t *x, cairo_atomic_int_t val)
+_cairo_atomic_int_set_relaxed (cairo_atomic_int_t *x, int val)
 {
     CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
     *x = val;
diff --git a/src/cairo-freed-pool-private.h b/src/cairo-freed-pool-private.h
index 8a7af523d..ced1adb3d 100644
--- a/src/cairo-freed-pool-private.h
+++ b/src/cairo-freed-pool-private.h
@@ -50,12 +50,12 @@ CAIRO_BEGIN_DECLS
  */
 #define MAX_FREED_POOL_SIZE 16
 typedef struct {
-    void *pool[MAX_FREED_POOL_SIZE];
+    cairo_atomic_intptr_t pool[MAX_FREED_POOL_SIZE];
     cairo_atomic_int_t top;
 } freed_pool_t;
 
 static cairo_always_inline void *
-_atomic_fetch (void **slot)
+_atomic_fetch (cairo_atomic_intptr_t *slot)
 {
     void *ptr;
 
@@ -67,7 +67,7 @@ _atomic_fetch (void **slot)
 }
 
 static cairo_always_inline cairo_bool_t
-_atomic_store (void **slot, void *ptr)
+_atomic_store (cairo_atomic_intptr_t *slot, void *ptr)
 {
     return _cairo_atomic_ptr_cmpxchg (slot, NULL, ptr);
 }
diff --git a/src/cairo-freed-pool.c b/src/cairo-freed-pool.c
index 5b1c4c0bb..6d46ab1c1 100644
--- a/src/cairo-freed-pool.c
+++ b/src/cairo-freed-pool.c
@@ -83,8 +83,7 @@ _freed_pool_reset (freed_pool_t *pool)
     int i;
 
     for (i = 0; i < ARRAY_LENGTH (pool->pool); i++) {
-	free (pool->pool[i]);
-	pool->pool[i] = NULL;
+	free (_atomic_fetch (&pool->pool[i]));
     }
 
     _cairo_atomic_int_set_relaxed (&pool->top, 0);
diff --git a/src/cairo-misc.c b/src/cairo-misc.c
index 6e3189740..23e3eaf0b 100644
--- a/src/cairo-misc.c
+++ b/src/cairo-misc.c
@@ -803,12 +803,12 @@ get_C_locale (void)
     locale_t C;
 
 retry:
-    C = (locale_t) _cairo_atomic_ptr_get ((void **) &C_locale);
+    C = (locale_t) _cairo_atomic_ptr_get ((cairo_atomic_intptr_t *) &C_locale);
 
     if (unlikely (!C)) {
         C = newlocale (LC_ALL_MASK, "C", NULL);
 
-        if (!_cairo_atomic_ptr_cmpxchg ((void **) &C_locale, NULL, C)) {
+        if (!_cairo_atomic_ptr_cmpxchg ((cairo_atomic_intptr_t *) &C_locale, NULL, C)) {
             freelocale (C_locale);
             goto retry;
         }
diff --git a/src/cairo-mutex-private.h b/src/cairo-mutex-private.h
index 65732a180..6b3eb0365 100644
--- a/src/cairo-mutex-private.h
+++ b/src/cairo-mutex-private.h
@@ -53,9 +53,15 @@ cairo_private void _cairo_mutex_finalize (void);
 #endif
 /* only if using static initializer and/or finalizer define the boolean */
 #if _CAIRO_MUTEX_IMPL_USE_STATIC_INITIALIZER || _CAIRO_MUTEX_IMPL_USE_STATIC_FINALIZER
+
+#if HAS_ATOMIC_OPS
+  cairo_private extern cairo_atomic_int_t _cairo_mutex_initialized;
+#else
   cairo_private extern int _cairo_mutex_initialized;
 #endif
 
+#endif
+
 /* Finally, extern the static mutexes and undef */
 
 #define CAIRO_MUTEX_DECLARE(mutex) cairo_private extern cairo_mutex_t mutex;
diff --git a/src/cairo-mutex.c b/src/cairo-mutex.c
index 5b6debeca..89acad525 100644
--- a/src/cairo-mutex.c
+++ b/src/cairo-mutex.c
@@ -51,7 +51,11 @@
 #  define _CAIRO_MUTEX_IMPL_INITIALIZED_DEFAULT_VALUE _CAIRO_MUTEX_INITIALIZED
 # endif
 
+#if HAS_ATOMIC_OPS
+cairo_atomic_int_t _cairo_mutex_initialized = _CAIRO_MUTEX_IMPL_INITIALIZED_DEFAULT_VALUE;
+#else
 int _cairo_mutex_initialized = _CAIRO_MUTEX_IMPL_INITIALIZED_DEFAULT_VALUE;
+#endif
 
 # undef _CAIRO_MUTEX_IMPL_INITIALIZED_DEFAULT_VALUE
 
diff --git a/src/cairo-recording-surface.c b/src/cairo-recording-surface.c
index e2f74e905..59428c8a4 100644
--- a/src/cairo-recording-surface.c
+++ b/src/cairo-recording-surface.c
@@ -1735,7 +1735,7 @@ _cairo_recording_surface_regions_allocate_unique_id (void)
 	unique_id = 1;
     return unique_id;
 #else
-    cairo_atomic_int_t old, id;
+    int old, id;
 
     do {
 	old = _cairo_atomic_uint_get (&unique_id);
diff --git a/src/cairo-reference-count-private.h b/src/cairo-reference-count-private.h
index 75fdf3538..f19125c61 100644
--- a/src/cairo-reference-count-private.h
+++ b/src/cairo-reference-count-private.h
@@ -52,7 +52,7 @@ typedef struct {
 
 #define CAIRO_REFERENCE_COUNT_GET_VALUE(RC) _cairo_atomic_int_get (&(RC)->ref_count)
 
-#define CAIRO_REFERENCE_COUNT_INVALID_VALUE ((cairo_atomic_int_t) -1)
+#define CAIRO_REFERENCE_COUNT_INVALID_VALUE ((int) -1)
 #define CAIRO_REFERENCE_COUNT_INVALID {CAIRO_REFERENCE_COUNT_INVALID_VALUE}
 
 #define CAIRO_REFERENCE_COUNT_IS_INVALID(RC) (CAIRO_REFERENCE_COUNT_GET_VALUE (RC) == CAIRO_REFERENCE_COUNT_INVALID_VALUE)
diff --git a/src/cairo-surface.c b/src/cairo-surface.c
index 657146790..a8117d699 100644
--- a/src/cairo-surface.c
+++ b/src/cairo-surface.c
@@ -277,7 +277,7 @@ _cairo_surface_allocate_unique_id (void)
 	unique_id = 1;
     return unique_id;
 #else
-    cairo_atomic_int_t old, id;
+    int old, id;
 
     do {
 	old = _cairo_atomic_uint_get (&unique_id);
diff --git a/src/win32/cairo-win32-device.c b/src/win32/cairo-win32-device.c
index 781ee0cde..6032ce7d9 100644
--- a/src/win32/cairo-win32-device.c
+++ b/src/win32/cairo-win32-device.c
@@ -136,7 +136,7 @@ _cairo_win32_device_get (void)
     device->msimg32_dll = NULL;
     device->alpha_blend = _cairo_win32_device_get_alpha_blend (device);
 
-    if (_cairo_atomic_ptr_cmpxchg ((void **)&__cairo_win32_device, NULL, device))
+    if (_cairo_atomic_ptr_cmpxchg ((cairo_atomic_intptr_t *)&__cairo_win32_device, NULL, device))
 	return cairo_device_reference(&device->base);
 
     _cairo_win32_device_destroy (device);
commit 8d0650bb60076807338cad84e7c50be436d026a3
Author: Adrian Johnson <ajohnson at redneon.com>
Date:   Sun May 28 07:24:36 2023 +0930

    Use intptr_t for cairo_atomic_intptr_t
    
    Since we now require C11 we can use intptr_t instead of figuring out
    the right int size.

diff --git a/src/cairo-atomic-private.h b/src/cairo-atomic-private.h
index 89556ef7f..dd49e618b 100644
--- a/src/cairo-atomic-private.h
+++ b/src/cairo-atomic-private.h
@@ -45,12 +45,6 @@
 
 #include <assert.h>
 
-/* The autoconf on OpenBSD 4.5 produces the malformed constant name
- * SIZEOF_VOID__ rather than SIZEOF_VOID_P.  Work around that here. */
-#if !defined(SIZEOF_VOID_P) && defined(SIZEOF_VOID__)
-# define SIZEOF_VOID_P SIZEOF_VOID__
-#endif
-
 CAIRO_BEGIN_DECLS
 
 /* C++11 atomic primitives were designed to be more flexible than the
@@ -97,15 +91,7 @@ _cairo_atomic_ptr_get (void **x)
 # define _cairo_atomic_int_dec(x) ((void) __atomic_fetch_sub(x, 1, __ATOMIC_SEQ_CST))
 # define _cairo_atomic_int_dec_and_test(x) (__atomic_fetch_sub(x, 1, __ATOMIC_SEQ_CST) == 1)
 
-#if SIZEOF_VOID_P==SIZEOF_INT
-typedef int cairo_atomic_intptr_t;
-#elif SIZEOF_VOID_P==SIZEOF_LONG
-typedef long cairo_atomic_intptr_t;
-#elif SIZEOF_VOID_P==SIZEOF_LONG_LONG
-typedef long long cairo_atomic_intptr_t;
-#else
-#error No matching integer pointer type
-#endif
+typedef intptr_t cairo_atomic_intptr_t;
 
 static cairo_always_inline cairo_bool_t
 _cairo_atomic_int_cmpxchg_impl(cairo_atomic_int_t *x,
@@ -193,15 +179,7 @@ _cairo_atomic_ptr_get (void **x)
 # define _cairo_atomic_int_cmpxchg(x, oldv, newv) __sync_bool_compare_and_swap (x, oldv, newv)
 # define _cairo_atomic_int_cmpxchg_return_old(x, oldv, newv) __sync_val_compare_and_swap (x, oldv, newv)
 
-#if SIZEOF_VOID_P==SIZEOF_INT
-typedef int cairo_atomic_intptr_t;
-#elif SIZEOF_VOID_P==SIZEOF_LONG
-typedef long cairo_atomic_intptr_t;
-#elif SIZEOF_VOID_P==SIZEOF_LONG_LONG
-typedef long long cairo_atomic_intptr_t;
-#else
-#error No matching integer pointer type
-#endif
+typedef intptr_t cairo_atomic_intptr_t;
 
 # define _cairo_atomic_ptr_cmpxchg(x, oldv, newv) \
     __sync_bool_compare_and_swap ((cairo_atomic_intptr_t*)x, (cairo_atomic_intptr_t)oldv, (cairo_atomic_intptr_t)newv)
@@ -227,15 +205,7 @@ typedef  AO_t cairo_atomic_int_t;
 # define _cairo_atomic_int_dec_and_test(x) (AO_fetch_and_sub1_full(x) == 1)
 # define _cairo_atomic_int_cmpxchg(x, oldv, newv) AO_compare_and_swap_full(x, oldv, newv)
 
-#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
+typedef intptr_t cairo_atomic_intptr_t;
 
 # define _cairo_atomic_ptr_get(x) _cairo_atomic_intptr_to_voidptr (AO_load_full (x))
 # define _cairo_atomic_ptr_cmpxchg(x, oldv, newv) \
@@ -259,13 +229,13 @@ typedef int32_t cairo_atomic_int_t;
 # define _cairo_atomic_int_dec_and_test(x) (OSAtomicDecrement32Barrier (x) == 0)
 # define _cairo_atomic_int_cmpxchg(x, oldv, newv) OSAtomicCompareAndSwap32Barrier(oldv, newv, x)
 
+typedef intptr_t cairo_atomic_intptr_t;
+
 #if SIZEOF_VOID_P==4
-typedef int32_t cairo_atomic_intptr_t;
 # define _cairo_atomic_ptr_cmpxchg(x, oldv, newv) \
     OSAtomicCompareAndSwap32Barrier((cairo_atomic_intptr_t)oldv, (cairo_atomic_intptr_t)newv, (cairo_atomic_intptr_t *)x)
 
 #elif SIZEOF_VOID_P==8
-typedef int64_t cairo_atomic_intptr_t;
 # define _cairo_atomic_ptr_cmpxchg(x, oldv, newv) \
     OSAtomicCompareAndSwap64Barrier((cairo_atomic_intptr_t)oldv, (cairo_atomic_intptr_t)newv, (cairo_atomic_intptr_t *)x)
 
@@ -283,16 +253,7 @@ typedef int64_t cairo_atomic_intptr_t;
 #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
+typedef intptr_t cairo_atomic_intptr_t;
 
 static cairo_always_inline cairo_atomic_int_t
 _cairo_atomic_int_get (cairo_atomic_int_t *x)
@@ -341,16 +302,7 @@ _cairo_atomic_ptr_cmpxchg_return_old (void **x, void *oldv, void *newv)
 #ifndef HAS_ATOMIC_OPS
 
 typedef int 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
+typedef intptr_t cairo_atomic_intptr_t;
 
 cairo_private void
 _cairo_atomic_int_inc (cairo_atomic_int_t *x);


More information about the cairo-commit mailing list