From 982dc928e7645affd7ced26bed89fac622369fc3 Mon Sep 17 00:00:00 2001 From: Jeff Hill Date: Thu, 4 Nov 1999 01:32:37 +0000 Subject: [PATCH] added new functionality to allow replacement of vxWorks watchdogs --- src/libCom/timer/osiTimer.cpp | 184 +++++++++++++++++++--------------- src/libCom/timer/osiTimer.h | 66 ++++++++---- 2 files changed, 147 insertions(+), 103 deletions(-) diff --git a/src/libCom/timer/osiTimer.cpp b/src/libCom/timer/osiTimer.cpp index 711b1e2f8..beffa9ed9 100644 --- a/src/libCom/timer/osiTimer.cpp +++ b/src/libCom/timer/osiTimer.cpp @@ -45,10 +45,82 @@ osiTimerQueue osiDefaultTimerQueue; +// +// osiTimer::osiTimer () +// +// create an active timer that will expire in delay seconds +// +epicsShareFunc osiTimer::osiTimer (double delay, osiTimerQueue & queueIn) +{ + this->arm (queueIn, delay); +} + +// +// osiTimer::osiTimer () +// +// create an inactive timer +// +epicsShareFunc osiTimer::osiTimer () : +curState (osiTimer::stateLimbo), pQueue (0) +{ +} + +// +// osiTimer::~osiTimer() +// +epicsShareFunc osiTimer::~osiTimer() +{ + this->cleanup (); +} + +// +// osiTimer::cancel () +// +epicsShareFunc void osiTimer::cancel () +{ + this->cleanup (); + this->destroy (); +} + +// +// osiTimer::cleanup () +// +void osiTimer::cleanup () +{ + if (this->pQueue) { + // + // signal the timer queue if this + // occurrring during the expire call + // back + // + if (this == this->pQueue->pExpireTmr) { + this->pQueue->pExpireTmr = 0; + } + switch (this->curState) { + case statePending: + this->pQueue->pending.remove(*this); + break; + case stateExpired: + this->pQueue->expired.remove(*this); + break; + case stateLimbo: + break; + default: + assert(0); + } + this->pQueue = NULL; + this->curState = stateLimbo; + } + else { + assert (this->curState==stateLimbo); + } +} + + // // osiTimer::arm() // -epicsShareFunc void osiTimer::arm (double *pInitialDelay) +void osiTimer::arm (osiTimerQueue & queueIn, double initialDelay) { # ifdef DEBUG unsigned preemptCount=0u; @@ -56,15 +128,8 @@ epicsShareFunc void osiTimer::arm (double *pInitialDelay) // // calculate absolute expiration time - // (dont call base's delay() virtual func - // in the constructor) // - if (pInitialDelay) { - this->exp = osiTime::getCurrent() + *pInitialDelay; - } - else { - this->exp = osiTime::getCurrent() + this->delay(); - } + this->exp = osiTime::getCurrent() + initialDelay; // // insert into the pending queue @@ -74,20 +139,20 @@ epicsShareFunc void osiTimer::arm (double *pInitialDelay) // // **** this should use a binary tree ???? // - tsDLIterBD iter = this->queue.pending.last(); + tsDLIterBD iter = queueIn.pending.last(); while (1) { if (iter==tsDLIterBD::eol()) { // // add to the beginning of the list // - this->queue.pending.push (*this); + queueIn.pending.push (*this); break; } if (iter->exp <= this->exp) { // // add after the item found that expires earlier // - this->queue.pending.insertAfter (*this, *iter); + queueIn.pending.insertAfter (*this, *iter); break; } # ifdef DEBUG @@ -95,59 +160,26 @@ epicsShareFunc void osiTimer::arm (double *pInitialDelay) # endif --iter; } + this->curState = osiTimer::statePending; + this->pQueue = &queueIn; # ifdef DEBUG this->queue.show(10u); # endif # ifdef DEBUG - double theDelay; - if (pInitialDelay) { - theDelay = *pInitialDelay; - } - else { - theDelay = this->delay(); - } // // name virtual function isnt always useful here because this is // often called inside the constructor (unless we are // rearming the same timer) // printf ("Arm of \"%s\" with delay %f at %lx preempting %u\n", - this->name(), theDelay, (unsigned long)this, preemptCount); + this->name(), initialDelay, (unsigned long)this, preemptCount); # endif } -// -// osiTimer::~osiTimer() -// -epicsShareFunc osiTimer::~osiTimer() -{ - // - // signal the timer queue if this - // was deleted during its expire call - // back - // - if (this == this->queue.pExpireTmr) { - this->queue.pExpireTmr = 0; - } - switch (this->curState) { - case osiTimer::statePending: - this->queue.pending.remove(*this); - break; - case osiTimer::stateExpired: - this->queue.expired.remove(*this); - break; - case osiTimer::stateLimbo: - break; - default: - assert(0); - } - this->curState = osiTimer::stateLimbo; -} - // // osiTimer::again() // @@ -178,18 +210,11 @@ epicsShareFunc double osiTimer::delay() const epicsShareFunc void osiTimer::show (unsigned level) const { osiTime cur(osiTime::getCurrent()); - double delay; printf ("osiTimer at %p for \"%s\" with again = %d\n", this, this->name(), this->again()); - if (this->exp >= cur) { - delay = this->exp - cur; - } - else { - delay = cur - this->exp; - delay = -delay; - } if (level>=1u) { + double delay = this->exp - cur; printf ("\tdelay to expire = %f, state = %d\n", delay, this->curState); } @@ -269,17 +294,18 @@ void osiTimerQueue::process() pTmr->expire(); if (this->pExpireTmr == pTmr) { if (pTmr->again()) { - pTmr->arm(); + pTmr->arm (*pTmr->pQueue, pTmr->delay()); } else { - pTmr->destroy(); + pTmr->pQueue = NULL; + pTmr->destroy (); } } else { // // no recursive calls to process allowed // - assert(this->pExpireTmr == 0); + assert (this->pExpireTmr == 0); } } this->inProcess = false; @@ -332,36 +358,27 @@ epicsShareFunc const char *osiTimer::name() const return "osiTimer"; } +// +// osiTimer::reschedule() +// +// pull this timer out of the queue and reinstall +// it with a new experation time +// +epicsShareFunc void osiTimer::reschedule (osiTimerQueue & queueIn) +{ + this->reschedule (this->delay(), queueIn); +} + // // osiTimer::reschedule() // // pull this timer out of the queue ans reinstall // it with a new experation time // -epicsShareFunc void osiTimer::reschedule (double newDelay) +epicsShareFunc void osiTimer::reschedule (double newDelay, osiTimerQueue & queueIn) { - // - // signal the timer queue if this - // occurrring during the expire call - // back - // - if (this == this->queue.pExpireTmr) { - this->queue.pExpireTmr = 0; - } - switch (this->curState) { - case osiTimer::statePending: - this->queue.pending.remove(*this); - break; - case osiTimer::stateExpired: - this->queue.expired.remove(*this); - break; - case osiTimer::stateLimbo: - break; - default: - assert(0); - } - this->curState = osiTimer::stateLimbo; - this->arm (&newDelay); + this->cleanup (); + this->arm (queueIn, newDelay); } // @@ -379,4 +396,5 @@ epicsShareFunc double osiTimer::timeRemaining () else { return 0.0; } -} \ No newline at end of file +} + diff --git a/src/libCom/timer/osiTimer.h b/src/libCom/timer/osiTimer.h index c22f460d7..0ff76b1e8 100644 --- a/src/libCom/timer/osiTimer.h +++ b/src/libCom/timer/osiTimer.h @@ -50,14 +50,43 @@ public: // class noDelaySpecified {}; - epicsShareFunc osiTimer (double delay, osiTimerQueue & queueIn = osiDefaultTimerQueue) : - queue (queueIn) - { - this->arm (&delay); - } + // + // create an active timer that will expire in delay seconds + // + epicsShareFunc osiTimer (double delay, osiTimerQueue & queueIn = osiDefaultTimerQueue); + + // + // create an inactive timer + // + epicsShareFunc osiTimer (); + epicsShareFunc virtual ~osiTimer(); + // + // change the timers expiration to newDelay + // seconds after when reschedule() is called + // + epicsShareFunc void reschedule (double newDelay, osiTimerQueue & queueIn = osiDefaultTimerQueue); + + // + // change the timers expiration to this->delay() + // seconds after when reschedule() is called + // + epicsShareFunc void reschedule (osiTimerQueue & queueIn = osiDefaultTimerQueue); + + // + // inactivate the timer and call the virtual destroy() + // member function + // + epicsShareFunc void cancel (); + + // + // return the number of seconds remaining before + // this osiTimer will expire + // + epicsShareFunc double timeRemaining(); + // // called when the osiTimer expires // @@ -66,9 +95,13 @@ public: // // called if // 1) osiTimer exists and the osiTimerQueue is deleted - // 2) when the osiTimer expies and again() returs false + // 2) when the osiTimer expires and again() returs false // // osiTimer::destroy() does a "delete this" + // + // if the derived class replaces this function then it + // is taking responsibility for freeing (deleting) + // timer resources when they are nolonger needed. // epicsShareFunc virtual void destroy(); @@ -94,17 +127,6 @@ public: // epicsShareFunc virtual double delay() const; - // - // change the timers expiration to newDelay - // seconds after when reschedule() is called - // - epicsShareFunc void reschedule (double newDelay); - - // - // return the number of seconds remaining before - // this osiTimer will expire - // - epicsShareFunc double timeRemaining(); epicsShareFunc virtual void show (unsigned level) const; @@ -118,13 +140,17 @@ private: osiTime exp; // experation time state curState; // current state - osiTimerQueue &queue; + osiTimerQueue *pQueue; // pointer to current timer queue // - // arm() // place osiTimer in the pending queue // - epicsShareFunc void arm (double *pInitialDelay=0); + void arm (osiTimerQueue & queueIn, double initialDelay); + + // + // detach from any timer queues + // + void cleanup (); }; //