X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fstructure%2FSGAtomic.hxx;h=d4611d11c078c0e8c5ef3cbb6332d68047d7ffad;hb=b9a34b1b05ce9cab1b4b67816d7d24bd2bc364b7;hp=29c23c2511ddfe631264573a385e1e0a573c4e91;hpb=8bd903dd96a39b8b8d9e4dfb399eb91cb4ce94c7;p=simgear.git diff --git a/simgear/structure/SGAtomic.hxx b/simgear/structure/SGAtomic.hxx index 29c23c25..d4611d11 100644 --- a/simgear/structure/SGAtomic.hxx +++ b/simgear/structure/SGAtomic.hxx @@ -1,6 +1,6 @@ /* -*-c++-*- * - * Copyright (C) 2005-2006 Mathias Froehlich + * Copyright (C) 2005-2009 Mathias Froehlich * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -28,7 +28,7 @@ #elif defined(__sgi) && defined(_COMPILER_VERSION) && (_COMPILER_VERSION>=730) // No need to include something. Is a Compiler API ... # define SGATOMIC_USE_MIPSPRO_BUILTINS -#elif defined(WIN32) +#elif defined(_WIN32) # include # define SGATOMIC_USE_WIN32_INTERLOCKED #else @@ -81,7 +81,25 @@ public: SGGuard lock(mMutex); return mValue; #endif - } + } + + bool compareAndExchange(unsigned oldValue, unsigned newValue) + { +#if defined(SGATOMIC_USE_GCC4_BUILTINS) + return __sync_bool_compare_and_swap(&mValue, oldValue, newValue); +#elif defined(SGATOMIC_USE_MIPOSPRO_BUILTINS) + return __compare_and_swap(&mValue, oldValue, newValue); +#elif defined(SGATOMIC_USE_WIN32_INTERLOCKED) + long volatile* lvPtr = reinterpret_cast(&mValue); + return oldValue == InterlockedCompareExchange(lvPtr, newValue, oldValue); +#else + SGGuard lock(mMutex); + if (mValue != oldValue) + return false; + mValue = newValue; + return true; +#endif + } private: SGAtomic(const SGAtomic&); @@ -91,11 +109,37 @@ private: && !defined(SGATOMIC_USE_MIPOSPRO_BUILTINS) \ && !defined(SGATOMIC_USE_WIN32_INTERLOCKED) mutable SGMutex mMutex; -#endif -#ifdef SGATOMIC_USE_WIN32_INTERLOCKED - __declspec(align(32)) #endif unsigned mValue; }; +namespace simgear +{ +// Typesafe wrapper around SGSwappable +template +class Swappable : private SGAtomic +{ +public: + Swappable(const T& value) : SGAtomic(static_cast(value)) + { + } + T operator() () const + { + return static_cast(SGAtomic::operator unsigned ()); + } + Swappable& operator=(const Swappable& rhs) + { + for (unsigned oldval = unsigned(*this); + !compareAndExchange(oldval, unsigned(rhs)); + oldval = unsigned(*this)) + ; + return *this; + } + bool compareAndSwap(const T& oldVal, const T& newVal) + { + return SGAtomic::compareAndExchange(static_cast(oldVal), + static_cast(newVal)); + } +}; +} #endif