dannote / mod-ndb

Automatically exported from code.google.com/p/mod-ndb
0 stars 0 forks source link

compare and swap #50

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
As part of the lock-free design of mod_ndb, an atomic compare_and_swap() 
function is needed.

Original issue reported on code.google.com by john.david.duncan on 26 Oct 2007 at 11:13

GoogleCodeExporter commented 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

GoogleCodeExporter commented 9 years ago
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

GoogleCodeExporter commented 9 years ago

Original comment by john.david.duncan on 28 Dec 2007 at 5:07

GoogleCodeExporter commented 9 years ago
Does gcc provide __sync_val_compare_and_swap() on all platforms?

Original comment by john.david.duncan on 21 Apr 2008 at 5:32

GoogleCodeExporter commented 9 years ago
__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