diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2009-10-13 16:10:39 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2009-10-15 13:05:46 +0100 |
commit | ef9286751d8346ecb803bfb5916581ee4dfc84db (patch) | |
tree | 2e78392a19f1a0a2d07fb8408b85e4f98ac58cfe /src/cairo-atomic-private.h | |
parent | d85eda97dd9116f51e0255b29652f4b52ba4f8e9 (diff) | |
download | cairo-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.h | 41 |
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) |