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:
@@ -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;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user