Equalizer 1.0

compareAndSwap.h

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
Generated on Sun May 8 2011 19:11:05 for Equalizer 1.0 by  doxygen 1.7.3