added new functionality to allow replacement of vxWorks watchdogs

This commit is contained in:
Jeff Hill
1999-11-04 01:32:37 +00:00
parent 351971a749
commit 982dc928e7
2 changed files with 147 additions and 103 deletions

View File

@@ -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<osiTimer> iter = this->queue.pending.last();
tsDLIterBD<osiTimer> iter = queueIn.pending.last();
while (1) {
if (iter==tsDLIterBD<osiTimer>::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;
}
}
}

View File

@@ -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 ();
};
//