Use SGAtomic's compareAndExchange instead of a new SGSwappable class

Also, eliminate the __declspec(32) of that class which is causing problems
in osg::buffered_object.
This commit is contained in:
Tim Moore
2009-07-17 00:29:48 +02:00
parent fc7ec4299e
commit f525a05be8
2 changed files with 14 additions and 67 deletions
+1 -1
View File
@@ -106,7 +106,7 @@ protected:
ContextInfo(const ContextInfo& rhs) : valid(rhs.valid()) {} ContextInfo(const ContextInfo& rhs) : valid(rhs.valid()) {}
ContextInfo& operator=(const ContextInfo& rhs) ContextInfo& operator=(const ContextInfo& rhs)
{ {
valid = rhs.valid(); valid = rhs.valid;
} }
Swappable<Status> valid; Swappable<Status> valid;
}; };
+13 -66
View File
@@ -113,85 +113,32 @@ private:
unsigned mValue; unsigned mValue;
}; };
// Value that can be atomically compared and swapped.
class SGSwappable
{
public:
typedef unsigned long value_type;
SGSwappable(unsigned long value = 0) : mValue(value) {}
operator unsigned long() const
{
#if defined(SGATOMIC_USE_GCC4_BUILTINS)
__sync_synchronize();
return mValue;
#elif defined(SGATOMIC_USE_MIPOSPRO_BUILTINS)
__synchronize();
return mValue;
#elif defined(SGATOMIC_USE_WIN32_INTERLOCKED)
return static_cast<long const volatile &>(mValue);
#else
SGGuard<SGMutex> lock(mMutex);
return mValue;
#endif
}
bool compareAndSwap(unsigned long oldVal, unsigned long newVal)
{
#if defined(SGATOMIC_USE_GCC4_BUILTINS)
return __sync_bool_compare_and_swap(&mValue, oldVal, newVal);
#elif defined(SGATOMIC_USE_MIPOSPRO_BUILTINS)
return __compare_and_swap(&mValue, oldVal, newVal);
#elif defined(SGATOMIC_USE_WIN32_INTERLOCKED)
long previous
= InterlockedCompareExchange(reinterpret_cast<long volatile*>(&mValue),
(long)newVal,
(long)oldVal);
return previous == (long)oldVal;
#else
SGGuard<SGMutex> lock(mMutex);
if (oldVal == mValue) {
mValue = newVal;
return true;
} else {
return false;
}
#endif
}
private:
SGSwappable(const SGAtomic&);
SGSwappable& operator=(const SGAtomic&);
#if !defined(SGATOMIC_USE_GCC4_BUILTINS) \
&& !defined(SGATOMIC_USE_MIPOSPRO_BUILTINS) \
&& !defined(SGATOMIC_USE_WIN32_INTERLOCKED)
mutable SGMutex mMutex;
#endif
#ifdef SGATOMIC_USE_WIN32_INTERLOCKED
__declspec(align(32))
#endif
value_type mValue;
};
namespace simgear namespace simgear
{ {
// Typesafe wrapper around SGSwappable // Typesafe wrapper around SGSwappable
template <typename T> template <typename T>
class Swappable : private SGSwappable class Swappable : private SGAtomic
{ {
public: public:
Swappable(const T& value) : SGSwappable(static_cast<value_type>(value)) Swappable(const T& value) : SGAtomic(static_cast<unsigned>(value))
{ {
} }
T operator() () const T operator() () const
{ {
return static_cast<T>(SGSwappable::operator unsigned long ()); return static_cast<T>(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) bool compareAndSwap(const T& oldVal, const T& newVal)
{ {
return SGSwappable::compareAndSwap(static_cast<value_type>(oldVal), return SGAtomic::compareAndExchange(static_cast<unsigned>(oldVal),
static_cast<value_type>(newVal)); static_cast<unsigned>(newVal));
} }
}; };
} }