[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.
This commit is contained in:
M Joonas Pihlaja 2009-06-21 14:02:46 +01:00
parent d0c1c92821
commit 80990c7f72
2 changed files with 13 additions and 2 deletions

View file

@ -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

View file

@ -36,7 +36,11 @@
#include "cairo-atomic-private.h"
#include "cairo-mutex-private.h"
#ifndef HAS_ATOMIC_OPS
#ifdef HAS_ATOMIC_OPS
COMPILE_TIME_ASSERT(sizeof(void*) == sizeof(int) ||
sizeof(void*) == sizeof(long) ||
sizeof(void*) == sizeof(long long));
#else
void
_cairo_atomic_int_inc (int *x)
{