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:
parent
fc7ec4299e
commit
f525a05be8
@ -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;
|
||||
};
|
||||
|
@ -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));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user