summaryrefslogtreecommitdiff
path: root/src/cairo-atomic-private.h
diff options
context:
space:
mode:
authorM Joonas Pihlaja <jpihlaja@cc.helsinki.fi>2009-06-21 14:02:46 +0100
committerM Joonas Pihlaja <jpihlaja@cc.helsinki.fi>2009-06-21 17:34:12 +0300
commit80990c7f729a666fc646182a36ffd311d7396a1a (patch)
treece67c289795d9459a67a6effe3b3dae8bba1d961 /src/cairo-atomic-private.h
parentd0c1c9282164bffb76f7419873e93608dc6d9876 (diff)
[atomic] Use an integer __sync_val_compare_and_swap() for pointer CAS.
Fix an implicit pointer/integer cast in _cairo_atomic_ptr_cmpxchg() when building with LLVM/clang. The Intel synchronization primitives __sync_val_compare_and_swap() are only defined by Intel for types int, long, long long and their unsigned variants. This patch uses one of those for _cairo_atomic_ptr_cmpxchg() instead of relying on a gcc extension of __sync_val_compare_and_swap() to pointer types.
Diffstat (limited to 'src/cairo-atomic-private.h')
-rw-r--r--src/cairo-atomic-private.h9
1 files changed, 8 insertions, 1 deletions
diff --git a/src/cairo-atomic-private.h b/src/cairo-atomic-private.h
index 108cb39c..10860fe1 100644
--- a/src/cairo-atomic-private.h
+++ b/src/cairo-atomic-private.h
@@ -54,8 +54,15 @@ typedef int cairo_atomic_int_t;
# 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)
-# define _cairo_atomic_ptr_cmpxchg(x, oldv, newv) __sync_val_compare_and_swap (x, oldv, newv)
+# define _cairo_atomic_ptr_cmpxchg(x, oldv, newv) \
+ (sizeof(void*) == sizeof(int) ?\
+ (void*)__sync_val_compare_and_swap ((int*)x, (int)oldv, (int)newv) :\
+ sizeof(void*) == sizeof(long) ?\
+ (void*)__sync_val_compare_and_swap ((long*)x, (long)oldv, (long)newv) :\
+ sizeof(void*) == sizeof(long long) ?\
+ (void*)__sync_val_compare_and_swap ((long long*)x, (long long)oldv, (long long)newv) :\
+ (void*)(oldv)/*impossible*/)
#endif