timer and timeStamp added to misc. copyright and license info added

This commit is contained in:
Marty Kraimer
2010-11-23 07:30:13 -05:00
parent 28aad96b34
commit 9db054cc54
100 changed files with 1376 additions and 7236 deletions
+2
View File
@@ -19,6 +19,7 @@ INC += executor.h
INC += showConstructDestruct.h
INC += timeStamp.h
INC += timeFunction.h
INC += timer.h
LIBSRCS += byteBuffer.cpp
LIBSRCS += bitSet.cpp
@@ -30,6 +31,7 @@ LIBSRCS += thread.cpp
LIBSRCS += executor.cpp
LIBSRCS += timeStamp.cpp
LIBSRCS += timeFunction.cpp
LIBSRCS += timer.cpp
LIBRARY=pvMisc
+6
View File
@@ -1,3 +1,9 @@
/* bitSet.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include "string.h"
#include "stdio.h"
#include "bitSet.h"
+5
View File
@@ -1,4 +1,9 @@
/* bitSet.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef BITSET_H
#define BITSET_H
#include <stdexcept>
+5
View File
@@ -1,3 +1,8 @@
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/*
* byteBuffer.cpp
*
+5
View File
@@ -1,4 +1,9 @@
/* byteBuffer.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef BYTEBUFFER_H
#define BYTEBUFFER_H
+5
View File
@@ -1,3 +1,8 @@
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/*
* epicsException.hpp
*
+5
View File
@@ -1,4 +1,9 @@
/* event.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <cstddef>
#include <cstdlib>
#include <cstddef>
+5
View File
@@ -1,4 +1,9 @@
/* event.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef EVENT_H
#define EVENT_H
#include <memory>
+10 -1
View File
@@ -1,4 +1,9 @@
/* executor.h */
/* executor.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <cstddef>
#include <cstdlib>
#include <cstddef>
@@ -186,6 +191,10 @@ Executor::~Executor() {
totalDestruct++;
}
Executor *Executor::create(String threadName,ThreadPriority priority)
{
return new Executor(threadName,priority);
}
ExecutorNode * Executor::createNode(Command*command)
{return pImpl->createNode(command);}
+7 -1
View File
@@ -1,4 +1,9 @@
/* executor.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef EXECUTOR_H
#define EXECUTOR_H
#include <memory>
@@ -19,12 +24,13 @@ public:
class Executor : private NoDefaultMethods {
public:
Executor(String threadName,ThreadPriority priority);
static ConstructDestructCallback *getConstructDestructCallback();
static Executor *create(String threadName,ThreadPriority priority);
ExecutorNode * createNode(Command *command);
void execute(ExecutorNode *node);
void destroy();
private:
Executor(String threadName,ThreadPriority priority);
~Executor();
class ExecutorPvt *pImpl;
};
+5
View File
@@ -1,4 +1,9 @@
/* linkedList.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include "linkedListVoid.h"
+5
View File
@@ -1,4 +1,9 @@
/* linkedListVoid.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <cstddef>
#include <cstdlib>
#include <cstddef>
+5
View File
@@ -1,4 +1,9 @@
/* linkedListVoid.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include "pvType.h"
#include "showConstructDestruct.h"
+5
View File
@@ -1,4 +1,9 @@
/* lock.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef LOCK_H
#define LOCK_H
#include <epicsMutex.h>
+5
View File
@@ -1,4 +1,9 @@
/* noDefaultMethods.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef NO_DEFAULT_METHODS_H
#define NO_DEFAULT_METHODS_H
namespace epics { namespace pvData {
+5
View File
@@ -1,4 +1,9 @@
/* pvType.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <string>
#ifndef PVTYPE_H
#define PVTYPE_H
+5
View File
@@ -1,4 +1,9 @@
/* requester.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <string>
#ifndef REQUESTER_H
#define REQUESTER_H
+5
View File
@@ -1,4 +1,9 @@
/* serialize.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef SERIALIZE_H
#define SERIALIZE_H
#include "bitSet.h"
+5
View File
@@ -1,3 +1,8 @@
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/*
* serializeHelper.cpp
*
+5
View File
@@ -1,3 +1,8 @@
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
/*
* serializeHelper.h
*
+5
View File
@@ -1,4 +1,9 @@
/* showConstructDestruct.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <stddef.h>
#include <stdlib.h>
#include <stddef.h>
+5
View File
@@ -1,4 +1,9 @@
/* showConstructDestruct.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef SHOWCONSTRUCTDESTRUCT_H
#define SHOWCONSTRUCTDESTRUCT_H
#include <stddef.h>
+5
View File
@@ -1,4 +1,9 @@
/* thread.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <cstddef>
#include <cstdlib>
#include <cstddef>
+5
View File
@@ -1,4 +1,9 @@
/* thread.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef THREAD_H
#define THREAD_H
#include "noDefaultMethods.h"
+8 -3
View File
@@ -1,4 +1,9 @@
/* timeFunction.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include "noDefaultMethods.h"
#include "pvType.h"
#include "timeStamp.h"
@@ -27,15 +32,15 @@ TimeFunction::~TimeFunction() {}
double TimeFunction::timeCall()
{
TimeStamp startTime(0,0);
TimeStamp endTime(0,0);
TimeStamp startTime;
TimeStamp endTime;
double perCall = 0.0;
long ntimes = 1;
while(true) {
startTime.getCurrent();
for(long i=0; i<ntimes; i++) requester->function();
endTime.getCurrent();
double diff = TimeStamp::diffInSeconds(&endTime,&startTime);
double diff = TimeStamp::diff(endTime,startTime);
if(diff>=1.0) {
perCall = diff/(double)ntimes;
break;
+5
View File
@@ -1,4 +1,9 @@
/* timeFunction.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef TIMEFUNCTION_H
#define TIMEFUNCTION_H
#include "noDefaultMethods.h"
+117 -20
View File
@@ -1,4 +1,15 @@
/* timeStamp.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <cstddef>
#include <cstdlib>
#include <cstddef>
#include <string>
#include <cstdio>
#include <epicsTime.h>
#include "noDefaultMethods.h"
#include "pvType.h"
@@ -6,40 +17,126 @@
namespace epics { namespace pvData {
static uint64 TS_EPOCH_SEC_PAST_1970=7305*86400;
int32 milliSecPerSec = 1000;
int32 microSecPerSec = milliSecPerSec*milliSecPerSec;
int32 nanoSecPerSec = milliSecPerSec*microSecPerSec;
int64 posixEpochAtEpicsEpoch = POSIX_TIME_AT_EPICS_EPOCH;
TimeStamp::TimeStamp(uint64 secondsPastEpoch,uint32 nanoSeconds)
TimeStamp::TimeStamp(int64 secondsPastEpoch,int32 nanoSeconds)
: secondsPastEpoch(secondsPastEpoch),nanoSeconds(nanoSeconds)
{}
TimeStamp::~TimeStamp() {}
int64 TimeStamp::getEpicsSecondsPastEpoch()
{
return secondsPastEpoch - TS_EPOCH_SEC_PAST_1970;
}
void TimeStamp::put(uint64 seconds,uint32 nano)
{
secondsPastEpoch = seconds;
nanoSeconds = nano;
}
void TimeStamp::getCurrent()
{
epicsTimeStamp epicsTime;
epicsTimeGetCurrent(&epicsTime);
secondsPastEpoch = epicsTime.secPastEpoch;
secondsPastEpoch += TS_EPOCH_SEC_PAST_1970;
secondsPastEpoch += posixEpochAtEpicsEpoch;
nanoSeconds = epicsTime.nsec;
}
double TimeStamp::diffInSeconds(TimeStamp *left,TimeStamp *right)
double TimeStamp::toSeconds() const
{
double diff = left->secondsPastEpoch - right->secondsPastEpoch;
int64 nano =left->nanoSeconds - right->nanoSeconds;
diff += ((double)nano)/1e9;
return diff;
double value = secondsPastEpoch;
double nano = nanoSeconds;
value += nano/1e9;
return value;
}
int64 TimeStamp::diffInt(TimeStamp const & left,TimeStamp const&right )
{
int64 sl = left.secondsPastEpoch;
int32 nl = left.nanoSeconds;
int64 sr = right.secondsPastEpoch;
int32 nr = right.nanoSeconds;
int64 sdiff = sl - sr;
sdiff *= nanoSecPerSec;
sdiff += nl - nr;
return sdiff;
}
bool TimeStamp::operator==(TimeStamp const &right) const
{
int64 sdiff = diffInt(*this,right);
if(sdiff==0) return true;
return false;
}
bool TimeStamp::operator!=(TimeStamp const &right) const
{
int64 sdiff = diffInt(*this,right);
if(sdiff!=0) return true;
return false;
}
bool TimeStamp::operator<=(TimeStamp const &right) const
{
int64 sdiff = diffInt(*this,right);
if(sdiff<=0) return true;
return false;
}
bool TimeStamp::operator< (TimeStamp const &right) const
{
int64 sdiff = diffInt(*this,right);
if(sdiff<0) return true;
return false;
}
bool TimeStamp::operator>=(TimeStamp const &right) const
{
int64 sdiff = diffInt(*this,right);
if(sdiff>=0) return true;
return false;
}
bool TimeStamp::operator>(TimeStamp const &right) const
{
int64 sdiff = diffInt(*this,right);
if(sdiff>0) return true;
return false;
}
double TimeStamp::diff(TimeStamp const & a,TimeStamp const & b)
{
double result = a.secondsPastEpoch - b.secondsPastEpoch;
result += (a.nanoSeconds - b.nanoSeconds)/1e9;
return result;
}
TimeStamp & TimeStamp::operator+=(int64 seconds)
{
secondsPastEpoch += seconds;
return *this;
}
TimeStamp & TimeStamp::operator-=(int64 seconds)
{
secondsPastEpoch -= seconds;
return *this;
}
TimeStamp & TimeStamp::operator+=(double seconds)
{
int64 secs = seconds;
int64 nano = (seconds - secs)*1e9;
nanoSeconds += nano;
if(nanoSeconds>nanoSecPerSec) {
nanoSeconds -= nanoSecPerSec;
secondsPastEpoch += 1;
} else if(nanoSeconds<-nanoSecPerSec) {
nanoSeconds += -nanoSecPerSec;
secondsPastEpoch -= 1;
}
secondsPastEpoch += secs;
return *this;
}
TimeStamp & TimeStamp::operator-=(double seconds)
{
return operator+=(-seconds);
}
int64 TimeStamp::getMilliseconds()
+41 -9
View File
@@ -1,25 +1,57 @@
/* timeStamp.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef TIMESTAMP_H
#define TIMESTAMP_H
#include "noDefaultMethods.h"
#include "epicsTime.h"
#include "pvType.h"
namespace epics { namespace pvData {
class TimeStamp : private NoDefaultMethods {
extern int32 milliSecPerSec;
extern int32 microSecPerSec;
extern int32 nanoSecPerSec;
extern int64 posixEpochAtEpicsEpoch;
class TimeStamp {
public:
TimeStamp(uint64 secondsPastEpoch,uint32 nanoSeconds);
~TimeStamp();
int64 getSecondsPastEpoch(){return secondsPastEpoch;}
int32 getNanoSeconds() {return nanoSeconds;}
int64 getEpicsSecondsPastEpoch();
void put(uint64 secondsPastEpoch,uint32 nanoSeconds);
TimeStamp()
:secondsPastEpoch(0),nanoSeconds(0) {}
//default constructors and destructor are OK
//This class should not be extended
TimeStamp(int64 secondsPastEpoch,int32 nanoSeconds = 0);
TimeStamp(epicsTimeStamp &epics);
int64 getSecondsPastEpoch() const {return secondsPastEpoch;}
int64 getEpicsSecondsPastEpoch() const {
return secondsPastEpoch - posixEpochAtEpicsEpoch;
}
int32 getNanoSeconds() const {return nanoSeconds;}
void put(int64 secondsPastEpoch,int32 nanoSeconds = 0) {
this->secondsPastEpoch = secondsPastEpoch;
this->nanoSeconds = nanoSeconds;
}
void getCurrent();
static double diffInSeconds(TimeStamp *left,TimeStamp *right);
double toSeconds() const ;
bool operator==(TimeStamp const &) const;
bool operator!=(TimeStamp const &) const;
bool operator<=(TimeStamp const &) const;
bool operator< (TimeStamp const &) const;
bool operator>=(TimeStamp const &) const;
bool operator> (TimeStamp const &) const;
static double diff(TimeStamp const & a,TimeStamp const & b);
TimeStamp & operator+=(int64 seconds);
TimeStamp & operator-=(int64 seconds);
TimeStamp & operator+=(double seconds);
TimeStamp & operator-=(double seconds);
// milliseconds since epoch
int64 getMilliseconds();
void put(int64 milliseconds);
private:
static int64 diffInt(TimeStamp const &left,TimeStamp const &right );
int64 secondsPastEpoch;
int32 nanoSeconds;
};
+332
View File
@@ -0,0 +1,332 @@
/* timer.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <stddef.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include <stdexcept>
#include "pvType.h"
#include "lock.h"
#include "noDefaultMethods.h"
#include "showConstructDestruct.h"
#include "linkedList.h"
#include "thread.h"
#include "timeStamp.h"
#include "timer.h"
#include "event.h"
namespace epics { namespace pvData {
static volatile int64 totalNodeConstruct = 0;
static volatile int64 totalNodeDestruct = 0;
static volatile int64 totalTimerConstruct = 0;
static volatile int64 totalTimerDestruct = 0;
static Mutex *globalMutex = 0;
static int64 getTotalTimerNodeConstruct()
{
Lock xx(globalMutex);
return totalNodeConstruct;
}
static int64 getTotalTimerNodeDestruct()
{
Lock xx(globalMutex);
return totalNodeDestruct;
}
static int64 getTotalTimerConstruct()
{
Lock xx(globalMutex);
return totalTimerConstruct;
}
static int64 getTotalTimerDestruct()
{
Lock xx(globalMutex);
return totalTimerDestruct;
}
static ConstructDestructCallback *pCDCallbackTimerNode;
static ConstructDestructCallback *pCDCallbackTimer;
static void init()
{
static Mutex mutex = Mutex();
Lock xx(&mutex);
if(globalMutex==0) {
globalMutex = new Mutex();
pCDCallbackTimerNode = new ConstructDestructCallback(
"timerNode",
getTotalTimerNodeConstruct,getTotalTimerNodeDestruct,0);
pCDCallbackTimer = new ConstructDestructCallback(
"timer",
getTotalTimerConstruct,getTotalTimerDestruct,0);
}
}
ConstructDestructCallback * TimerNode::getConstructDestructCallback()
{
init();
return pCDCallbackTimerNode;
}
ConstructDestructCallback * Timer::getConstructDestructCallback()
{
init();
return pCDCallbackTimer;
}
class TimerNodePvt;
typedef LinkedListNode<TimerNodePvt> ListNode;
typedef LinkedList<TimerNodePvt> List;
class TimerNodePvt {
public:
TimerNode *timerNode;
TimerCallback *callback;
ListNode *listNode;
TimeStamp timeToRun;
TimerPvt *timerPvt;
double period;
TimerNodePvt(TimerNode *timerNode,TimerCallback *callback);
~TimerNodePvt();
};
TimerNodePvt::TimerNodePvt(TimerNode *timerNode,TimerCallback *callback)
: timerNode(timerNode),callback(callback),
listNode(new ListNode(this)),timeToRun(TimeStamp()),
timerPvt(0), period(0.0)
{}
TimerNodePvt::~TimerNodePvt()
{
delete listNode;
}
struct TimerPvt : public RunnableReady {
public:
TimerPvt(String threadName,ThreadPriority priority);
~TimerPvt();
virtual void run(ThreadReady *threadReady);
public: // only used by this source module
List *list;
Mutex mutex;
Event *waitForWork;
Event *waitForDone;
Thread *thread;
volatile bool alive;
};
TimerPvt::TimerPvt(String threadName,ThreadPriority priority)
: list(new List()),
mutex(Mutex()),
waitForWork(new Event(eventEmpty)),
waitForDone(new Event(eventEmpty)),
thread(new Thread(threadName,priority,this)),
alive(true)
{
thread->start();
}
TimerPvt::~TimerPvt()
{
delete thread;
delete waitForDone;
delete waitForWork;
delete list;
}
static void addElement(TimerPvt *timer,TimerNodePvt *node)
{
List *list = timer->list;
ListNode *nextNode = list->getHead();
if(nextNode==0) {
list->addTail(node->listNode);
return;
}
while(true) {
TimerNodePvt *listNode = nextNode->getObject();
if((node->timeToRun)<(listNode->timeToRun)) {
list->insertBefore(listNode->listNode,node->listNode);
return;
}
nextNode = list->getNext(listNode->listNode);
if(nextNode==0) {
list->addTail(node->listNode);
return;
}
}
}
TimerNode::TimerNode(TimerCallback *callback)
: pImpl(new TimerNodePvt(this,callback))
{
init();
Lock xx(globalMutex);
totalNodeConstruct++;
}
TimerNode *TimerNode::create(TimerCallback *callback)
{
return new TimerNode(callback);
}
TimerNode::~TimerNode()
{
delete pImpl;
Lock xx(globalMutex);
totalNodeDestruct++;
}
void TimerNode::destroy()
{
cancel();
delete this;
}
void TimerNode::cancel()
{
TimerPvt *timerPvt = pImpl->timerPvt;
if(timerPvt==0) return;
Lock xx(&timerPvt->mutex);
if(pImpl->timerPvt==0) return;
pImpl->timerPvt->list->remove(pImpl);
pImpl->timerPvt = 0;
}
bool TimerNode::isScheduled()
{
TimerPvt *pvt = pImpl->timerPvt;
if(pvt==0) return false;
Lock xx(&pvt->mutex);
return pImpl->listNode->isOnList();
}
void TimerPvt::run(ThreadReady *threadReady)
{
threadReady->ready();
TimeStamp currentTime;
while(alive) {
currentTime.getCurrent();
TimeStamp *timeToRun = 0;
double period = 0.0;
TimerNodePvt *nodeToCall = 0;
{
Lock xx(&mutex);
ListNode *listNode = list->getHead();
if(listNode!=0) {
TimerNodePvt *timerNodePvt = listNode->getObject();
timeToRun = &timerNodePvt->timeToRun;
double diff = TimeStamp::diff(
*timeToRun,currentTime);
if(diff<=0.0) {
nodeToCall = timerNodePvt;
list->removeHead();
period = timerNodePvt->period;
if(period>0) {
timerNodePvt->timeToRun += period;
addElement(this,timerNodePvt);
} else {
timerNodePvt->timerPvt = 0;
}
listNode = list->getHead();
if(listNode!=0) {
timerNodePvt = listNode->getObject();
timeToRun = &timerNodePvt->timeToRun;
} else {
timeToRun = 0;
}
}
}
}
if(nodeToCall!=0) {
nodeToCall->callback->callback();
}
if(!alive) break;
if(timeToRun==0) {
waitForWork->wait();
} else {
double delay = TimeStamp::diff(*timeToRun,currentTime);
waitForWork->wait(delay);
}
}
waitForDone->signal();
}
Timer::Timer(String threadName, ThreadPriority priority)
: pImpl(new TimerPvt(threadName,priority))
{
init();
Lock xx(globalMutex);
totalTimerConstruct++;
}
Timer * Timer::create(String threadName, ThreadPriority priority)
{
return new Timer(threadName,priority);
}
Timer::~Timer() {
delete pImpl;
Lock xx(globalMutex);
totalTimerDestruct++;
}
void Timer::destroy()
{
{
Lock xx(&pImpl->mutex);
pImpl->alive = false;
pImpl->waitForWork->signal();
pImpl->waitForDone->wait();
}
List *list = pImpl->list;
ListNode *node = 0;
while((node = list->removeHead())!=0) {
node->getObject()->callback->timerStopped();
}
delete this;
}
void Timer::scheduleAfterDelay(TimerNode *timerNode,double delay)
{
schedulePeriodic(timerNode,delay,0.0);
}
void Timer::schedulePeriodic(TimerNode *timerNode,double delay,double period)
{
TimerNodePvt *timerNodePvt = timerNode->pImpl;
if(timerNodePvt->listNode->isOnList()) {
throw std::logic_error(String("already queued"));
}
if(!pImpl->alive) {
timerNodePvt->callback->timerStopped();
return;
}
TimeStamp *timeStamp = &timerNodePvt->timeToRun;
timeStamp->getCurrent();
*timeStamp += delay;
timerNodePvt->period = period;
bool isFirst = false;
{
Lock xx(&pImpl->mutex);
timerNodePvt->timerPvt = pImpl;
addElement(pImpl,timerNodePvt);
TimerNodePvt *first = pImpl->list->getHead()->getObject();
if(first==timerNodePvt) isFirst = true;
}
if(isFirst) pImpl->waitForWork->signal();
}
}}
+57
View File
@@ -0,0 +1,57 @@
/* timer.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef TIMER_H
#define TIMER_H
#include <stddef.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include "pvType.h"
#include "thread.h"
#include "noDefaultMethods.h"
#include "showConstructDestruct.h"
namespace epics { namespace pvData {
class TimerCallback {
public:
virtual void callback() = 0;
virtual void timerStopped() = 0;
};
class TimerNode : private NoDefaultMethods {
public:
static ConstructDestructCallback *getConstructDestructCallback();
static TimerNode *create(TimerCallback *timerCallback);
void destroy();
void cancel();
bool isScheduled();
private:
TimerNode(TimerCallback *timerCallback);
~TimerNode();
class TimerNodePvt *pImpl;
friend class Timer;
};
class Timer : private NoDefaultMethods {
public:
static ConstructDestructCallback *getConstructDestructCallback();
static Timer * create(String threadName, ThreadPriority priority);
void destroy();
void scheduleAfterDelay(TimerNode *timerNode,double delay);
void schedulePeriodic(TimerNode *timerNode,double delay,double period);
private:
Timer(String threadName, ThreadPriority priority);
~Timer();
class TimerPvt *pImpl;
friend class TimerNode;
};
}}
#endif /* TIMER_H */