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__) && ( (__GNUC__ > 4) || ((__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1)) )) || defined(_MSC_VER) || defined(_WIN32) || defined(__APPLE__) || defined(AO_HAVE_compare_and_swap_full)
00035 # define EQ_HAS_COMPARE_AND_SWAP
00036
00038 inline void memoryBarrier()
00039 {
00040 #if defined(__GNUC__) && ( (__GNUC__ > 4) || ((__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1)) )
00041 __sync_synchronize();
00042 #elif defined(_MSC_VER) && (_MSC_VER >= 1300)
00043 _ReadWriteBarrier();
00044 #elif defined(__APPLE__)
00045 OSMemoryBarrier();
00046 #elif defined(AO_HAVE_nop_full)
00047 AO_nop_full();
00048 #elif defined( __PPC__ )
00049 asm volatile("sync":::"memory");
00050 #elif defined( __i386__ ) || defined( __i486__ ) || defined( __i586__ ) || defined( __i686__ ) || defined( __x86_64__ )
00051 asm volatile("mfence":::"memory");
00052 #else
00053 # warning "no memory barrier implemented for this platform"
00054 #endif
00055 }
00056
00061 template <class C, class D>
00062 inline bool compareAndSwap(volatile C * addr, D old, D nw)
00063 {
00064 #if defined(__GNUC__) && ( (__GNUC__ > 4) || ((__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1)) )
00065 return __sync_bool_compare_and_swap(addr, old, nw);
00066 #elif defined(_MSC_VER)
00067 return _InterlockedCompareExchange(addr,nw,old) == old;
00068 #elif defined(_WIN32)
00069 return InterlockedCompareExchange(addr,nw,old) == old;
00070 #elif defined(__APPLE__)
00071 return OSAtomicCompareAndSwap32((int32_t) old, (int32_t)nw, (int32_t*)addr);
00072 #elif defined(AO_HAVE_compare_and_swap_full)
00073 return AO_compare_and_swap_full(reinterpret_cast<volatile AO_t*>(addr),
00074 reinterpret_cast<AO_t>(old),
00075 reinterpret_cast<AO_t>(nw));
00076 #else
00077 # warning ("CompareAndSwap emulation")
00078 # include <eq/base/lock.h>
00079 # include <eq/base/scopedMutex.h>
00080
00081 static Lock guard;
00082 ScopedMutex lock(guard);
00083
00084 if (*addr == old)
00085 {
00086 *addr = nw;
00087 return true;
00088 }
00089 else
00090 return false;
00091 #endif
00092 }
00093
00094 #endif
00095 }
00096
00097 }
00098 #endif // EQBASE_COMPAREANDSWAP_H