Equalizer 1.0
|
00001 00002 // Copyright (C) 2007, 2008 Tim Blechmann & Thomas Grill 00003 // 00004 // Distributed under the Boost Software License, Version 1.0. (See 00005 // accompanying file LICENSE_1_0.txt or copy at 00006 // http://www.boost.org/LICENSE_1_0.txt) 00007 00008 // Disclaimer: Not a Boost library. 00009 00010 /* Copyright (c) 2008-2011, Stefan Eilemann <eile@equalizergraphics.com> 00011 Modifications to use within co::base namespace and naming conventions. 00012 Original at http://tim.klingt.org/git?p=boost_lockfree.git;a=tree 00013 */ 00014 00015 #ifndef COBASE_COMPAREANDSWAP_H 00016 #define COBASE_COMPAREANDSWAP_H 00017 00018 #if defined(_MSC_VER) && (_MSC_VER >= 1300) 00019 # include <intrin.h> 00020 # pragma intrinsic(_ReadWriteBarrier) 00021 #endif 00022 00023 #ifdef Darwin 00024 # include <libkern/OSAtomic.h> 00025 #endif 00026 00027 namespace co 00028 { 00029 namespace base 00030 { 00031 00032 #if (defined(__GNUC__) && \ 00033 ( (__GNUC__ > 4) || ((__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1)) )) || \ 00034 defined(_MSC_VER) || defined(_WIN32) || defined(__APPLE__) || \ 00035 defined(AO_HAVE_compare_and_swap_full) 00036 # define EQ_HAS_COMPARE_AND_SWAP 00037 00039 inline void memoryBarrier() 00040 { 00041 #if defined(__GNUC__) && \ 00042 ( (__GNUC__ > 4) || ((__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1)) ) 00043 __sync_synchronize(); 00044 #elif defined(_MSC_VER) && (_MSC_VER >= 1300) 00045 _ReadWriteBarrier(); 00046 #elif defined(__APPLE__) 00047 OSMemoryBarrier(); 00048 #elif defined(AO_HAVE_nop_full) 00049 AO_nop_full(); 00050 #elif defined( __PPC__ ) 00051 asm volatile("sync":::"memory"); 00052 #elif defined( __i386__ ) || defined( __i486__ ) || defined( __i586__ ) || \ 00053 defined( __i686__ ) || defined( __x86_64__ ) 00054 asm volatile("mfence":::"memory"); 00055 #else 00056 # warning "no memory barrier implemented for this platform" 00057 #endif 00058 } 00059 00065 template <class D> 00066 inline bool compareAndSwap(long * addr, D old, D nw) 00067 { 00068 #if defined(__GNUC__) && \ 00069 ( (__GNUC__ > 4) || ((__GNUC__ >= 4) && (__GNUC_MINOR__ >= 1)) ) 00070 return __sync_bool_compare_and_swap(addr, old, nw); 00071 #elif defined(_MSC_VER) 00072 return _InterlockedCompareExchange(addr,nw,old) == old; 00073 #elif defined(_WIN32) 00074 return InterlockedCompareExchange(addr,nw,old) == old; 00075 #elif defined(__APPLE__) 00076 return OSAtomicCompareAndSwap32((int32_t) old, (int32_t)nw, (int32_t*)addr); 00077 #elif defined(AO_HAVE_compare_and_swap_full) 00078 return AO_compare_and_swap_full(reinterpret_cast<volatile AO_t*>(addr), 00079 reinterpret_cast<AO_t>(old), 00080 reinterpret_cast<AO_t>(nw)); 00081 #else 00082 # warning ("CompareAndSwap emulation") 00083 # include <co/base/lock.h> // used in inline function 00084 # include <co/base/scopedMutex.h> // used in inline function 00085 00086 static Lock guard; 00087 ScopedMutex lock(guard); 00088 00089 if (*addr == old) 00090 { 00091 *addr = nw; 00092 return true; 00093 } 00094 else 00095 return false; 00096 #endif 00097 } 00098 00099 #endif 00100 } 00101 00102 } 00103 #endif // COBASE_COMPAREANDSWAP_H