From 673cb24fc23a3c0a34266cbed5e5c34899a3e706 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Thu, 28 Apr 2016 09:20:13 -0400 Subject: [PATCH] replace use of epics_auto_ptr w/ eapt_array add helpers for udpiiu to calculate parameters maxPeriod and nTimers, allowing them to be const. Add SearchArray to hold fixed-size array of auto_ptr. --- src/ca/client/nciu.h | 1 + src/ca/client/udpiiu.cpp | 85 +++++++++++++++++++++++----------------- src/ca/client/udpiiu.h | 17 ++++++-- 3 files changed, 65 insertions(+), 38 deletions(-) diff --git a/src/ca/client/nciu.h b/src/ca/client/nciu.h index 4994465a8..7cba6e82b 100644 --- a/src/ca/client/nciu.h +++ b/src/ca/client/nciu.h @@ -58,6 +58,7 @@ protected: channelNode (); bool isInstalledInServer ( epicsGuard < epicsMutex > & ) const; bool isConnected ( epicsGuard < epicsMutex > & ) const; +public: static unsigned getMaxSearchTimerCount (); private: enum channelState { diff --git a/src/ca/client/udpiiu.cpp b/src/ca/client/udpiiu.cpp index adf2ba949..837a836d9 100644 --- a/src/ca/client/udpiiu.cpp +++ b/src/ca/client/udpiiu.cpp @@ -64,6 +64,52 @@ const udpiiu::pProtoStubUDP udpiiu::udpJumpTableCAC [] = &udpiiu::repeaterAckAction, }; + +static +double getMaxPeriod() +{ + double maxPeriod = maxSearchPeriodDefault; + + if ( envGetConfigParamPtr ( & EPICS_CA_MAX_SEARCH_PERIOD ) ) { + long longStatus = envGetDoubleConfigParam ( + & EPICS_CA_MAX_SEARCH_PERIOD, & maxPeriod ); + if ( ! longStatus ) { + if ( maxPeriod < maxSearchPeriodLowerLimit ) { + epicsPrintf ( "\"%s\" out of range (low)\n", + EPICS_CA_MAX_SEARCH_PERIOD.name ); + maxPeriod = maxSearchPeriodLowerLimit; + epicsPrintf ( "Setting \"%s\" = %f seconds\n", + EPICS_CA_MAX_SEARCH_PERIOD.name, maxPeriod ); + } + } + else { + epicsPrintf ( "EPICS \"%s\" wasnt a real number\n", + EPICS_CA_MAX_SEARCH_PERIOD.name ); + epicsPrintf ( "Setting \"%s\" = %f seconds\n", + EPICS_CA_MAX_SEARCH_PERIOD.name, maxPeriod ); + } + } + + return maxPeriod; +} + +static +unsigned getNTimers(double maxPeriod) +{ + unsigned nTimers = static_cast < unsigned > ( 1.0 + log ( maxPeriod / minRoundTripEstimate ) / log ( 2.0 ) ); + + if ( nTimers > channelNode::getMaxSearchTimerCount () ) { + nTimers = channelNode::getMaxSearchTimerCount (); + epicsPrintf ( "\"%s\" out of range (high)\n", + EPICS_CA_MAX_SEARCH_PERIOD.name ); + epicsPrintf ( "Setting \"%s\" = %f seconds\n", + EPICS_CA_MAX_SEARCH_PERIOD.name, + (1<<(nTimers-1)) * minRoundTripEstimate ); + } + + return nTimers; +} + // // udpiiu::udpiiu () // @@ -85,14 +131,15 @@ udpiiu::udpiiu ( repeaterSubscribeTmr ( m_repeaterTimerNotify, timerQueue, cbMutexIn, ctxNotifyIn ), govTmr ( *this, timerQueue, cacMutexIn ), - maxPeriod ( maxSearchPeriodDefault ), + maxPeriod ( getMaxPeriod() ), rtteMean ( minRoundTripEstimate ), rtteMeanDev ( 0 ), cacRef ( cac ), cbMutex ( cbMutexIn ), cacMutex ( cacMutexIn ), + nTimers ( getNTimers(maxPeriod) ), + ppSearchTmr ( nTimers ), nBytesInXmitBuf ( 0 ), - nTimers ( 0 ), beaconAnomalyTimerIndex ( 0 ), sequenceNumber ( 0 ), lastReceivedSeqNo ( 0 ), @@ -104,45 +151,13 @@ udpiiu::udpiiu ( lastReceivedSeqNoIsValid ( false ) { cacGuard.assertIdenticalMutex ( cacMutex ); - - if ( envGetConfigParamPtr ( & EPICS_CA_MAX_SEARCH_PERIOD ) ) { - long longStatus = envGetDoubleConfigParam ( - & EPICS_CA_MAX_SEARCH_PERIOD, & this->maxPeriod ); - if ( ! longStatus ) { - if ( this->maxPeriod < maxSearchPeriodLowerLimit ) { - epicsPrintf ( "\"%s\" out of range (low)\n", - EPICS_CA_MAX_SEARCH_PERIOD.name ); - this->maxPeriod = maxSearchPeriodLowerLimit; - epicsPrintf ( "Setting \"%s\" = %f seconds\n", - EPICS_CA_MAX_SEARCH_PERIOD.name, this->maxPeriod ); - } - } - else { - epicsPrintf ( "EPICS \"%s\" wasnt a real number\n", - EPICS_CA_MAX_SEARCH_PERIOD.name ); - epicsPrintf ( "Setting \"%s\" = %f seconds\n", - EPICS_CA_MAX_SEARCH_PERIOD.name, this->maxPeriod ); - } - } - double powerOfTwo = log ( this->maxPeriod / minRoundTripEstimate ) / log ( 2.0 ); - this->nTimers = static_cast < unsigned > ( powerOfTwo + 1.0 ); - if ( this->nTimers > channelNode::getMaxSearchTimerCount () ) { - this->nTimers = channelNode::getMaxSearchTimerCount (); - epicsPrintf ( "\"%s\" out of range (high)\n", - EPICS_CA_MAX_SEARCH_PERIOD.name ); - epicsPrintf ( "Setting \"%s\" = %f seconds\n", - EPICS_CA_MAX_SEARCH_PERIOD.name, - (1<<(this->nTimers-1)) * minRoundTripEstimate ); - } - - powerOfTwo = log ( beaconAnomalySearchPeriod / minRoundTripEstimate ) / log ( 2.0 ); + double powerOfTwo = log ( beaconAnomalySearchPeriod / minRoundTripEstimate ) / log ( 2.0 ); this->beaconAnomalyTimerIndex = static_cast < unsigned > ( powerOfTwo + 1.0 ); if ( this->beaconAnomalyTimerIndex >= this->nTimers ) { this->beaconAnomalyTimerIndex = this->nTimers - 1; } - this->ppSearchTmr.reset ( new epics_auto_ptr < class searchTimer > [ this->nTimers ] ); for ( unsigned i = 0; i < this->nTimers; i++ ) { this->ppSearchTmr[i].reset ( new searchTimer ( *this, timerQueue, i, cacMutexIn, diff --git a/src/ca/client/udpiiu.h b/src/ca/client/udpiiu.h index 103547919..595b8daad 100644 --- a/src/ca/client/udpiiu.h +++ b/src/ca/client/udpiiu.h @@ -25,6 +25,8 @@ #ifndef udpiiuh #define udpiiuh +#include + #ifdef epicsExportSharedSymbols # define udpiiuh_accessh_epicsExportSharedSymbols # undef epicsExportSharedSymbols @@ -160,15 +162,24 @@ private: repeaterSubscribeTimer repeaterSubscribeTmr; disconnectGovernorTimer govTmr; tsDLList < SearchDest > _searchDestList; - double maxPeriod; + const double maxPeriod; double rtteMean; double rtteMeanDev; cac & cacRef; epicsMutex & cbMutex; epicsMutex & cacMutex; - epics_auto_ptr < epics_auto_ptr < class searchTimer >, eapt_array > ppSearchTmr; + const unsigned nTimers; + struct SearchArray { + typedef std::auto_ptr value_type; + value_type *arr; + SearchArray(size_t n) : arr(new value_type[n]) {} + ~SearchArray() { delete[] arr; } + value_type& operator[](size_t i) const { return arr[i]; } + private: + SearchArray(const SearchArray&); + SearchArray& operator=(const SearchArray&); + } ppSearchTmr; unsigned nBytesInXmitBuf; - unsigned nTimers; unsigned beaconAnomalyTimerIndex; ca_uint32_t sequenceNumber; ca_uint32_t lastReceivedSeqNo;