epicsTimerNotify::expireStatus disconnectGovernorTimer::expire ( const epicsTime & /* currentTime */ ) // X aCC 361 { epicsGuard < epicsMutex > guard ( this->mutex ); while ( nciu * pChan = chanList.get () ) { pChan->channelNode::listMember = channelNode::cs_none; this->iiu.govExpireNotify ( guard, *pChan ); } return expireStatus ( restart, disconnectGovernorPeriod ); }
epicsTimerNotify::expireStatus periodicVerify::expire ( const epicsTime & ) { this->nExpire++; double root = 3.14159; for ( unsigned i = 0u; i < 1000; i++ ) { root = sqrt ( root ); } verify ( ! this->cancelCalled ); double delay = rand (); delay = delay / RAND_MAX; delay /= 10.0; return expireStatus ( restart, delay ); }
expireStatus expire(const epicsTime ¤tTime) {done=true; return expireStatus(noRestart);}
// // searchTimer::expire () // epicsTimerNotify::expireStatus searchTimer::expire ( const epicsTime & currentTime ) // X aCC 361 { epicsGuard < epicsMutex > guard ( this->mutex ); while ( nciu * pChan = this->chanListRespPending.get () ) { pChan->channelNode::listMember = channelNode::cs_none; this->iiu.noSearchRespNotify ( guard, *pChan, this->index ); } this->timeAtLastSend = currentTime; // boost search period for channels not recently // searched for if there was some success if ( this->searchResponses && this->boostPossible ) { while ( nciu * pChan = this->chanListReqPending.get () ) { pChan->channelNode::listMember = channelNode::cs_none; this->iiu.boostChannel ( guard, *pChan ); } } if ( this->searchAttempts ) { #if 0 // // dynamically adjust the number of UDP frames per // try depending how many search requests are not // replied to // // The variable this->framesPerTry // determines the number of UDP frames to be sent // each time that expire() is called. // If this value is too high we will waste some // network bandwidth. If it is too low we will // use very little of the incoming UDP message // buffer associated with the server's port and // will therefore take longer to connect. We // initialize this->framesPerTry to a prime number // so that it is less likely that the // same channel is in the last UDP frame // sent every time that this is called (and // potentially discarded by a CA server with // a small UDP input queue). // // increase frames per try only if we see better than // a 93.75% success rate for one pass through the list // if ( this->searchResponses > ( this->searchAttempts - (this->searchAttempts/16u) ) ) { // increase UDP frames per try if we have a good score if ( this->framesPerTry < maxTriesPerFrame ) { // a congestion avoidance threshold similar to TCP is now used if ( this->framesPerTry < this->framesPerTryCongestThresh ) { this->framesPerTry += this->framesPerTry; } else { this->framesPerTry += (this->framesPerTry/8) + 1; } debugPrintf ( ("Increasing frame count to %u t=%u r=%u\n", this->framesPerTry, this->searchAttempts, this->searchResponses) ); } } // if we detect congestion because we have less than a 87.5% success // rate then gradually reduce the frames per try else if ( this->searchResponses < ( this->searchAttempts - (this->searchAttempts/8u) ) ) { if ( this->framesPerTry > 1 ) { this->framesPerTry--; } this->framesPerTryCongestThresh = this->framesPerTry/2 + 1; debugPrintf ( ("Congestion detected - set frames per try to %f t=%u r=%u\n", this->framesPerTry, this->searchAttempts, this->searchResponses) ); } #else if ( this->searchResponses == this->searchAttempts ) { // increase UDP frames per try if we have a good score if ( this->framesPerTry < maxTriesPerFrame ) { // a congestion avoidance threshold similar to TCP is now used if ( this->framesPerTry < this->framesPerTryCongestThresh ) { double doubled = 2 * this->framesPerTry; if ( doubled > this->framesPerTryCongestThresh ) { this->framesPerTry = this->framesPerTryCongestThresh; } else { this->framesPerTry = doubled; } } else { this->framesPerTry += 1.0 / this->framesPerTry; } debugPrintf ( ("Increasing frame count to %g t=%u r=%u\n", this->framesPerTry, this->searchAttempts, this->searchResponses) ); } } else { this->framesPerTryCongestThresh = this->framesPerTry / 2.0; this->framesPerTry = 1u; debugPrintf ( ("Congestion detected - set frames per try to %g t=%u r=%u\n", this->framesPerTry, this->searchAttempts, this->searchResponses) ); } #endif } this->dgSeqNoAtTimerExpireBegin = this->iiu.datagramSeqNumber ( guard ); this->searchAttempts = 0; this->searchResponses = 0; unsigned nFrameSent = 0u; while ( true ) { nciu * pChan = this->chanListReqPending.get (); if ( ! pChan ) { break; } pChan->channelNode::listMember = channelNode::cs_none; bool success = pChan->searchMsg ( guard ); if ( ! success ) { if ( this->iiu.datagramFlush ( guard, currentTime ) ) { nFrameSent++; if ( nFrameSent < this->framesPerTry ) { success = pChan->searchMsg ( guard ); } } if ( ! success ) { this->chanListReqPending.push ( *pChan ); pChan->channelNode::setReqPendingState ( guard, this->index ); break; } } this->chanListRespPending.add ( *pChan ); pChan->channelNode::setRespPendingState ( guard, this->index ); if ( this->searchAttempts < UINT_MAX ) { this->searchAttempts++; } } // flush out the search request buffer if ( this->iiu.datagramFlush ( guard, currentTime ) ) { nFrameSent++; } this->dgSeqNoAtTimerExpireEnd = this->iiu.datagramSeqNumber ( guard ) - 1u; # ifdef DEBUG if ( this->searchAttempts ) { char buf[64]; currentTime.strftime ( buf, sizeof(buf), "%M:%S.%09f"); debugPrintf ( ("sent %u delay sec=%f Rts=%s\n", nFrameSent, this->period(), buf ) ); } # endif return expireStatus ( restart, this->period ( guard ) ); }