timer and timeStamp added to misc. copyright and license info added
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -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 */
|
||||
Reference in New Issue
Block a user