From 839faf66c0cff75985ef16525f2e0dcead880d58 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Thu, 10 Sep 2015 12:26:05 -0400 Subject: [PATCH] AtomicValue use epicsAtomic if available --- src/remote/codec.h | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/src/remote/codec.h b/src/remote/codec.h index 988c982..edfd6f3 100644 --- a/src/remote/codec.h +++ b/src/remote/codec.h @@ -21,6 +21,11 @@ #include #include #include +#include + +#if defined(EPICS_VERSION_INT) && EPICS_VERSION_INT>=VERSION_INT(3,15,1,0) +#include +#endif #include #include @@ -48,8 +53,39 @@ namespace epics { namespace pvAccess { namespace detail { - // TODO replace mutex with atomic (CAS) operations - template +#if defined(EPICS_VERSION_INT) && EPICS_VERSION_INT>=VERSION_INT(3,15,1,0) + template + 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 + { + AtomicValue realval; + public: + inline bool getAndSet(bool newval) + { + return this->realval.getAndSet(newval?1:0)!=0; + } + inline bool get() { return !!this->realval.get(); } + }; + +#else + template class AtomicValue { public: @@ -69,6 +105,7 @@ namespace epics { T _value; epics::pvData::Mutex mutex; }; +#endif // TODO replace this queue with lock-free implementation