compareAndSwap.h
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef EQBASE_COMPAREANDSWAP_H
00016 #define EQBASE_COMPAREANDSWAP_H
00017
00018 #include <eq/base/base.h>
00019
00020 #if defined(_MSC_VER) && (_MSC_VER >= 1300)
00021 # include <intrin.h>
00022 # pragma intrinsic(_ReadWriteBarrier)
00023 #endif
00024
00025 #ifdef Darwin
00026 # include <libkern/OSAtomic.h>
00027 #endif
00028
00029 namespace eq
00030 {
00031 namespace base
00032 {
00033
00034 #if (defined(__GNUC__) && \
00035 ( (__GNUC__ > 4) || ((__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1)) )) || \
00036 defined(_MSC_VER) || defined(_WIN32) || defined(__APPLE__) || \
00037 defined(AO_HAVE_compare_and_swap_full)
00038 # define EQ_HAS_COMPARE_AND_SWAP
00039
00041 inline void memoryBarrier()
00042 {
00043 #if defined(__GNUC__) && \
00044 ( (__GNUC__ > 4) || ((__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1)) )
00045 __sync_synchronize();
00046 #elif defined(_MSC_VER) && (_MSC_VER >= 1300)
00047 _ReadWriteBarrier();
00048 #elif defined(__APPLE__)
00049 OSMemoryBarrier();
00050 #elif defined(AO_HAVE_nop_full)
00051 AO_nop_full();
00052 #elif defined( __PPC__ )
00053 asm volatile("sync":::"memory");
00054 #elif defined( __i386__ ) || defined( __i486__ ) || defined( __i586__ ) || \
00055 defined( __i686__ ) || defined( __x86_64__ )
00056 asm volatile("mfence":::"memory");
00057 #else
00058 # warning "no memory barrier implemented for this platform"
00059 #endif
00060 }
00061
00067 template <class C, class D>
00068 inline bool compareAndSwap(volatile C * addr, D old, D nw)
00069 {
00070 #if defined(__GNUC__) && \
00071 ( (__GNUC__ > 4) || ((__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1)) )
00072 return __sync_bool_compare_and_swap(addr, old, nw);
00073 #elif defined(_MSC_VER)
00074 return _InterlockedCompareExchange(addr,nw,old) == old;
00075 #elif defined(_WIN32)
00076 return InterlockedCompareExchange(addr,nw,old) == old;
00077 #elif defined(__APPLE__)
00078 return OSAtomicCompareAndSwap32((int32_t) old, (int32_t)nw, (int32_t*)addr);
00079 #elif defined(AO_HAVE_compare_and_swap_full)
00080 return AO_compare_and_swap_full(reinterpret_cast<volatile AO_t*>(addr),
00081 reinterpret_cast<AO_t>(old),
00082 reinterpret_cast<AO_t>(nw));
00083 #else
00084 # warning ("CompareAndSwap emulation")
00085 # include <eq/base/lock.h>
00086 # include <eq/base/scopedMutex.h>
00087
00088 static Lock guard;
00089 ScopedMutex lock(guard);
00090
00091 if (*addr == old)
00092 {
00093 *addr = nw;
00094 return true;
00095 }
00096 else
00097 return false;
00098 #endif
00099 }
00100
00101 #endif
00102 }
00103
00104 }
00105 #endif // EQBASE_COMPAREANDSWAP_H