232 lines
7.2 KiB
C++
232 lines
7.2 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:
|
|
void destroy ();
|
|
void start ( class epicsTimerNotify &, const epicsTime & );
|
|
void start ( class epicsTimerNotify &, double delaySeconds );
|
|
void cancel ();
|
|
expireInfo getExpireInfo () const;
|
|
void show ( unsigned int level ) const;
|
|
class timerQueue & getPrivTimerQueue ();
|
|
protected:
|
|
timer ( class timerQueue & );
|
|
~timer ();
|
|
private:
|
|
enum state { statePending = 45, stateLimbo = 78 };
|
|
epicsTime exp; // experation time
|
|
state curState; // current state
|
|
epicsTimerNotify *pNotify; // callback
|
|
timerQueue &queue;
|
|
void privateStart ( epicsTimerNotify & notify, const epicsTime & );
|
|
void privateCancel ( epicsAutoMutex & );
|
|
timer & operator = ( const timer & );
|
|
friend class timerQueue;
|
|
};
|
|
|
|
struct epicsTimerForC : public epicsTimerNotify, public timer {
|
|
public:
|
|
void destroy ();
|
|
protected:
|
|
epicsTimerForC ( timerQueue &, epicsTimerCallback, void *pPrivateIn );
|
|
~epicsTimerForC ();
|
|
private:
|
|
epicsTimerCallback pCallBack;
|
|
void * pPrivate;
|
|
expireStatus expire ( const epicsTime & currentTime );
|
|
epicsTimerForC & operator = ( const epicsTimerForC & );
|
|
friend class timerQueue;
|
|
};
|
|
|
|
class timerQueue : public epicsTimerQueue {
|
|
public:
|
|
timerQueue ( epicsTimerQueueNotify ¬ify );
|
|
virtual ~timerQueue ();
|
|
double process ( const epicsTime & currentTime );
|
|
epicsTimer & createTimer ();
|
|
void show ( unsigned int level ) const;
|
|
epicsTimerForC & createTimerForC ( epicsTimerCallback, void *pPrivateIn );
|
|
void destroyTimerForC ( epicsTimerForC & );
|
|
private:
|
|
mutable epicsMutex mutex;
|
|
tsFreeList < class timer, 0x20 > timerFreeList;
|
|
tsFreeList < epicsTimerForC, 0x20 > cTimerfreeList;
|
|
epicsEvent cancelBlockingEvent;
|
|
tsDLList < timer > timerList;
|
|
epicsTimerQueueNotify ¬ify;
|
|
timer *pExpireTmr;
|
|
epicsThreadId processThread;
|
|
bool cancelPending;
|
|
timerQueue ( const timerQueue & );
|
|
timerQueue & operator = ( const timerQueue & );
|
|
friend class timer;
|
|
};
|
|
|
|
class timerQueueActiveMgrPrivate { // X aCC 655
|
|
public:
|
|
timerQueueActiveMgrPrivate ();
|
|
protected:
|
|
virtual ~timerQueueActiveMgrPrivate () = 0;
|
|
private:
|
|
unsigned referenceCount;
|
|
friend class timerQueueActiveMgr;
|
|
};
|
|
|
|
class timerQueueActive : public epicsTimerQueueActive,
|
|
public epicsThreadRunable, public epicsTimerQueueNotify,
|
|
public timerQueueActiveMgrPrivate {
|
|
public:
|
|
timerQueueActive ( bool okToShare, unsigned priority );
|
|
virtual ~timerQueueActive () = 0;
|
|
epicsTimer & createTimer ();
|
|
void show ( unsigned int level ) const;
|
|
bool sharingOK () const;
|
|
unsigned threadPriority () const;
|
|
epicsTimerForC & createTimerForC ( epicsTimerCallback, void *pPrivateIn );
|
|
void destroyTimerForC ( epicsTimerForC & );
|
|
private:
|
|
timerQueue queue;
|
|
epicsEvent rescheduleEvent;
|
|
epicsEvent exitEvent;
|
|
epicsThread thread;
|
|
bool okToShare;
|
|
bool exitFlag;
|
|
bool terminateFlag;
|
|
void run ();
|
|
void reschedule ();
|
|
epicsTimerQueue & getEpicsTimerQueue ();
|
|
timerQueueActive ( const timerQueueActive & );
|
|
timerQueueActive & operator = ( const timerQueueActive & );
|
|
};
|
|
|
|
struct epicsTimerQueueActiveForC : public timerQueueActive,
|
|
public tsDLNode < epicsTimerQueueActiveForC > {
|
|
public:
|
|
epicsTimerQueueActiveForC ( bool okToShare, unsigned priority );
|
|
void release ();
|
|
void * operator new ( size_t size );
|
|
void operator delete ( void *pCadaver, size_t size );
|
|
protected:
|
|
virtual ~epicsTimerQueueActiveForC ();
|
|
private:
|
|
static tsFreeList < epicsTimerQueueActiveForC > freeList;
|
|
static epicsMutex freeListMutex;
|
|
epicsTimerQueueActiveForC ( const epicsTimerQueueActiveForC & );
|
|
epicsTimerQueueActiveForC & operator = ( const epicsTimerQueueActiveForC & );
|
|
};
|
|
|
|
class timerQueueActiveMgr {
|
|
public:
|
|
timerQueueActiveMgr ();
|
|
~timerQueueActiveMgr ();
|
|
epicsTimerQueueActiveForC & allocate ( bool okToShare,
|
|
unsigned threadPriority = epicsThreadPriorityMin + 10 );
|
|
void release ( epicsTimerQueueActiveForC & );
|
|
private:
|
|
epicsMutex mutex;
|
|
tsDLList < epicsTimerQueueActiveForC > sharedQueueList;
|
|
timerQueueActiveMgr ( const timerQueueActiveMgr & );
|
|
timerQueueActiveMgr & operator = ( const timerQueueActiveMgr & );
|
|
};
|
|
|
|
extern timerQueueActiveMgr queueMgr;
|
|
|
|
class timerQueuePassive : public epicsTimerQueuePassive {
|
|
public:
|
|
timerQueuePassive ( epicsTimerQueueNotify & );
|
|
epicsTimer & createTimer ();
|
|
void show ( unsigned int level ) const;
|
|
double process ( const epicsTime & currentTime );
|
|
epicsTimerForC & createTimerForC ( epicsTimerCallback, void *pPrivateIn );
|
|
void destroyTimerForC ( epicsTimerForC & );
|
|
protected:
|
|
timerQueue queue;
|
|
~timerQueuePassive ();
|
|
epicsTimerQueue & getEpicsTimerQueue ();
|
|
timerQueuePassive ( const timerQueuePassive & );
|
|
timerQueuePassive & operator = ( const timerQueuePassive & );
|
|
};
|
|
|
|
inline epicsTimerForC & timerQueue::createTimerForC
|
|
( epicsTimerCallback pCB, void *pPriv )
|
|
{
|
|
epicsAutoMutex autoLock ( this->mutex );
|
|
void *pBuf = this->cTimerfreeList.allocate ( sizeof (epicsTimerForC) );
|
|
if ( ! pBuf ) {
|
|
throw std::bad_alloc();
|
|
}
|
|
return * new ( pBuf ) epicsTimerForC ( *this, pCB, pPriv );
|
|
}
|
|
|
|
inline void timerQueue::destroyTimerForC ( epicsTimerForC & tmr )
|
|
{
|
|
tmr.~epicsTimerForC ();
|
|
this->cTimerfreeList.release ( &tmr, sizeof ( tmr ) );
|
|
}
|
|
|
|
inline bool timerQueueActive::sharingOK () const
|
|
{
|
|
return this->okToShare;
|
|
}
|
|
|
|
inline unsigned timerQueueActive::threadPriority () const
|
|
{
|
|
return thread.getPriority ();
|
|
}
|
|
|
|
inline void * epicsTimerQueueActiveForC::operator new ( size_t size )
|
|
{
|
|
epicsAutoMutex locker ( epicsTimerQueueActiveForC::freeListMutex );
|
|
return epicsTimerQueueActiveForC::freeList.allocate ( size );
|
|
}
|
|
|
|
inline void epicsTimerQueueActiveForC::operator delete ( void *pCadaver, size_t size )
|
|
{
|
|
epicsAutoMutex locker ( epicsTimerQueueActiveForC::freeListMutex );
|
|
epicsTimerQueueActiveForC::freeList.release ( pCadaver, size );
|
|
}
|
|
|
|
#endif // epicsTimerPrivate_h
|
|
|