Open GoogleCodeExporter opened 9 years ago
We want compare and swap with a pointer.
First, distinguish between Apache 1.3 and Apache 2.
Apache 1.3 is single-threaded, so the implementation is trivial.
On Apache 2, check the platform.
On Mac, include OSAtomic.h and use OSAtomicCompareAndSwap32 or
OSAtomicCompareAndSwap64,
depending on the size of a pointer.
On Solaris, include atomic.h and use atomic_cas_ptr().
On other platforms, you can use APR. Of special interest, of course, is linux
x86. APR's implementation looks
like this:
#if (defined(__linux__) || defined(__EMX__)) && defined(__i386__) &&
!APR_FORCE_ATOMIC_GENERIC
#define apr_atomic_cas(mem,with,cmp) \
({ apr_atomic_t prev; \
asm volatile ("lock; cmpxchgl %1, %2" \
: "=a" (prev) \
: "r" (with), "m" (*(mem)), "0"(cmp) \
: "memory"); \
prev;})
Another implementation on x86_64 looks like this -- it uses cmpxchgq instead of
cmpxchgl:
/* Returns nonzero if the comparison succeeded. */
AO_INLINE int
AO_compare_and_swap_full(volatile AO_t *addr,
AO_t old, AO_t new_val)
{
char result;
__asm__ __volatile__("lock; cmpxchgq %3, %0; setz %1"
: "=m"(*addr), "=q"(result)
: "m"(*addr), "r" (new_val), "a"(old) : "memory");
return (int) result;
}
There's an implementation in MySQL 5.1 my_atomic.h along these lines:
#define make_atomic_cas_body(S) \
asm volatile (LOCK "; cmpxchg %3, %0; setz %2;" \
: "+m" (*a), "+a" (*cmp), "=q" (ret): "r" (set))
Original comment by john.david.duncan
on 27 Oct 2007 at 12:10
On Mac, OSAtomic.h was introduced in 10.4. But *all* OS X releases provide
CompareAndSwap() in
CarbonCore/DriverSynchronization.h in the CoreServices framework.
Original comment by john.david.duncan
on 28 Oct 2007 at 7:55
Original comment by john.david.duncan
on 28 Dec 2007 at 5:07
Does gcc provide __sync_val_compare_and_swap() on all platforms?
Original comment by john.david.duncan
on 21 Apr 2008 at 5:32
__sync_val_compare_and_swap() is supported beginning with GCC 4.1.0.
See: http://gcc.gnu.org/onlinedocs/gcc-4.1.0/gcc/Atomic-Builtins.html
Original comment by john.david.duncan
on 21 Apr 2008 at 5:44
Original issue reported on code.google.com by
john.david.duncan
on 26 Oct 2007 at 11:13