From a57460cedb032b862032f5c7aaeceb5c07601087 Mon Sep 17 00:00:00 2001 From: Freddie Akeroyd Date: Tue, 16 Aug 2022 20:47:58 +0100 Subject: [PATCH 1/7] Try to stop spectra gettng into alarm or disconnected * Add SEVR STAT and UDF fields to data arrays * Do not slow scan PVs that are not being monitored * Reduce scan rate on fixed pvs that do not change * Remove alarm level limits on axis PVs --- isisdaeApp/src/FixedValuePV.cpp | 2 + isisdaeApp/src/Makefile | 1 + isisdaeApp/src/NoAlarmPV.cpp | 37 +++++++++++++++++ isisdaeApp/src/exPV.cc | 63 +++++++++++++++------------- isisdaeApp/src/exServer.cc | 74 +++++++++++++++++++++------------ isisdaeApp/src/exServer.h | 26 +++++++++++- 6 files changed, 145 insertions(+), 58 deletions(-) create mode 100644 isisdaeApp/src/NoAlarmPV.cpp diff --git a/isisdaeApp/src/FixedValuePV.cpp b/isisdaeApp/src/FixedValuePV.cpp index 3d781c1..3e3e01b 100644 --- a/isisdaeApp/src/FixedValuePV.cpp +++ b/isisdaeApp/src/FixedValuePV.cpp @@ -39,6 +39,8 @@ bool FixedValuePV::getNewValue(smartGDDPointer& pDD) return true; } +template class FixedValuePV; +template class FixedValuePV; template class FixedValuePV; template class FixedValuePV; template class FixedValuePV; diff --git a/isisdaeApp/src/Makefile b/isisdaeApp/src/Makefile index e56e8e6..e4de037 100644 --- a/isisdaeApp/src/Makefile +++ b/isisdaeApp/src/Makefile @@ -36,6 +36,7 @@ isisdae_SRCS += SpectrumPV.cc NORDPV.cc MonLookupPV.cc CountsPV.cc FixedValuePV. isisdae_SRCS += exChannel.cc exPV.cc exScalarPV.cc exVectorPV.cc exServer.cc isisdae_SRCS += isisdaeDriver.cpp isisdaeInterface.cpp CRPTMapping.cpp isisdae_SRCS += MonitorSpectrumPV.cpp MonitorCountsPV.cpp dae_isisicpint_dummy.cpp +isisdae_SRCS += NoAlarmPV.cpp isisdae_LIBS += webget htmltidy asyn oncrpc utilities zlib pcrecpp pcre pugixml isisdae_LIBS += ADnEDSupport diff --git a/isisdaeApp/src/NoAlarmPV.cpp b/isisdaeApp/src/NoAlarmPV.cpp new file mode 100644 index 0000000..f598ab1 --- /dev/null +++ b/isisdaeApp/src/NoAlarmPV.cpp @@ -0,0 +1,37 @@ +#include + +#include "exServer.h" +#include "gddApps.h" + +NoAlarmPV::NoAlarmPV ( exServer & cas, pvInfo &setup, bool preCreateFlag, bool scanOnIn) : FixedValuePV(cas, setup, preCreateFlag, scanOnIn, 0) +{ + assert(this->info.getType () == aitEnumEnum16); +} + +caStatus NoAlarmPV::getEnumsImpl ( gdd & enumsIn ) +{ + static const unsigned nStr = 1; + aitFixedString *str; + exFixedStringDestructor *pDes; + + str = new aitFixedString[nStr]; + if (!str) { + return S_casApp_noMemory; + } + + pDes = new exFixedStringDestructor; + if (!pDes) { + delete [] str; + return S_casApp_noMemory; + } + + strncpy (str[0].fixed_string, "NO_ALARM", + sizeof(str[0].fixed_string)); + + enumsIn.setDimension(1); + enumsIn.setBound (0,0,nStr); + enumsIn.putRef (str, pDes); + + return S_cas_success; +} + diff --git a/isisdaeApp/src/exPV.cc b/isisdaeApp/src/exPV.cc index c18ccb2..1ef23f7 100644 --- a/isisdaeApp/src/exPV.cc +++ b/isisdaeApp/src/exPV.cc @@ -21,12 +21,6 @@ char exPV::hasBeenInitialized = 0; gddAppFuncTable exPV::ft; epicsTime exPV::currentTime; -// -// special gddDestructor guarantees same form of new and delete -// -class exFixedStringDestructor: public gddDestructor { - virtual void run (void *); -}; // // exPV::exPV() @@ -46,16 +40,9 @@ exPV::exPV ( exServer & casIn, pvInfo & setup, // assert (this->info.getElementCount()>=1u); - memset(&(this->lastTimer), 0, sizeof(this->lastTimer)); + memset(&(this->lastScan), 0, sizeof(this->lastScan)); - // - // start a very slow background scan - // (we will speed this up to the normal rate when - // someone is watching the PV) - // - if ( this->scanOn && this->info.getScanPeriod () > 0.0 ) { - this->timer.start ( *this, this->getScanPeriod() ); - } + // we no longer start a very slow background scan here } // @@ -114,11 +101,27 @@ epicsTimerNotify::expireStatus exPV::expire ( const epicsTime & /*currentTime*/ ) // X aCC 361 { static const double sleep_delay = atof(getenv("ISISDAE_TIMER_SLEEP") != NULL ? getenv("ISISDAE_TIMER_SLEEP") : ".001"); + // only periodic scan if somebody is interested in us + if (this->interest) { + doScan(); + } + this->timerDone.signal(); + epicsThreadSleep(sleep_delay); // yield thread, this is in case we have a big timer queue and start to starve DAE access + if ( this->scanOn && this->getScanPeriod() > 0.0 ) { + return expireStatus ( restart, this->getScanPeriod() ); + } + else { + return noRestart; + } +} + +void exPV::doScan() +{ try { this->scan(); epicsGuard _lock(timerLock); - epicsTimeGetCurrent(&(this->lastTimer)); + epicsTimeGetCurrent(&(this->lastScan)); } catch(const std::exception& ex) { @@ -128,17 +131,9 @@ exPV::expire ( const epicsTime & /*currentTime*/ ) // X aCC 361 { errlogSevPrintf(errlogMajor, "CAS: exPV::expire: Scan failed"); } - this->timerDone.signal(); - epicsThreadSleep(sleep_delay); // yield thread, this is in case we have a big timer queue and start to starve DAE access - if ( this->scanOn && this->getScanPeriod() > 0.0 ) { - return expireStatus ( restart, this->getScanPeriod() ); - } - else { - return noRestart; - } } -// + // exPV::bestExternalType() // aitEnum exPV::bestExternalType () const @@ -158,8 +153,10 @@ caStatus exPV::interestRegister () this->interest = true; // std::cerr << "CAS: Interest registered in PV \"" << getName() << "\"" << std::endl; if ( this->scanOn && this->getScanPeriod() > 0.0 && - this->getScanPeriod() < this->timer.getExpireDelay() ) { + (!this->timer.getExpireInfo().active || this->getScanPeriod() < this->timer.getExpireDelay()) + ) { this->timer.start ( *this, this->getScanPeriod() ); + } return S_casApp_success; @@ -172,6 +169,7 @@ void exPV::interestDelete() { // std::cerr << "CAS: Interest unregistered in PV \"" << getName() << "\"" << std::endl; this->interest = false; + this->timer.cancel(); } // @@ -258,7 +256,7 @@ caStatus exPV::getUnits( gdd & units ) } // -// exPV::getEnums() +// exPV::getEnumsImpl() // // returns the eneumerated state strings // for a discrete channel @@ -267,7 +265,7 @@ caStatus exPV::getUnits( gdd & units ) // and therefore this isnt appropriate in an // analog context ... // -caStatus exPV::getEnums ( gdd & enumsIn ) +caStatus exPV::getEnumsImpl ( gdd & enumsIn ) { if ( this->info.getType () == aitEnumEnum16 ) { static const unsigned nStr = 2; @@ -300,6 +298,11 @@ caStatus exPV::getEnums ( gdd & enumsIn ) return S_cas_success; } +caStatus exPV::getEnums ( gdd & enumsIn ) +{ + return getEnumsImpl(enumsIn); +} + // // exPV::getValue() // @@ -348,7 +351,7 @@ caStatus exPV::read ( const casCtx & ctx, gdd & protoIn ) double tdiff; { epicsGuard _lock(timerLock); - tdiff = epicsTimeDiffInSeconds(&now, &(this->lastTimer)); + tdiff = epicsTimeDiffInSeconds(&now, &(this->lastScan)); } if ( (this->interest && this->scanOn && this->getScanPeriod() > 0.0) || (tdiff < cache_time) ) { @@ -367,7 +370,7 @@ caStatus exPV::read ( const casCtx & ctx, gdd & protoIn ) caStatus exPV::doRead ( const casCtx & ctx, gdd & protoIn ) { - this->expire(epicsTime()); // does a scan + this->doScan(); return this->ft.read(*this, protoIn); } diff --git a/isisdaeApp/src/exServer.cc b/isisdaeApp/src/exServer.cc index 3ef4c03..79f6452 100644 --- a/isisdaeApp/src/exServer.cc +++ b/isisdaeApp/src/exServer.cc @@ -327,7 +327,7 @@ void exServer::createAxisPVs(bool is_monitor, int id, int period, const char* ax char buffer[256], pvAlias[256]; const char* prefix = (is_monitor ? "MON" : "SPEC"); sprintf(buffer, "%s:%d:%d:%s", prefix, period, id, axis); - pvInfo* pPVI = new pvInfo (0.5, buffer, 1.0e9f, 0.0f, units.c_str(), aitEnumFloat32, m_ntc); + pvInfo* pPVI = new pvInfo (0.5, buffer, 0.0f, 0.0f, units.c_str(), aitEnumFloat32, m_ntc); m_pvList[buffer] = pPVI; SpectrumPV* pSPV = (is_monitor ? new MonitorSpectrumPV(*this, *pPVI, true, scanOn, axis, id, period) : new SpectrumPV(*this, *pPVI, true, scanOn, axis, id, period)); @@ -367,18 +367,22 @@ void exServer::createAxisPVs(bool is_monitor, int id, int period, const char* ax sprintf(pvAlias, "%s%s", m_pvPrefix.c_str(), buffer); this->installAliasName(*pPVI, pvAlias); } + createStandardPVs(prefix, period, id, axis, units, is_monitor); +} +void exServer::createStandardPVs(const char* prefix, int period, int id, const char* axis, const std::string& units, bool is_monitor) +{ + char buffer[256], pvAlias[256]; sprintf(buffer, "%s:%d:%d:%s.DESC", prefix, period, id, axis); std::ostringstream desc; desc << axis << " (" << (is_monitor ? "mon=" : "spec=") << id << ",period=" << period << ")"; - pPVI = createFixedPV(buffer, desc.str(), "", aitEnumString); + pvInfo* pPVI = createFixedPV(buffer, desc.str(), "", aitEnumString); if (period == 1) { sprintf(buffer, "%s:%d:%s.DESC", prefix, id, axis); sprintf(pvAlias, "%s%s", m_pvPrefix.c_str(), buffer); this->installAliasName(*pPVI, pvAlias); } - sprintf(buffer, "%s:%d:%d:%s.EGU", prefix, period, id, axis); pPVI = createFixedPV(buffer, units, "", aitEnumString); if (period == 1) @@ -387,13 +391,37 @@ void exServer::createAxisPVs(bool is_monitor, int id, int period, const char* ax sprintf(pvAlias, "%s%s", m_pvPrefix.c_str(), buffer); this->installAliasName(*pPVI, pvAlias); } + sprintf(buffer, "%s:%d:%d:%s.UDF", prefix, period, id, axis); + pPVI = createFixedPV(buffer, 0, "", aitEnumInt8); + if (period == 1) + { + sprintf(buffer, "%s:%d:%s.UDF", prefix, id, axis); + sprintf(pvAlias, "%s%s", m_pvPrefix.c_str(), buffer); + this->installAliasName(*pPVI, pvAlias); + } + sprintf(buffer, "%s:%d:%d:%s.STAT", prefix, period, id, axis); + pPVI = createNoAlarmPV(buffer); + if (period == 1) + { + sprintf(buffer, "%s:%d:%s.STAT", prefix, id, axis); + sprintf(pvAlias, "%s%s", m_pvPrefix.c_str(), buffer); + this->installAliasName(*pPVI, pvAlias); + } + sprintf(buffer, "%s:%d:%d:%s.SEVR", prefix, period, id, axis); + pPVI = createNoAlarmPV(buffer); + if (period == 1) + { + sprintf(buffer, "%s:%d:%s.SEVR", prefix, id, axis); + sprintf(pvAlias, "%s%s", m_pvPrefix.c_str(), buffer); + this->installAliasName(*pPVI, pvAlias); + } } template pvInfo* exServer::createFixedPV(const std::string& pvStr, const T& value, const char* units, aitEnum ait_type) { char pvAlias[256]; - pvInfo* pPVI = new pvInfo (0.5, pvStr.c_str(), 0.0f, 0.0f, units, ait_type, 1); /// @todo would be nice to use arithmetic value, but need to check for strings + pvInfo* pPVI = new pvInfo (5.0, pvStr.c_str(), 0.0f, 0.0f, units, ait_type, 1); /// @todo would be nice to use arithmetic value, but need to check for strings m_pvList[pvStr.c_str()] = pPVI; exPV* pPV = new FixedValuePV(*this, *pPVI, true, scanOn, value); pPVI->setPV(pPV); @@ -402,13 +430,25 @@ pvInfo* exServer::createFixedPV(const std::string& pvStr, const T& value, const return pPVI; } +pvInfo* exServer::createNoAlarmPV(const std::string& pvStr) +{ + char pvAlias[256]; + pvInfo* pPVI = new pvInfo (5.0, pvStr.c_str(), 0.0f, 0.0f, "", aitEnumEnum16, 1); /// @todo would be nice to use arithmetic value, but need to check for strings + m_pvList[pvStr.c_str()] = pPVI; + exPV* pPV = new NoAlarmPV(*this, *pPVI, true, scanOn); + pPVI->setPV(pPV); + epicsSnprintf(pvAlias, sizeof(pvAlias), "%s%s", m_pvPrefix.c_str(), pvStr.c_str()); + this->installAliasName(*pPVI, pvAlias); + return pPVI; +} + // id is spec or mon number void exServer::createCountsPV(bool is_monitor, int id, int period) { char buffer[256], pvAlias[256]; const char* prefix = (is_monitor ? "MON" : "SPEC"); sprintf(buffer, "%s:%d:%d:C", prefix, period, id); - pvInfo* pPVI = new pvInfo (0.5, buffer, 1.0e9f, 0.0f, "cnt", aitEnumInt32, 1); + pvInfo* pPVI = new pvInfo (0.5, buffer, 0.0f, 0.0f, "cnt", aitEnumInt32, 1); m_pvList[buffer] = pPVI; exPV* pPV = (is_monitor ? new MonitorCountsPV(*this, *pPVI, true, scanOn, id, period) : new CountsPV(*this, *pPVI, true, scanOn, id, period)); @@ -425,28 +465,10 @@ void exServer::createCountsPV(bool is_monitor, int id, int period) sprintf(pvAlias, "%s%s.VAL", m_pvPrefix.c_str(), buffer); this->installAliasName(*pPVI, pvAlias); } - - sprintf(buffer, "%s:%d:%d:C.DESC", prefix, period, id); - std::ostringstream desc; - desc << "Integral (" << (is_monitor ? "mon=" : "spec=") << id << ",period=" << period << ")"; - pPVI = createFixedPV(buffer, desc.str(), "", aitEnumString); - if (period == 1) - { - sprintf(buffer, "%s:%d:C.DESC", prefix, id); - sprintf(pvAlias, "%s%s", m_pvPrefix.c_str(), buffer); - this->installAliasName(*pPVI, pvAlias); - } - - sprintf(buffer, "%s:%d:%d:C.EGU", prefix, period, id); - pPVI = createFixedPV(buffer, std::string("cnt"), "", aitEnumString); - if (period == 1) - { - sprintf(buffer, "%s:%d:C.EGU", prefix, id); - sprintf(pvAlias, "%s%s", m_pvPrefix.c_str(), buffer); - this->installAliasName(*pPVI, pvAlias); - } + createStandardPVs(prefix, period, id, "C", "cnt", is_monitor); } + bool exServer::createSpecPVs(const std::string& pvStr) { int spec, period; @@ -491,7 +513,7 @@ bool exServer::createMonitorPVs(const std::string& pvStr) createCountsPV(true, mon, period); sprintf(buffer, "MON:%d:%d:S", period, mon); - pvInfo* pPVI = new pvInfo (0.5, buffer, 1.0e9f, 0.0f, "", aitEnumInt32, 1); + pvInfo* pPVI = new pvInfo (0.5, buffer, 0.0f, 0.0f, "", aitEnumInt32, 1); m_pvList[buffer] = pPVI; exPV* pPV = new MonLookupPV(*this, *pPVI, true, scanOn, mon); pPVI->setPV(pPV); diff --git a/isisdaeApp/src/exServer.h b/isisdaeApp/src/exServer.h index 67e82b3..53fc9f1 100644 --- a/isisdaeApp/src/exServer.h +++ b/isisdaeApp/src/exServer.h @@ -137,6 +137,13 @@ class pvEntry // X aCC 655 pvEntry ( const pvEntry & ); }; +// +// special gddDestructor guarantees same form of new and delete +// +class exFixedStringDestructor: public gddDestructor { + virtual void run (void *); +}; + // // exPV @@ -225,6 +232,7 @@ class exPV : public casPV, public epicsTimerNotify, static epicsTime currentTime; virtual caStatus updateValue ( const gdd & ) = 0; + virtual gddAppFuncTableStatus getEnumsImpl(gdd &value); private: @@ -232,9 +240,10 @@ class exPV : public casPV, public epicsTimerNotify, // scan timer expire // expireStatus expire ( const epicsTime & currentTime ); + void doScan(); epicsEvent timerDone; // a timer has fired and completed a scan - epicsTimeStamp lastTimer; // last time we ran timer task + epicsTimeStamp lastScan; // last time we ran ran a scan // // Std PV Attribute fetch support @@ -323,6 +332,16 @@ class FixedValuePV : public exScalarPV { FixedValuePV ( const FixedValuePV & ); }; +class NoAlarmPV : public FixedValuePV { +public: + NoAlarmPV ( exServer & cas, pvInfo &setup, + bool preCreateFlag, bool scanOnIn); + virtual caStatus getEnumsImpl ( gdd & enumsIn ); +private: + NoAlarmPV & operator = ( const NoAlarmPV & ); + NoAlarmPV ( const NoAlarmPV & ); +}; + class MonLookupPV : public exScalarPV { public: MonLookupPV ( exServer & cas, pvInfo &setup, @@ -454,7 +473,7 @@ class exServer : private caServer { void createAxisPVs(bool is_monitor, int id, int period, const char* axis, const std::string& units); void createCountsPV(bool is_monitor, int id, int period); template pvInfo* createFixedPV(const std::string& pvStr, const T& value, const char* units, aitEnum ait_type); - + pvInfo* createNoAlarmPV(const std::string& pvStr); private: resTable < pvEntry, stringId > stringResTbl; epicsTimerQueueActive * pTimerQueue; @@ -471,6 +490,9 @@ class exServer : private caServer { const char * pPVName ); pvAttachReturn pvAttach ( const casCtx &, const char * pPVName ); + + void createStandardPVs(const char* prefix, int period, int id, const char* axis, const std::string& units, bool is_monitor); + exServer & operator = ( const exServer & ); exServer ( const exServer & ); From 17dbba13e9bbec6b1e8092cc9383c40202497804 Mon Sep 17 00:00:00 2001 From: Freddie Akeroyd Date: Tue, 16 Aug 2022 23:16:52 +0100 Subject: [PATCH 2/7] =?UTF-8?q?=C2=81Add=20HOPR/LOPR?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- isisdaeApp/src/FixedValuePV.cpp | 1 + isisdaeApp/src/exServer.cc | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/isisdaeApp/src/FixedValuePV.cpp b/isisdaeApp/src/FixedValuePV.cpp index 3e3e01b..3c526cc 100644 --- a/isisdaeApp/src/FixedValuePV.cpp +++ b/isisdaeApp/src/FixedValuePV.cpp @@ -43,5 +43,6 @@ template class FixedValuePV; template class FixedValuePV; template class FixedValuePV; template class FixedValuePV; +template class FixedValuePV; template class FixedValuePV; diff --git a/isisdaeApp/src/exServer.cc b/isisdaeApp/src/exServer.cc index 79f6452..5d567d4 100644 --- a/isisdaeApp/src/exServer.cc +++ b/isisdaeApp/src/exServer.cc @@ -415,6 +415,22 @@ void exServer::createStandardPVs(const char* prefix, int period, int id, const c sprintf(pvAlias, "%s%s", m_pvPrefix.c_str(), buffer); this->installAliasName(*pPVI, pvAlias); } + sprintf(buffer, "%s:%d:%d:%s.HOPR", prefix, period, id, axis); + pPVI = createFixedPV(buffer, 0.0, "", aitEnumFloat64); + if (period == 1) + { + sprintf(buffer, "%s:%d:%s.HOPR", prefix, id, axis); + sprintf(pvAlias, "%s%s", m_pvPrefix.c_str(), buffer); + this->installAliasName(*pPVI, pvAlias); + } + sprintf(buffer, "%s:%d:%d:%s.LOPR", prefix, period, id, axis); + pPVI = createFixedPV(buffer, 0.0, "", aitEnumFloat64); + if (period == 1) + { + sprintf(buffer, "%s:%d:%s.LOPR", prefix, id, axis); + sprintf(pvAlias, "%s%s", m_pvPrefix.c_str(), buffer); + this->installAliasName(*pPVI, pvAlias); + } } template From 92b2d8b6b87ef5f72ff3818b56a0ba5b9ebe301f Mon Sep 17 00:00:00 2001 From: Freddie Akeroyd Date: Thu, 18 Aug 2022 12:33:48 +0100 Subject: [PATCH 3/7] Add PCAS debug variable --- isisdaeApp/src/exPV.cc | 14 ++++++++++++-- isisdaeApp/src/exServer.h | 1 + isisdaeApp/src/isisdaeInclude.dbd | 1 + 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/isisdaeApp/src/exPV.cc b/isisdaeApp/src/exPV.cc index 1ef23f7..465b3aa 100644 --- a/isisdaeApp/src/exPV.cc +++ b/isisdaeApp/src/exPV.cc @@ -102,6 +102,9 @@ exPV::expire ( const epicsTime & /*currentTime*/ ) // X aCC 361 { static const double sleep_delay = atof(getenv("ISISDAE_TIMER_SLEEP") != NULL ? getenv("ISISDAE_TIMER_SLEEP") : ".001"); // only periodic scan if somebody is interested in us + if (isisdaePCASDebug > 0) { + std::cerr << "CAS: exPV::expire() timer expired \"" << getName() << "\"" << std::endl; + } if (this->interest) { doScan(); } @@ -117,6 +120,9 @@ exPV::expire ( const epicsTime & /*currentTime*/ ) // X aCC 361 void exPV::doScan() { + if (isisdaePCASDebug > 0) { + std::cerr << "CAS: exPV::doScan() updating data for \"" << getName() << "\"" << std::endl; + } try { this->scan(); @@ -151,7 +157,9 @@ caStatus exPV::interestRegister () } this->interest = true; -// std::cerr << "CAS: Interest registered in PV \"" << getName() << "\"" << std::endl; + if (isisdaePCASDebug > 0) { + std::cerr << "CAS: exPV::interestRegister() in PV \"" << getName() << "\"" << std::endl; + } if ( this->scanOn && this->getScanPeriod() > 0.0 && (!this->timer.getExpireInfo().active || this->getScanPeriod() < this->timer.getExpireDelay()) ) { @@ -167,7 +175,9 @@ caStatus exPV::interestRegister () // void exPV::interestDelete() { -// std::cerr << "CAS: Interest unregistered in PV \"" << getName() << "\"" << std::endl; + if (isisdaePCASDebug > 0) { + std::cerr << "CAS: exPV::interestDelete() in PV \"" << getName() << "\"" << std::endl; + } this->interest = false; this->timer.cancel(); } diff --git a/isisdaeApp/src/exServer.h b/isisdaeApp/src/exServer.h index 53fc9f1..1919028 100644 --- a/isisdaeApp/src/exServer.h +++ b/isisdaeApp/src/exServer.h @@ -664,3 +664,4 @@ inline exChannel::exChannel ( const casCtx & ctxIn ) : { } +extern "C" int isisdaePCASDebug; diff --git a/isisdaeApp/src/isisdaeInclude.dbd b/isisdaeApp/src/isisdaeInclude.dbd index c6cf3ce..fcce919 100644 --- a/isisdaeApp/src/isisdaeInclude.dbd +++ b/isisdaeApp/src/isisdaeInclude.dbd @@ -1 +1,2 @@ registrar("isisdaeRegister") +variable(isisdaePCASDebug, int) From 0377f0038a1e9dae63efefe1e77214fe73088a40 Mon Sep 17 00:00:00 2001 From: Freddie Akeroyd Date: Thu, 18 Aug 2022 12:37:58 +0100 Subject: [PATCH 4/7] Add PCAS debug variable --- isisdaeApp/src/isisdaeDriver.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/isisdaeApp/src/isisdaeDriver.cpp b/isisdaeApp/src/isisdaeDriver.cpp index 773ad95..ae96764 100644 --- a/isisdaeApp/src/isisdaeDriver.cpp +++ b/isisdaeApp/src/isisdaeDriver.cpp @@ -2685,6 +2685,8 @@ int isisdaeConfigure(const char *portName, int options, const char *host, const volatile bool isisdaeDriver::daeIOCisRunning = false; +int isisdaePCASDebug = 0; + void isisdaeDriver::waitForIOCRunning() { while (!daeIOCisRunning) @@ -2792,5 +2794,6 @@ static void isisdaeRegister(void) } epicsExportRegistrar(isisdaeRegister); +epicsExportAddress(int, isisdaePCASDebug); } From 923660a7468bc42197e6fa09cae7505a9ce07e7c Mon Sep 17 00:00:00 2001 From: Freddie Akeroyd Date: Thu, 18 Aug 2022 23:01:45 +0100 Subject: [PATCH 5/7] Add dereference to asynIO (missing from example used) --- isisdaeApp/src/exPV.cc | 1 + isisdaeApp/src/exServer.h | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/isisdaeApp/src/exPV.cc b/isisdaeApp/src/exPV.cc index 465b3aa..80581d1 100644 --- a/isisdaeApp/src/exPV.cc +++ b/isisdaeApp/src/exPV.cc @@ -370,6 +370,7 @@ caStatus exPV::read ( const casCtx & ctx, gdd & protoIn ) if (m_asyncIO) { myAsyncReadIO *pIO = new myAsyncReadIO(ctx, protoIn, *this); // will delete itself on IO completion + epicsThreadCreate("myAsyncReadIO", epicsThreadPriorityMedium, epicsThreadStackMedium, myAsyncReadIO::readThreadC, pIO); return S_casApp_asyncCompletion; } else diff --git a/isisdaeApp/src/exServer.h b/isisdaeApp/src/exServer.h index 1919028..ce08336 100644 --- a/isisdaeApp/src/exServer.h +++ b/isisdaeApp/src/exServer.h @@ -424,10 +424,9 @@ class myAsyncReadIO : public casAsyncReadIO { m_value = &protoIn; m_value->reference(); - epicsThreadCreate("myAsyncReadIO", epicsThreadPriorityMedium, epicsThreadStackMedium, readThread, this); } - static void readThread(void* arg) + static void readThreadC(void* arg) { myAsyncReadIO* aio = (myAsyncReadIO*)arg; aio->readThread(); @@ -441,6 +440,13 @@ class myAsyncReadIO : public casAsyncReadIO if (status1 != S_casApp_success) std::cerr << "CAS: Error returned by postIOCompletion" << std::endl; } + ~myAsyncReadIO() + { + m_value->unreference(); + m_value = NULL; + } + + }; // From 1c63bfc3e464decf2617c42c6dced87c9fd95755 Mon Sep 17 00:00:00 2001 From: Freddie Akeroyd Date: Thu, 18 Aug 2022 23:17:23 +0100 Subject: [PATCH 6/7] Add comments --- isisdaeApp/src/exServer.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/isisdaeApp/src/exServer.h b/isisdaeApp/src/exServer.h index ce08336..d92a69f 100644 --- a/isisdaeApp/src/exServer.h +++ b/isisdaeApp/src/exServer.h @@ -423,6 +423,8 @@ class myAsyncReadIO : public casAsyncReadIO myAsyncReadIO(const casCtx & ctx, gdd & protoIn, exPV& pv) : casAsyncReadIO(ctx), m_pv(pv), m_ctx(ctx) { m_value = &protoIn; + // keep variable alive for use in readThread() + // will unreference in destructor m_value->reference(); } @@ -437,6 +439,8 @@ class myAsyncReadIO : public casAsyncReadIO caStatus status, status1; status = m_pv.doRead(m_ctx, *m_value); status1 = postIOCompletion(status, *m_value); + // at this point we will have had our destructor called for us + // so do not reference any variables in "this" if (status1 != S_casApp_success) std::cerr << "CAS: Error returned by postIOCompletion" << std::endl; } From 5467f1b3d996f601b597503526ea94552eb0d424 Mon Sep 17 00:00:00 2001 From: Freddie Akeroyd Date: Sun, 21 Aug 2022 21:39:25 +0100 Subject: [PATCH 7/7] Make monLookup asynchronous --- isisdaeApp/src/MonLookupPV.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/isisdaeApp/src/MonLookupPV.cpp b/isisdaeApp/src/MonLookupPV.cpp index c04cc2c..3b7ae62 100644 --- a/isisdaeApp/src/MonLookupPV.cpp +++ b/isisdaeApp/src/MonLookupPV.cpp @@ -8,7 +8,7 @@ /// class for a PV that converts a monitor number into a spectrum number -MonLookupPV::MonLookupPV ( exServer & cas, pvInfo &setup, bool preCreateFlag, bool scanOnIn, int monitor ) : exScalarPV(cas, setup, preCreateFlag, scanOnIn, false), m_monitor(monitor) +MonLookupPV::MonLookupPV ( exServer & cas, pvInfo &setup, bool preCreateFlag, bool scanOnIn, int monitor ) : exScalarPV(cas, setup, preCreateFlag, scanOnIn, true), m_monitor(monitor) { }