231 lines
6.0 KiB
C++
231 lines
6.0 KiB
C++
/*
|
|
* $Id$
|
|
*
|
|
* Author Jeffrey O. Hill
|
|
* johill@lanl.gov
|
|
* 505 665 1831
|
|
*
|
|
* Experimental Physics and Industrial Control System (EPICS)
|
|
*
|
|
* Copyright 1991, the Regents of the University of California,
|
|
* and the University of Chicago Board of Governors.
|
|
*
|
|
* This software was produced under U.S. Government contracts:
|
|
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
|
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
|
*
|
|
* Initial development by:
|
|
* The Controls and Automation Group (AT-8)
|
|
* Ground Test Accelerator
|
|
* Accelerator Technology Division
|
|
* Los Alamos National Laboratory
|
|
*
|
|
* Co-developed with
|
|
* The Controls and Computing Group
|
|
* Accelerator Systems Division
|
|
* Advanced Photon Source
|
|
* Argonne National Laboratory
|
|
*
|
|
*/
|
|
|
|
#ifndef epicsTimerPrivate_h
|
|
#define epicsTimerPrivate_h
|
|
|
|
#include "tsFreeList.h"
|
|
#include "tsDLList.h"
|
|
#include "epicsTimer.h"
|
|
|
|
#ifdef DEBUG
|
|
# define debugPrintf(ARGSINPAREN) printf ARGSINPAREN
|
|
#else
|
|
# define debugPrintf(ARGSINPAREN)
|
|
#endif
|
|
|
|
class timer : public epicsTimer, public tsDLNode < timer > {
|
|
public:
|
|
timer ( epicsTimerNotify &, class timerQueue & );
|
|
void start ( const epicsTime & );
|
|
void start ( double delaySeconds );
|
|
void cancel ();
|
|
double getExpireDelay () const;
|
|
void show ( unsigned int level ) const;
|
|
void * operator new ( size_t size );
|
|
void operator delete ( void *pCadaver, size_t size );
|
|
class noMemory {}; // exception
|
|
protected:
|
|
~timer ();
|
|
private:
|
|
enum state { statePending = 45, stateLimbo = 78 };
|
|
epicsTime exp; // experation time
|
|
state curState; // current state
|
|
epicsTimerNotify ¬ify; // callback
|
|
timerQueue &queue;
|
|
void privateStart ( const epicsTime & );
|
|
void privateCancel ();
|
|
double privateDelayToFirstExpire () const;
|
|
static tsFreeList < class timer, 0x20 > freeList;
|
|
friend class timerQueue;
|
|
};
|
|
|
|
class timerQueue {
|
|
public:
|
|
timerQueue ( epicsTimerQueueNotify ¬ify );
|
|
~timerQueue ();
|
|
void process ();
|
|
double delayToFirstExpire () const;
|
|
void show ( unsigned int level ) const;
|
|
private:
|
|
mutable epicsMutex mutex;
|
|
epicsEvent cancelBlockingEvent;
|
|
tsDLList < timer > timerList;
|
|
epicsTimerQueueNotify ¬ify;
|
|
timer *pExpireTmr;
|
|
epicsThreadId processThread;
|
|
bool cancelPending;
|
|
friend class timer;
|
|
};
|
|
|
|
class timerQueueActiveMgrPrivate {
|
|
public:
|
|
timerQueueActiveMgrPrivate ();
|
|
protected:
|
|
virtual ~timerQueueActiveMgrPrivate () = 0;
|
|
private:
|
|
unsigned referenceCount;
|
|
friend class timerQueueActiveMgr;
|
|
};
|
|
|
|
class timerQueueActive : public epicsTimerQueue,
|
|
public epicsThreadRunable, public epicsTimerQueueNotify,
|
|
public timerQueueActiveMgrPrivate {
|
|
public:
|
|
timerQueueActive ( bool okToShare, unsigned priority );
|
|
~timerQueueActive () = 0;
|
|
epicsTimer & createTimer ( epicsTimerNotify & );
|
|
void show ( unsigned int level ) const;
|
|
bool sharingOK () const;
|
|
int threadPriority () const;
|
|
timerQueue & getTimerQueue ();
|
|
private:
|
|
timerQueue queue;
|
|
epicsEvent rescheduleEvent;
|
|
epicsEvent exitEvent;
|
|
epicsThread thread;
|
|
bool okToShare;
|
|
bool exitFlag;
|
|
bool terminateFlag;
|
|
void run ();
|
|
void reschedule ();
|
|
};
|
|
|
|
struct epicsTimerQueueForC : public timerQueueActive,
|
|
public tsDLNode < epicsTimerQueueForC > {
|
|
public:
|
|
epicsTimerQueueForC ( bool okToShare, unsigned priority );
|
|
void release ();
|
|
void * operator new ( size_t size );
|
|
void operator delete ( void *pCadaver, size_t size );
|
|
protected:
|
|
virtual ~epicsTimerQueueForC ();
|
|
private:
|
|
static tsFreeList < epicsTimerQueueForC > freeList;
|
|
};
|
|
|
|
class timerQueueActiveMgr {
|
|
public:
|
|
~timerQueueActiveMgr ();
|
|
epicsTimerQueueForC & allocate ( bool okToShare,
|
|
int threadPriority = epicsThreadPriorityMin + 10 );
|
|
void release ( epicsTimerQueueForC & );
|
|
private:
|
|
epicsMutex mutex;
|
|
tsDLList < epicsTimerQueueForC > sharedQueueList;
|
|
};
|
|
|
|
extern timerQueueActiveMgr queueMgr;
|
|
|
|
class timerQueuePassive : public epicsTimerQueuePassive {
|
|
public:
|
|
timerQueuePassive ( epicsTimerQueueNotify & );
|
|
epicsTimer & createTimer ( epicsTimerNotify & );
|
|
void process ();
|
|
double getNextExpireDelay () const;
|
|
void show ( unsigned int level ) const;
|
|
void release ();
|
|
timerQueue & getTimerQueue ();
|
|
void * operator new ( size_t size );
|
|
void operator delete ( void *pCadaver, size_t size );
|
|
protected:
|
|
~timerQueuePassive ();
|
|
private:
|
|
timerQueue queue;
|
|
static tsFreeList < class timerQueuePassive, 0x8 > freeList;
|
|
};
|
|
|
|
inline void * timer::operator new ( size_t size )
|
|
{
|
|
return timer::freeList.allocate ( size );
|
|
}
|
|
|
|
inline void timer::operator delete ( void *pCadaver, size_t size )
|
|
{
|
|
timer::freeList.release ( pCadaver, size );
|
|
}
|
|
|
|
inline double timer::privateDelayToFirstExpire () const
|
|
{
|
|
if ( this->curState == statePending ) {
|
|
double delay = this->exp - epicsTime::getCurrent ();
|
|
if ( delay < 0.0 ) {
|
|
delay = 0.0;
|
|
}
|
|
return delay;
|
|
}
|
|
else {
|
|
return -DBL_MAX;
|
|
}
|
|
}
|
|
|
|
inline bool timerQueueActive::sharingOK () const
|
|
{
|
|
return this->okToShare;
|
|
}
|
|
|
|
inline int timerQueueActive::threadPriority () const
|
|
{
|
|
return thread.getPriority ();
|
|
}
|
|
|
|
inline timerQueue & timerQueueActive::getTimerQueue ()
|
|
{
|
|
return this->queue;
|
|
}
|
|
|
|
inline void * timerQueuePassive::operator new ( size_t size )
|
|
{
|
|
return timerQueuePassive::freeList.allocate ( size );
|
|
}
|
|
|
|
inline void timerQueuePassive::operator delete ( void *pCadaver, size_t size )
|
|
{
|
|
timerQueuePassive::freeList.release ( pCadaver, size );
|
|
}
|
|
|
|
inline timerQueue & timerQueuePassive::getTimerQueue ()
|
|
{
|
|
return this->queue;
|
|
}
|
|
|
|
inline void * epicsTimerQueueForC::operator new ( size_t size )
|
|
{
|
|
return epicsTimerQueueForC::freeList.allocate ( size );
|
|
}
|
|
|
|
inline void epicsTimerQueueForC::operator delete ( void *pCadaver, size_t size )
|
|
{
|
|
epicsTimerQueueForC::freeList.release ( pCadaver, size );
|
|
}
|
|
|
|
#endif // epicsTimerPrivate_h
|
|
|