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

View File

@ -106,7 +106,7 @@ protected:
ContextInfo(const ContextInfo& rhs) : valid(rhs.valid()) {}
ContextInfo& operator=(const ContextInfo& rhs)
{
valid = rhs.valid();
valid = rhs.valid;
}
Swappable<Status> valid;
};

View File

@ -113,85 +113,32 @@ private:
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
{
// Typesafe wrapper around SGSwappable
template <typename T>
class Swappable : private SGSwappable
class Swappable : private SGAtomic
{
public:
Swappable(const T& value) : SGSwappable(static_cast<value_type>(value))
Swappable(const T& value) : SGAtomic(static_cast<unsigned>(value))
{
}
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)
{
return SGSwappable::compareAndSwap(static_cast<value_type>(oldVal),
static_cast<value_type>(newVal));
return SGAtomic::compareAndExchange(static_cast<unsigned>(oldVal),
static_cast<unsigned>(newVal));
}
};
}