AtomicValue use epicsAtomic if available

This commit is contained in:
Michael Davidsaver
2015-09-10 12:26:05 -04:00
parent c59715f687
commit 839faf66c0
+39 -2
View File
@@ -21,6 +21,11 @@
#include <osiSock.h>
#include <epicsTime.h>
#include <epicsThread.h>
#include <epicsVersion.h>
#if defined(EPICS_VERSION_INT) && EPICS_VERSION_INT>=VERSION_INT(3,15,1,0)
#include <epicsAtomic.h>
#endif
#include <pv/byteBuffer.h>
#include <pv/pvType.h>
@@ -48,8 +53,39 @@ namespace epics {
namespace pvAccess {
namespace detail {
// TODO replace mutex with atomic (CAS) operations
template<typename T>
#if defined(EPICS_VERSION_INT) && EPICS_VERSION_INT>=VERSION_INT(3,15,1,0)
template<typename T>
class AtomicValue
{
T val;
public:
AtomicValue() :val(0) {}
inline T getAndSet(T newval)
{
int oldval;
// epicsAtomic doesn't have unconditional swap
do {
oldval = epics::atomic::get(val);
}while(epics::atomic::compareAndSwap(val, oldval, newval)!=oldval);
return oldval;
}
inline T get() { return epics::atomic::get(val); }
};
// treat bool as int
template<>
class AtomicValue<bool>
{
AtomicValue<int> realval;
public:
inline bool getAndSet(bool newval)
{
return this->realval.getAndSet(newval?1:0)!=0;
}
inline bool get() { return !!this->realval.get(); }
};
#else
template<typename T>
class AtomicValue
{
public:
@@ -69,6 +105,7 @@ namespace epics {
T _value;
epics::pvData::Mutex mutex;
};
#endif
// TODO replace this queue with lock-free implementation