summaryrefslogtreecommitdiff
path: root/src/cairo-atomic-private.h
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2009-10-13 16:10:39 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2009-10-15 13:05:46 +0100
commitef9286751d8346ecb803bfb5916581ee4dfc84db (patch)
tree2e78392a19f1a0a2d07fb8408b85e4f98ac58cfe /src/cairo-atomic-private.h
parentd85eda97dd9116f51e0255b29652f4b52ba4f8e9 (diff)
downloadcairo-ef9286751d8346ecb803bfb5916581ee4dfc84db.tar.gz
[atomic] Fallback to libatomic-ops-dev
Use libatomic-ops-dev in preference to mutex-based atomics, if we do not have the builtin atomic intrinsics available.
Diffstat (limited to 'src/cairo-atomic-private.h')
-rw-r--r--src/cairo-atomic-private.h41
1 files changed, 36 insertions, 5 deletions
diff --git a/src/cairo-atomic-private.h b/src/cairo-atomic-private.h
index bf79b7a99..d2583a17a 100644
--- a/src/cairo-atomic-private.h
+++ b/src/cairo-atomic-private.h
@@ -57,6 +57,9 @@ CAIRO_BEGIN_DECLS
typedef int cairo_atomic_int_t;
+# define _cairo_atomic_int_get(x) (*x)
+# define _cairo_atomic_int_set(x, value) ((*x) = value)
+
# define _cairo_atomic_int_inc(x) ((void) __sync_fetch_and_add(x, 1))
# define _cairo_atomic_int_dec_and_test(x) (__sync_fetch_and_add(x, -1) == 1)
# define _cairo_atomic_int_cmpxchg(x, oldv, newv) __sync_val_compare_and_swap (x, oldv, newv)
@@ -76,6 +79,35 @@ typedef long long cairo_atomic_intptr_t;
#endif
+#if HAVE_LIB_ATOMIC_OPS
+#include <atomic_ops.h>
+
+#define HAS_ATOMIC_OPS 1
+
+typedef AO_t cairo_atomic_int_t;
+
+# define _cairo_atomic_int_get(x) (AO_load_full (x))
+# define _cairo_atomic_int_set(x, value) (AO_store_full (x))
+
+# define _cairo_atomic_int_inc(x) ((void) AO_fetch_and_add1_full(x))
+# define _cairo_atomic_int_dec_and_test(x) (AO_fetch_and_sub1_full(x) == 1)
+# define _cairo_atomic_int_cmpxchg(x, oldv, newv) ((cairo_atomic_int_t) 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
+
+# define _cairo_atomic_ptr_cmpxchg(x, oldv, newv) \
+ (void*) (cairo_atomic_intptr_t) _cairo_atomic_int_cmpxchg ((cairo_atomic_intptr_t*)(x), (cairo_atomic_intptr_t)oldv, (cairo_atomic_intptr_t)newv)
+
+#endif
+
#ifndef HAS_ATOMIC_OPS
@@ -93,9 +125,6 @@ _cairo_atomic_int_cmpxchg (int *x, int oldv, int newv);
cairo_private void *
_cairo_atomic_ptr_cmpxchg (void **x, void *oldv, void *newv);
-#endif
-
-
#ifdef ATOMIC_OP_NEEDS_MEMORY_BARRIER
# include "cairo-compiler-private.h"
@@ -113,14 +142,16 @@ _cairo_atomic_int_set (int *x, int value);
#endif
+#endif
+
#define _cairo_atomic_uint_get(x) _cairo_atomic_int_get(x)
#define _cairo_atomic_uint_cmpxchg(x, oldv, newv) \
- _cairo_atomic_int_cmpxchg((int *)x, oldv, newv)
+ _cairo_atomic_int_cmpxchg((cairo_atomic_int_t *)x, oldv, newv)
#define _cairo_status_set_error(status, err) do { \
/* hide compiler warnings about cairo_status_t != int (gcc treats its as \
* an unsigned integer instead, and about ignoring the return value. */ \
- int ret__ = _cairo_atomic_int_cmpxchg ((int *) status, CAIRO_STATUS_SUCCESS, err); \
+ int ret__ = _cairo_atomic_int_cmpxchg ((cairo_atomic_int_t *) status, CAIRO_STATUS_SUCCESS, err); \
(void) ret__; \
} while (0)