added event thread executor timeFunction showConstructDestruct timeStamp

This commit is contained in:
Marty Kraimer
2010-11-17 11:14:38 -05:00
parent 8f082c5ea6
commit 6e90ae7f12
51 changed files with 1826 additions and 487 deletions

View File

@@ -3,6 +3,7 @@ include $(TOP)/configure/CONFIG
DIRS += misc
DIRS += pv
DIRS += factory
DIRS += property
DIRS += miscTest
DIRS += pvTest
include $(TOP)/configure/RULES_DIRS

View File

@@ -12,6 +12,58 @@ namespace epics { namespace pvData {
static String notImplemented("not implemented");
static volatile int64 totalConstruct = 0;
static volatile int64 totalDestruct = 0;
static Mutex *globalMutex = 0;
class CDCallbackPVField : public ConstructDestructCallback {
public:
CDCallbackPVField();
virtual String getConstructName();
virtual int64 getTotalConstruct();
virtual int64 getTotalDestruct();
virtual int64 getTotalReferenceCount();
private:
String name;
};
CDCallbackPVField::CDCallbackPVField()
: name("pvField")
{
getShowConstructDestruct()->registerCallback(this);
}
String CDCallbackPVField::getConstructName() {return name;}
int64 CDCallbackPVField::getTotalConstruct()
{
Lock xx(globalMutex);
return totalConstruct;
}
int64 CDCallbackPVField::getTotalDestruct()
{
Lock xx(globalMutex);
return totalDestruct;
}
int64 CDCallbackPVField::getTotalReferenceCount()
{
return 0;
}
static ConstructDestructCallback *pConstructDestructCallback;
static void init()
{
static Mutex mutex = Mutex();
Lock xx(&mutex);
if(globalMutex==0) {
globalMutex = new Mutex();
pConstructDestructCallback = new CDCallbackPVField();
}
}
class PVFieldPvt {
public:
PVFieldPvt(PVStructure *parent,FieldConstPtr field);
@@ -42,31 +94,11 @@ PVFieldPvt::~PVFieldPvt()
}
static volatile int64 totalConstruct = 0;
static volatile int64 totalDestruct = 0;
static Mutex *globalMutex = 0;
void PVField::init()
{
globalMutex = new Mutex();
}
int64 PVField::getTotalConstruct()
{
Lock xx(globalMutex);
return totalConstruct;
}
int64 PVField::getTotalDestruct()
{
Lock xx(globalMutex);
return totalDestruct;
}
PVField::PVField(PVStructure *parent,FieldConstPtr field)
: pImpl(new PVFieldPvt(parent,field))
{
init();
Lock xx(globalMutex);
totalConstruct++;
}
@@ -78,6 +110,13 @@ PVField::~PVField()
delete pImpl;
}
ConstructDestructCallback *PVField::getConstructDestructCallback()
{
init();
return pConstructDestructCallback;
}
String PVField::getRequesterName()
{
static String none("none");

View File

@@ -9,270 +9,307 @@
namespace epics { namespace pvData {
static DebugLevel debugLevel = lowDebug;
static void newLine(StringBuilder buffer, int indentLevel)
{
*buffer += "\n";
for(int i=0; i<indentLevel; i++) *buffer += " ";
}
static DebugLevel debugLevel = lowDebug;
class FieldPvt {
public :
FieldPvt(String fieldName,Type type);
String fieldName;
Type type;
mutable volatile int referenceCount;
};
static void newLine(StringBuilder buffer, int indentLevel)
{
*buffer += "\n";
for(int i=0; i<indentLevel; i++) *buffer += " ";
}
FieldPvt::FieldPvt(String fieldName,Type type)
: fieldName(fieldName),type(type),referenceCount(0) { }
class FieldPvt {
public :
FieldPvt(String fieldName,Type type);
String fieldName;
Type type;
mutable volatile int referenceCount;
};
static volatile int totalReferenceCount = 0;
static volatile int64 totalConstruct = 0;
static volatile int64 totalDestruct = 0;
static Mutex *globalMutex;
FieldPvt::FieldPvt(String fieldName,Type type)
: fieldName(fieldName),type(type),referenceCount(0) { }
int Field::getTotalReferenceCount()
{
Lock xx(globalMutex);
return totalReferenceCount;
}
static volatile int64 totalReferenceCount = 0;
static volatile int64 totalConstruct = 0;
static volatile int64 totalDestruct = 0;
static Mutex *globalMutex = 0;
int64 Field::getTotalConstruct()
{
Lock xx(globalMutex);
return totalConstruct;
}
class CDCallbackPVIntrospect : public ConstructDestructCallback {
public:
CDCallbackPVIntrospect();
virtual String getConstructName();
virtual int64 getTotalConstruct();
virtual int64 getTotalDestruct();
virtual int64 getTotalReferenceCount();
private:
String name;
};
int64 Field::getTotalDestruct()
{
Lock xx(globalMutex);
return totalDestruct;
}
CDCallbackPVIntrospect::CDCallbackPVIntrospect()
: name("field")
{
getShowConstructDestruct()->registerCallback(this);
}
Field::Field(String fieldName,Type type)
: pImpl(new FieldPvt(fieldName,type))
{
Lock xx(globalMutex);
totalConstruct++;
}
String CDCallbackPVIntrospect::getConstructName()
{
return name;
}
Field::~Field() {
Lock xx(globalMutex);
totalDestruct++;
// note that compiler automatically calls destructor for fieldName
delete pImpl;
if(debugLevel==highDebug) printf("~Field %s\n",pImpl->fieldName.c_str());
}
int64 CDCallbackPVIntrospect::getTotalConstruct()
{
Lock xx(globalMutex);
return totalConstruct;
}
int Field::getReferenceCount() const {
Lock xx(globalMutex);
return pImpl->referenceCount;
}
String Field::getFieldName() const {return pImpl->fieldName;}
Type Field::getType() const {return pImpl->type;}
int64 CDCallbackPVIntrospect::getTotalDestruct()
{
Lock xx(globalMutex);
return totalDestruct;
}
void Field::incReferenceCount() const {
Lock xx(globalMutex);
pImpl->referenceCount++;
totalReferenceCount++;
}
int64 CDCallbackPVIntrospect::getTotalReferenceCount()
{
return totalReferenceCount;
}
void Field::decReferenceCount() const {
Lock xx(globalMutex);
if(pImpl->referenceCount<=0) {
String message("logicError field ");
message += pImpl->fieldName;
throw std::logic_error(message);
}
pImpl->referenceCount--;
totalReferenceCount--;
if(pImpl->referenceCount==0) delete this;
}
static ConstructDestructCallback *pConstructDestructCallback;
void Field::toString(StringBuilder buffer,int indentLevel) const{
*buffer += " ";
*buffer += pImpl->fieldName.c_str();
}
Scalar::Scalar(String fieldName,ScalarType scalarType)
: Field(fieldName,scalar),scalarType(scalarType){}
Scalar::~Scalar(){}
void Scalar::toString(StringBuilder buffer,int indentLevel) const{
ScalarTypeFunc::toString(buffer,scalarType);
Field::toString(buffer,indentLevel);
}
ScalarArray::ScalarArray
(String fieldName,ScalarType elementType)
: Field(fieldName,scalarArray),elementType(elementType){}
ScalarArray::~ScalarArray() {}
void ScalarArray::toString(StringBuilder buffer,int indentLevel) const{
String temp = String();
ScalarTypeFunc::toString(&temp,elementType);
temp += "Array";
*buffer += temp;
Field::toString(buffer,indentLevel);
}
StructureArray::StructureArray(String fieldName,StructureConstPtr structure)
: Field(fieldName,structureArray),pstructure(structure)
{
pstructure->incReferenceCount();
}
StructureArray::~StructureArray() {
if(debugLevel==highDebug) printf("~StructureArray\n");
pstructure->decReferenceCount();
}
void StructureArray::toString(StringBuilder buffer,int indentLevel) const {
*buffer += " structureArray ";
Field::toString(buffer,indentLevel);
newLine(buffer,indentLevel + 1);
pstructure->toString(buffer,indentLevel + 1);
}
Structure::Structure (String fieldName,
int numberFields, FieldConstPtrArray infields)
: Field(fieldName,structure),
numberFields(numberFields),
fields(new FieldConstPtr[numberFields])
{
for(int i=0; i<numberFields; i++) {
fields[i] = infields[i];
}
for(int i=0; i<numberFields; i++) {
String name = fields[i]->getFieldName();
// look for duplicates
for(int j=i+1; j<numberFields; j++) {
String otherName = fields[j]->getFieldName();
int result = name.compare(otherName);
if(result==0) {
String message("duplicate fieldName ");
message += name;
throw std::invalid_argument(message);
}
}
// inc reference counter
fields[i]->incReferenceCount();
}
}
Structure::~Structure() {
if(debugLevel==highDebug)
printf("~Structure %s\n",Field::getFieldName().c_str());
for(int i=0; i<numberFields; i++) {
FieldConstPtr pfield = fields[i];
pfield->decReferenceCount();
}
delete[] fields;
}
FieldConstPtr Structure::getField(String fieldName) const {
for(int i=0; i<numberFields; i++) {
FieldConstPtr pfield = fields[i];
int result = fieldName.compare(pfield->getFieldName());
if(result==0) return pfield;
}
return 0;
}
int Structure::getFieldIndex(String fieldName) const {
for(int i=0; i<numberFields; i++) {
FieldConstPtr pfield = fields[i];
int result = fieldName.compare(pfield->getFieldName());
if(result==0) return i;
}
return -1;
}
void Structure::toString(StringBuilder buffer,int indentLevel) const{
*buffer += "structure";
Field::toString(buffer,indentLevel);
newLine(buffer,indentLevel+1);
for(int i=0; i<numberFields; i++) {
FieldConstPtr pfield = fields[i];
pfield->toString(buffer,indentLevel+1);
if(i<numberFields-1) newLine(buffer,indentLevel+1);
}
}
ScalarConstPtr FieldCreate::createScalar(String fieldName,
ScalarType scalarType) const
{
Scalar *scalar = new Scalar(fieldName,scalarType);
return scalar;
}
ScalarArrayConstPtr FieldCreate::createScalarArray(
String fieldName,ScalarType elementType) const
{
ScalarArray *scalarArray = new ScalarArray(fieldName,elementType);
return scalarArray;
}
StructureConstPtr FieldCreate::createStructure (
String fieldName,int numberFields,
FieldConstPtr fields[]) const
{
Structure *structure = new Structure(
fieldName,numberFields,fields);
return structure;
}
StructureArrayConstPtr FieldCreate::createStructureArray(
String fieldName,StructureConstPtr structure) const
{
StructureArray *structureArray = new StructureArray(fieldName,structure);
return structureArray;
}
FieldConstPtr FieldCreate::create(String fieldName,
FieldConstPtr pfield) const
{
Type type = pfield->getType();
switch(type) {
case scalar: {
ScalarConstPtr pscalar = dynamic_cast<ScalarConstPtr>(pfield);
return createScalar(fieldName,pscalar->getScalarType());
}
case scalarArray: {
ScalarArrayConstPtr pscalarArray = dynamic_cast<ScalarArrayConstPtr>(pfield);
return createScalarArray(fieldName,pscalarArray->getElementType());
}
case structure: {
StructureConstPtr pstructure = dynamic_cast<StructureConstPtr>(pfield);
return createStructure(fieldName,pstructure->getNumberFields(),pstructure->getFields());
}
case structureArray: {
StructureArrayConstPtr pstructureArray = dynamic_cast<StructureArrayConstPtr>(pfield);
return createStructureArray(fieldName,pstructureArray->getStructure());
}
}
String message("field ");
message += fieldName;
throw std::logic_error(message);
}
static FieldCreate* fieldCreate = 0;
FieldCreate::FieldCreate()
{
static void init()
{
static Mutex mutex = Mutex();
Lock xx(&mutex);
if(globalMutex==0) {
globalMutex = new Mutex();
}
pConstructDestructCallback = new CDCallbackPVIntrospect();
}
}
FieldCreate * getFieldCreate() {
static Mutex mutex = Mutex();
Lock xx(&mutex);
if(fieldCreate==0) fieldCreate = new FieldCreate();
return fieldCreate;
}
Field::Field(String fieldName,Type type)
: pImpl(new FieldPvt(fieldName,type))
{
Lock xx(globalMutex);
totalConstruct++;
}
Field::~Field() {
Lock xx(globalMutex);
totalDestruct++;
// note that compiler automatically calls destructor for fieldName
delete pImpl;
if(debugLevel==highDebug) printf("~Field %s\n",pImpl->fieldName.c_str());
}
int Field::getReferenceCount() const {
Lock xx(globalMutex);
return pImpl->referenceCount;
}
String Field::getFieldName() const {return pImpl->fieldName;}
Type Field::getType() const {return pImpl->type;}
void Field::incReferenceCount() const {
Lock xx(globalMutex);
pImpl->referenceCount++;
totalReferenceCount++;
}
void Field::decReferenceCount() const {
Lock xx(globalMutex);
if(pImpl->referenceCount<=0) {
String message("logicError field ");
message += pImpl->fieldName;
throw std::logic_error(message);
}
pImpl->referenceCount--;
totalReferenceCount--;
if(pImpl->referenceCount==0) delete this;
}
void Field::toString(StringBuilder buffer,int indentLevel) const{
*buffer += " ";
*buffer += pImpl->fieldName.c_str();
}
Scalar::Scalar(String fieldName,ScalarType scalarType)
: Field(fieldName,scalar),scalarType(scalarType){}
Scalar::~Scalar(){}
void Scalar::toString(StringBuilder buffer,int indentLevel) const{
ScalarTypeFunc::toString(buffer,scalarType);
Field::toString(buffer,indentLevel);
}
ScalarArray::ScalarArray(String fieldName,ScalarType elementType)
: Field(fieldName,scalarArray),elementType(elementType){}
ScalarArray::~ScalarArray() {}
void ScalarArray::toString(StringBuilder buffer,int indentLevel) const{
String temp = String();
ScalarTypeFunc::toString(&temp,elementType);
temp += "Array";
*buffer += temp;
Field::toString(buffer,indentLevel);
}
StructureArray::StructureArray(String fieldName,StructureConstPtr structure)
: Field(fieldName,structureArray),pstructure(structure)
{
pstructure->incReferenceCount();
}
StructureArray::~StructureArray() {
if(debugLevel==highDebug) printf("~StructureArray\n");
pstructure->decReferenceCount();
}
void StructureArray::toString(StringBuilder buffer,int indentLevel) const {
*buffer += " structureArray ";
Field::toString(buffer,indentLevel);
newLine(buffer,indentLevel + 1);
pstructure->toString(buffer,indentLevel + 1);
}
Structure::Structure (String fieldName,
int numberFields, FieldConstPtrArray infields)
: Field(fieldName,structure),
numberFields(numberFields),
fields(new FieldConstPtr[numberFields])
{
for(int i=0; i<numberFields; i++) {
fields[i] = infields[i];
}
for(int i=0; i<numberFields; i++) {
String name = fields[i]->getFieldName();
// look for duplicates
for(int j=i+1; j<numberFields; j++) {
String otherName = fields[j]->getFieldName();
int result = name.compare(otherName);
if(result==0) {
String message("duplicate fieldName ");
message += name;
throw std::invalid_argument(message);
}
}
// inc reference counter
fields[i]->incReferenceCount();
}
}
Structure::~Structure() {
if(debugLevel==highDebug)
printf("~Structure %s\n",Field::getFieldName().c_str());
for(int i=0; i<numberFields; i++) {
FieldConstPtr pfield = fields[i];
pfield->decReferenceCount();
}
delete[] fields;
}
FieldConstPtr Structure::getField(String fieldName) const {
for(int i=0; i<numberFields; i++) {
FieldConstPtr pfield = fields[i];
int result = fieldName.compare(pfield->getFieldName());
if(result==0) return pfield;
}
return 0;
}
int Structure::getFieldIndex(String fieldName) const {
for(int i=0; i<numberFields; i++) {
FieldConstPtr pfield = fields[i];
int result = fieldName.compare(pfield->getFieldName());
if(result==0) return i;
}
return -1;
}
void Structure::toString(StringBuilder buffer,int indentLevel) const{
*buffer += "structure";
Field::toString(buffer,indentLevel);
newLine(buffer,indentLevel+1);
for(int i=0; i<numberFields; i++) {
FieldConstPtr pfield = fields[i];
pfield->toString(buffer,indentLevel+1);
if(i<numberFields-1) newLine(buffer,indentLevel+1);
}
}
ScalarConstPtr FieldCreate::createScalar(String fieldName,
ScalarType scalarType) const
{
Scalar *scalar = new Scalar(fieldName,scalarType);
return scalar;
}
ScalarArrayConstPtr FieldCreate::createScalarArray(
String fieldName,ScalarType elementType) const
{
ScalarArray *scalarArray = new ScalarArray(fieldName,elementType);
return scalarArray;
}
StructureConstPtr FieldCreate::createStructure (
String fieldName,int numberFields,
FieldConstPtr fields[]) const
{
Structure *structure = new Structure(
fieldName,numberFields,fields);
return structure;
}
StructureArrayConstPtr FieldCreate::createStructureArray(
String fieldName,StructureConstPtr structure) const
{
StructureArray *structureArray = new StructureArray(fieldName,structure);
return structureArray;
}
FieldConstPtr FieldCreate::create(String fieldName,
FieldConstPtr pfield) const
{
Type type = pfield->getType();
switch(type) {
case scalar: {
ScalarConstPtr pscalar = dynamic_cast<ScalarConstPtr>(pfield);
return createScalar(fieldName,pscalar->getScalarType());
}
case scalarArray: {
ScalarArrayConstPtr pscalarArray = dynamic_cast<ScalarArrayConstPtr>(pfield);
return createScalarArray(fieldName,pscalarArray->getElementType());
}
case structure: {
StructureConstPtr pstructure = dynamic_cast<StructureConstPtr>(pfield);
return createStructure(fieldName,pstructure->getNumberFields(),pstructure->getFields());
}
case structureArray: {
StructureArrayConstPtr pstructureArray = dynamic_cast<StructureArrayConstPtr>(pfield);
return createStructureArray(fieldName,pstructureArray->getStructure());
}
}
String message("field ");
message += fieldName;
throw std::logic_error(message);
}
static FieldCreate* fieldCreate = 0;
FieldCreate::FieldCreate()
{
init();
}
FieldCreate * getFieldCreate() {
static Mutex mutex = Mutex();
Lock xx(&mutex);
if(fieldCreate==0) fieldCreate = new FieldCreate();
return fieldCreate;
}
}}

View File

@@ -11,6 +11,56 @@
namespace epics { namespace pvData {
static volatile int64 totalConstruct = 0;
static volatile int64 totalDestruct = 0;
static Mutex *globalMutex = 0;
class CDCallbackPVAuxInfo : public ConstructDestructCallback {
public:
CDCallbackPVAuxInfo();
virtual String getConstructName();
virtual int64 getTotalConstruct();
virtual int64 getTotalDestruct();
virtual int64 getTotalReferenceCount();
private:
String name;
};
CDCallbackPVAuxInfo::CDCallbackPVAuxInfo()
: name("pvAuxInfo")
{
getShowConstructDestruct()->registerCallback(this);
}
String CDCallbackPVAuxInfo::getConstructName() {return name;}
int64 CDCallbackPVAuxInfo::getTotalConstruct()
{
Lock xx(globalMutex);
return totalConstruct;
}
int64 CDCallbackPVAuxInfo::getTotalDestruct()
{
Lock xx(globalMutex);
return totalDestruct;
}
int64 CDCallbackPVAuxInfo::getTotalReferenceCount()
{
return 0;
}
static ConstructDestructCallback *pConstructDestructCallback;
static void init()
{
static Mutex mutex = Mutex();
Lock xx(&mutex);
if(globalMutex==0) {
globalMutex = new Mutex();
pConstructDestructCallback = new CDCallbackPVAuxInfo();
}
}
typedef std::map<String,PVScalar * >::const_iterator map_iterator;
class PVAuxInfoPvt {
public:
PVAuxInfoPvt(PVField *pvField)
@@ -21,33 +71,10 @@ public:
std::map<String, PVScalar * > theMap;
};
static volatile int64 totalConstruct = 0;
static volatile int64 totalDestruct = 0;
static Mutex *globalMutex = 0;
typedef std::map<String,PVScalar * >::const_iterator map_iterator;
void PVAuxInfo::init()
{
globalMutex = new Mutex();
}
int64 PVAuxInfo::getTotalConstruct()
{
Lock xx(globalMutex);
return totalConstruct;
}
int64 PVAuxInfo::getTotalDestruct()
{
Lock xx(globalMutex);
return totalDestruct;
}
PVAuxInfo::PVAuxInfo(PVField *pvField)
: pImpl(new PVAuxInfoPvt(pvField))
{
init();
Lock xx(globalMutex);
totalConstruct++;
}
@@ -68,6 +95,11 @@ PVField * PVAuxInfo::getPVField() {
return pImpl->pvField;
}
ConstructDestructCallback *PVAuxInfo::getConstructDestructCallback()
{
init();
return pConstructDestructCallback;
}
PVScalar * PVAuxInfo::createInfo(String key,ScalarType scalarType)
{

View File

@@ -38,10 +38,7 @@ static Convert* convert = 0;
static FieldCreate * fieldCreate = 0;
static PVDataCreate* pvDataCreate = 0;
PVDataCreate::PVDataCreate(){
PVField::init();
PVAuxInfo::init();
}
PVDataCreate::PVDataCreate(){ }
PVField *PVDataCreate::createPVField(PVStructure *parent,
FieldConstPtr field)

View File

@@ -13,11 +13,23 @@ INC += bitSet.h
INC += byteBuffer.h
INC += epicsException.h
INC += serializeHelper.h
INC += event.h
INC += thread.h
INC += executor.h
INC += showConstructDestruct.h
INC += timeStamp.h
INC += timeFunction.h
LIBSRCS += byteBuffer.cpp
LIBSRCS += bitSet.cpp
LIBSRCS += serializeHelper.cpp
LIBSRCS += linkedListVoid.cpp
LIBSRCS += event.cpp
LIBSRCS += thread.cpp
LIBSRCS += executor.cpp
LIBSRCS += showConstructDestruct.cpp
LIBSRCS += timeStamp.cpp
LIBSRCS += timeFunction.cpp
LIBRARY=pvMisc

114
pvDataApp/misc/event.cpp Normal file
View File

@@ -0,0 +1,114 @@
/* event.cpp */
#include <cstddef>
#include <cstdlib>
#include <cstddef>
#include <string>
#include <cstdio>
#include <memory>
#include <vector>
#include <epicsThread.h>
#include <epicsMutex.h>
#include <epicsEvent.h>
#include "noDefaultMethods.h"
#include "pvType.h"
#include "lock.h"
#include "event.h"
namespace epics { namespace pvData {
static volatile int64 totalConstruct = 0;
static volatile int64 totalDestruct = 0;
static Mutex *globalMutex = 0;
static String alreadyOn("already on list");
class ConstructDestructCallbackEvent : public ConstructDestructCallback {
public:
ConstructDestructCallbackEvent();
virtual String getConstructName();
virtual int64 getTotalConstruct();
virtual int64 getTotalDestruct();
virtual int64 getTotalReferenceCount();
private:
String name;
};
ConstructDestructCallbackEvent::ConstructDestructCallbackEvent()
: name("event")
{
getShowConstructDestruct()->registerCallback(this);
}
String ConstructDestructCallbackEvent::getConstructName() {return name;}
int64 ConstructDestructCallbackEvent::getTotalConstruct()
{
Lock xx(globalMutex);
return totalConstruct;
}
int64 ConstructDestructCallbackEvent::getTotalDestruct()
{
Lock xx(globalMutex);
return totalDestruct;
}
int64 ConstructDestructCallbackEvent::getTotalReferenceCount()
{
return 0;
}
static ConstructDestructCallback *pConstructDestructCallback;
static void init()
{
static Mutex mutex = Mutex();
Lock xx(&mutex);
if(globalMutex==0) {
globalMutex = new Mutex();
pConstructDestructCallback = new ConstructDestructCallbackEvent();
}
}
Event::~Event() {
epicsEventDestroy(id);
totalDestruct++;
}
Event::Event(EventInitialState initial)
: id(epicsEventCreate((initial==eventEmpty)?epicsEventEmpty : epicsEventFull))
{
init();
totalConstruct++;
}
ConstructDestructCallback *Event::getConstructDestructCallback()
{
init();
return pConstructDestructCallback;
}
void Event::signal()
{
epicsEventSignal(id);
}
bool Event::wait ()
{
epicsEventWaitStatus status = epicsEventWait(id);
return status==epicsEventWaitOK ? true : false;
}
bool Event::wait ( double timeOut )
{
epicsEventWaitStatus status = epicsEventWaitWithTimeout(id,timeOut);
return status==epicsEventWaitOK ? true : false;
}
bool Event::tryWait ()
{
epicsEventWaitStatus status = epicsEventTryWait(id);
return status==epicsEventWaitOK ? true : false;
}
}}

40
pvDataApp/misc/event.h Normal file
View File

@@ -0,0 +1,40 @@
/* event.h */
#ifndef EVENT_H
#define EVENT_H
#include <memory>
#include <vector>
#include <epicsMutex.h>
#include <epicsEvent.h>
#include "noDefaultMethods.h"
#include "pvType.h"
#include "showConstructDestruct.h"
namespace epics { namespace pvData {
enum EventWaitStatus {
eventWaitOK,
eventWaitTimeout,
eventWaitError
};
enum EventInitialState {
eventEmpty,
eventFull
};
class Event : private NoDefaultMethods {
public:
~Event();
Event(EventInitialState initial);
static ConstructDestructCallback *getConstructDestructCallback();
void signal();
bool wait (); /* blocks until full */
bool wait ( double timeOut ); /* false if empty at time out */
bool tryWait (); /* false if empty */
private:
epicsEventId id;
};
}}
#endif /* EVENT_H */

223
pvDataApp/misc/executor.cpp Normal file
View File

@@ -0,0 +1,223 @@
/* executor.h */
#include <cstddef>
#include <cstdlib>
#include <cstddef>
#include <string>
#include <cstdio>
#include <memory>
#include <vector>
#include "linkedList.h"
#include "lock.h"
#include "thread.h"
#include "event.h"
#include "executor.h"
namespace epics { namespace pvData {
static volatile int64 totalConstruct = 0;
static volatile int64 totalDestruct = 0;
static Mutex *globalMutex = 0;
class ConstructDestructCallbackExecutor : public ConstructDestructCallback {
public:
ConstructDestructCallbackExecutor();
virtual String getConstructName();
virtual int64 getTotalConstruct();
virtual int64 getTotalDestruct();
virtual int64 getTotalReferenceCount();
private:
String name;
};
ConstructDestructCallbackExecutor::ConstructDestructCallbackExecutor()
: name("executor")
{
getShowConstructDestruct()->registerCallback(this);
}
String ConstructDestructCallbackExecutor::getConstructName() {return name;}
int64 ConstructDestructCallbackExecutor::getTotalConstruct()
{
Lock xx(globalMutex);
return totalConstruct;
}
int64 ConstructDestructCallbackExecutor::getTotalDestruct()
{
Lock xx(globalMutex);
return totalDestruct;
}
int64 ConstructDestructCallbackExecutor::getTotalReferenceCount()
{
return 0;
}
static ConstructDestructCallback *pConstructDestructCallback;
static void init() {
static Mutex mutex = Mutex();
Lock xx(&mutex);
if(globalMutex==0) {
globalMutex = new Mutex();
pConstructDestructCallback = new ConstructDestructCallbackExecutor();
}
}
typedef LinkedListNode<ExecutorNode> ExecutorListNode;
typedef LinkedList<ExecutorNode> ExecutorList;
class ExecutorNode {
public:
ExecutorNode(Command *command);
~ExecutorNode();
Command *command;
ExecutorListNode *node;
ExecutorListNode *runNode;
};
ExecutorNode::ExecutorNode(Command *command)
: command(command),
node(new ExecutorListNode(this)),
runNode(new ExecutorListNode(this))
{}
ExecutorNode::~ExecutorNode()
{
delete node;
delete runNode;
}
ConstructDestructCallback *Executor::getConstructDestructCallback()
{
init();
return pConstructDestructCallback;
}
class ExecutorPvt : public RunnableReady {
public:
ExecutorPvt(String threadName,ThreadPriority priority);
~ExecutorPvt();
ExecutorNode * createNode(Command *command);
void execute(ExecutorNode *node);
void destroy();
virtual void run(ThreadReady *threadReady);
private:
ExecutorList *executorList;
ExecutorList *runList;
Event *moreWork;
Event *stopped;
Mutex mutex;
volatile bool alive;
Thread *thread;
};
ExecutorPvt::ExecutorPvt(String threadName,ThreadPriority priority)
: executorList(new ExecutorList()),
runList(new ExecutorList()),
moreWork(new Event(eventEmpty)),
stopped(new Event(eventEmpty)),
mutex(Mutex()),
alive(true),
thread(new Thread(threadName,priority,this))
{
thread->start();
}
ExecutorPvt::~ExecutorPvt()
{
ExecutorListNode *node;
while((node=executorList->removeHead())!=0) {
delete node->getObject();
}
delete stopped;
delete moreWork;
delete runList;
delete executorList;
delete thread;
}
void ExecutorPvt::run(ThreadReady *threadReady)
{
bool firstTime = true;
while(alive) {
ExecutorListNode * executorListNode = 0;
if(firstTime) {
firstTime = false;
threadReady->ready();
}
while(alive && runList->isEmpty()) {
moreWork->wait();
}
if(alive) {
Lock xx(&mutex);
executorListNode = runList->removeHead();
}
if(alive && executorListNode!=0) {
executorListNode->getObject()->command->command();
}
}
stopped->signal();
}
ExecutorNode * ExecutorPvt::createNode(Command *command)
{
Lock xx(&mutex);
ExecutorNode *executorNode = new ExecutorNode(command);
executorList->addTail(executorNode->node);
return executorNode;
}
void ExecutorPvt::execute(ExecutorNode *node)
{
Lock xx(&mutex);
if(!alive || node->runNode->isOnList()) return;
bool isEmpty = runList->isEmpty();
runList->addTail(node->runNode);
if(isEmpty) moreWork->signal();
}
void ExecutorPvt::destroy()
{
{
Lock xx(&mutex);
alive = false;
}
moreWork->signal();
{
Lock xx(&mutex);
stopped->wait();
}
delete this;
}
Executor::Executor(String threadName,ThreadPriority priority)
: pImpl(new ExecutorPvt(threadName,priority))
{
init();
Lock xx(globalMutex);
totalConstruct++;
}
Executor::~Executor() {
Lock xx(globalMutex);
totalDestruct++;
}
ExecutorNode * Executor::createNode(Command*command)
{return pImpl->createNode(command);}
void Executor::execute(ExecutorNode *node) {pImpl->execute(node);}
void Executor::destroy() {
pImpl->destroy();
delete this;
}
}}

33
pvDataApp/misc/executor.h Normal file
View File

@@ -0,0 +1,33 @@
/* executor.h */
#ifndef EXECUTOR_H
#define EXECUTOR_H
#include <memory>
#include <vector>
#include "noDefaultMethods.h"
#include "pvType.h"
#include "thread.h"
namespace epics { namespace pvData {
// This is created by Executor.createNode and passed to Executor.execute
class ExecutorNode;
class Command {
public:
virtual void command() = 0;
};
class Executor : private NoDefaultMethods {
public:
Executor(String threadName,ThreadPriority priority);
static ConstructDestructCallback *getConstructDestructCallback();
ExecutorNode * createNode(Command *command);
void execute(ExecutorNode *node);
void destroy();
private:
~Executor();
class ExecutorPvt *pImpl;
};
}}
#endif /* EXECUTOR_H */

View File

@@ -19,41 +19,97 @@ static volatile int64 totalListDestruct = 0;
static Mutex *globalMutex = 0;
static String alreadyOnList("already on list");
int64 LinkedListVoidNode::getTotalConstruct()
class CDCallbackLinkedListNode : public ConstructDestructCallback {
public:
CDCallbackLinkedListNode();
virtual String getConstructName();
virtual int64 getTotalConstruct();
virtual int64 getTotalDestruct();
virtual int64 getTotalReferenceCount();
private:
String name;
};
CDCallbackLinkedListNode::CDCallbackLinkedListNode()
: name("linkedListNode")
{
getShowConstructDestruct()->registerCallback(this);
}
String CDCallbackLinkedListNode::getConstructName() {return name;}
int64 CDCallbackLinkedListNode::getTotalConstruct()
{
Lock xx(globalMutex);
return totalNodeConstruct;
}
int64 LinkedListVoidNode::getTotalDestruct()
int64 CDCallbackLinkedListNode::getTotalDestruct()
{
Lock xx(globalMutex);
return totalNodeDestruct;
}
int64 LinkedListVoid::getTotalConstruct()
int64 CDCallbackLinkedListNode::getTotalReferenceCount()
{
Lock xx(globalMutex);
return totalListConstruct;
return 0;
}
int64 LinkedListVoid::getTotalDestruct()
{
Lock xx(globalMutex);
return totalListDestruct;
class CDCallbackLinkedList : public ConstructDestructCallback {
public:
CDCallbackLinkedList();
virtual String getConstructName();
virtual int64 getTotalConstruct();
virtual int64 getTotalDestruct();
virtual int64 getTotalReferenceCount();
private:
String name;
};
CDCallbackLinkedList::CDCallbackLinkedList()
: name("linkedList")
{
getShowConstructDestruct()->registerCallback(this);
}
String CDCallbackLinkedList::getConstructName() {return name;}
void LinkedListVoid::init() {
int64 CDCallbackLinkedList::getTotalConstruct()
{
Lock xx(globalMutex);
return totalNodeConstruct;
}
int64 CDCallbackLinkedList::getTotalDestruct()
{
Lock xx(globalMutex);
return totalNodeDestruct;
}
int64 CDCallbackLinkedList::getTotalReferenceCount()
{
return 0;
}
static ConstructDestructCallback *pCDCallbackLinkedListNode;
static ConstructDestructCallback *pCDCallbackLinkedList;
static void initPvt()
{
static Mutex mutex = Mutex();
Lock xx(&mutex);
if(globalMutex==0) globalMutex = new Mutex();
Lock xx(&mutex);
if(globalMutex==0) {
globalMutex = new Mutex();
pCDCallbackLinkedListNode = new CDCallbackLinkedListNode();
pCDCallbackLinkedList = new CDCallbackLinkedList();
}
}
LinkedListVoidNode::LinkedListVoidNode(void *object)
: object(object),before(0),after(0)
{
LinkedListVoid::init();
initPvt();
Lock xx(globalMutex);
totalNodeConstruct++;
}
@@ -61,17 +117,24 @@ LinkedListVoidNode::LinkedListVoidNode(void *object)
LinkedListVoidNode::LinkedListVoidNode(bool isHead)
: object(this),before(this),after(this)
{
LinkedListVoid::init();
initPvt();
Lock xx(globalMutex);
totalNodeConstruct++;
}
LinkedListVoidNode::~LinkedListVoidNode()
{
Lock xx(globalMutex);
totalNodeDestruct++;
}
ConstructDestructCallback *LinkedListVoidNode::getConstructDestructCallback()
{
initPvt();
return pCDCallbackLinkedListNode;
}
void *LinkedListVoidNode::getObject() {
return object;
}
@@ -85,7 +148,7 @@ bool LinkedListVoidNode::isOnList()
LinkedListVoid::LinkedListVoid()
: head(new LinkedListVoidNode(true)),length(0)
{
LinkedListVoid::init();
initPvt();
Lock xx(globalMutex);
totalListConstruct++;
}
@@ -97,6 +160,12 @@ LinkedListVoid::~LinkedListVoid()
totalListDestruct++;
}
ConstructDestructCallback *LinkedListVoid::getConstructDestructCallback()
{
initPvt();
return pCDCallbackLinkedList;
}
int LinkedListVoid::getLength()
{
return length;

View File

@@ -1,6 +1,7 @@
/* linkedListVoid.h */
#include "pvType.h"
#include "showConstructDestruct.h"
#ifndef LINKEDLISTVOID_H
#define LINKEDLISTVOID_H
namespace epics { namespace pvData {
@@ -11,8 +12,7 @@ class LinkedListVoidNode;
class LinkedListVoidNode {
public:
~LinkedListVoidNode();
static int64 getTotalConstruct();
static int64 getTotalDestruct();
static ConstructDestructCallback *getConstructDestructCallback();
void *getObject();
bool isOnList();
protected:
@@ -31,8 +31,7 @@ private:
class LinkedListVoid {
public:
~LinkedListVoid();
static int64 getTotalConstruct();
static int64 getTotalDestruct();
static ConstructDestructCallback *getConstructDestructCallback();
int getLength();
void addTail(LinkedListVoidNode *listNode);
void addHead(LinkedListVoidNode *listNode);
@@ -53,7 +52,6 @@ public:
protected:
LinkedListVoid();
private:
static void init();
friend class LinkedListVoidNode;
LinkedListVoidNode *head;
int length;

View File

@@ -11,12 +11,12 @@ namespace epics { namespace pvData {
class Mutex {
public:
Mutex() : lockPtr(new epicsMutex()){}
~Mutex() { delete lockPtr;};
void lock(){lockPtr->lock();}\
void unlock(){lockPtr->unlock();}
Mutex() : id(epicsMutexMustCreate()){}
~Mutex() { epicsMutexDestroy(id) ;};
void lock(){epicsMutexMustLock(id);}\
void unlock(){epicsMutexUnlock(id);}
private:
epicsMutex *lockPtr;
epicsMutexId id;
};

View File

@@ -0,0 +1,61 @@
/* showConstructDestruct.cpp */
#include <stddef.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include "noDefaultMethods.h"
#include "lock.h"
#include "pvType.h"
#include "linkedList.h"
#include "showConstructDestruct.h"
namespace epics { namespace pvData {
static ShowConstructDestruct *pShowConstructDestruct = 0;
static Mutex *globalMutex = 0;
typedef LinkedListNode<ConstructDestructCallback> ListNode;
typedef LinkedList<ConstructDestructCallback> List;
static List *list;
ShowConstructDestruct::ShowConstructDestruct() {}
void ShowConstructDestruct::constuctDestructTotals(FILE *fd)
{
Lock xx(globalMutex);
ListNode *node = list->getHead();
while(node!=0) {
ConstructDestructCallback *callback = node->getObject();
String name = callback->getConstructName();
int64 reference = callback->getTotalReferenceCount();
int64 construct = callback->getTotalConstruct();
int64 destruct = callback->getTotalDestruct();
fprintf(fd,"%s: totalConstruct %lli totalDestruct %lli",
name.c_str(),construct,destruct);
if(reference>0) fprintf(fd," totalReference %lli",reference);
fprintf(fd,"\n");
node = list->getNext(node);
}
}
void ShowConstructDestruct::registerCallback(ConstructDestructCallback *callback)
{
Lock xx(globalMutex);
ListNode *listNode = new ListNode(callback);
list->addTail(listNode);
}
ShowConstructDestruct * getShowConstructDestruct()
{
static Mutex mutex = Mutex();
Lock xx(&mutex);
if(pShowConstructDestruct==0) {
globalMutex = new Mutex();
list = new List();
pShowConstructDestruct = new ShowConstructDestruct();
}
return pShowConstructDestruct;
}
}}

View File

@@ -0,0 +1,35 @@
/* showConstructDestruct.h */
#ifndef SHOWCONSTRUCTDESTRUCT_H
#define SHOWCONSTRUCTDESTRUCT_H
#include <stddef.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include "noDefaultMethods.h"
#include "pvType.h"
namespace epics { namespace pvData {
class ConstructDestructCallback {
public:
virtual String getConstructName() = 0;
virtual int64 getTotalConstruct() = 0;
virtual int64 getTotalDestruct() = 0;
virtual int64 getTotalReferenceCount() = 0;
};
class ShowConstructDestruct : private NoDefaultMethods {
public:
static void constuctDestructTotals(FILE *fd);
static void registerCallback(ConstructDestructCallback *callback);
private:
ShowConstructDestruct();
friend ShowConstructDestruct* getShowConstructDestruct();
};
extern ShowConstructDestruct* getShowConstructDestruct();
}}
#endif /* SHOWCONSTRUCTDESTRUCT_H */

255
pvDataApp/misc/thread.cpp Normal file
View File

@@ -0,0 +1,255 @@
/* thread.cpp */
#include <cstddef>
#include <cstdlib>
#include <cstddef>
#include <string>
#include <cstdio>
#include <epicsThread.h>
#include <epicsEvent.h>
#include "lock.h"
#include "event.h"
#include "thread.h"
#include "linkedList.h"
namespace epics { namespace pvData {
static unsigned int epicsPriority[] = {
epicsThreadPriorityLow,
epicsThreadPriorityLow + 15,
epicsThreadPriorityMedium - 15,
epicsThreadPriorityMedium,
epicsThreadPriorityMedium + 15,
epicsThreadPriorityHigh - 15,
epicsThreadPriorityHigh
};
unsigned int const * const ThreadPriorityFunc::getEpicsPriorities()
{
return epicsPriority;
}
static String threadPriorityNames[] = {
String("lowest"),String("lower"),String("low"),
String("middle"),
String("high"),String("higher"),String("highest")
};
class ThreadListElement;
typedef LinkedListNode<ThreadListElement> ThreadListNode;
typedef LinkedList<ThreadListElement> ThreadList;
static volatile int64 totalConstruct = 0;
static volatile int64 totalDestruct = 0;
static Mutex *globalMutex = 0;
static void addThread(Thread *thread);
static void removeThread(Thread *thread);
static ThreadList *list;
class ConstructDestructCallbackThread : public ConstructDestructCallback {
public:
ConstructDestructCallbackThread();
virtual String getConstructName();
virtual int64 getTotalConstruct();
virtual int64 getTotalDestruct();
virtual int64 getTotalReferenceCount();
private:
String name;
};
ConstructDestructCallbackThread::ConstructDestructCallbackThread()
: name("thread")
{
getShowConstructDestruct()->registerCallback(this);
}
String ConstructDestructCallbackThread::getConstructName() {return name;}
int64 ConstructDestructCallbackThread::getTotalConstruct()
{
Lock xx(globalMutex);
return totalConstruct;
}
int64 ConstructDestructCallbackThread::getTotalDestruct()
{
Lock xx(globalMutex);
return totalDestruct;
}
int64 ConstructDestructCallbackThread::getTotalReferenceCount()
{
return 0;
}
static ConstructDestructCallback *pConstructDestructCallback;
static void init()
{
static Mutex mutex = Mutex();
Lock xx(&mutex);
if(globalMutex==0) {
globalMutex = new Mutex();
list = new ThreadList();
pConstructDestructCallback = new ConstructDestructCallbackThread();
}
}
class ThreadListElement {
public:
ThreadListElement(Thread *thread) : thread(thread),node(new ThreadListNode(this)){}
~ThreadListElement(){delete node;}
Thread *thread;
ThreadListNode *node;
};
int ThreadPriorityFunc::getEpicsPriority(ThreadPriority threadPriority) {
return epicsPriority[threadPriority];
}
extern "C" void myFunc ( void * pPvt );
class Runnable : public ThreadReady {
public:
Runnable(Thread *thread,String name,
ThreadPriority priority, RunnableReady *runnable);
virtual ~Runnable();
Thread *start();
void ready();
public: // only used within this source module
Thread *thread;
String name;
ThreadPriority priority;
RunnableReady *runnable;
Event waitStart;
bool isReady;
epicsThreadId id;
};
extern "C" void myFunc ( void * pPvt )
{
Runnable *runnable = (Runnable *)pPvt;
runnable->waitStart.signal();
addThread(runnable->thread);
runnable->runnable->run(runnable);
removeThread(runnable->thread);
}
Runnable::Runnable(Thread *thread,String name,
ThreadPriority priority, RunnableReady *runnable)
: thread(thread),name(name),priority(priority),
runnable(runnable),
waitStart(eventEmpty),
isReady(false),
id(epicsThreadCreate(
name.c_str(),
epicsPriority[priority],
epicsThreadGetStackSize(epicsThreadStackSmall),
myFunc,this))
{
init();
Lock xx(globalMutex);
totalConstruct++;
}
Runnable::~Runnable()
{
Lock xx(globalMutex);
totalDestruct++;
}
Thread * Runnable::start()
{
if(!waitStart.wait(10.0)) {
fprintf(stderr,"thread %s did not call ready\n",thread->getName().c_str());
}
return thread;
}
void Runnable::ready()
{
waitStart.signal();
}
Thread::Thread(String name,ThreadPriority priority,RunnableReady *runnableReady)
: pImpl(new Runnable(this,name,priority,runnableReady))
{
}
Thread::~Thread()
{
delete pImpl;
}
ConstructDestructCallback *Thread::getConstructDestructCallback()
{
init();
return pConstructDestructCallback;
}
void Thread::start()
{
pImpl->start();
}
void Thread::sleep(double seconds)
{
epicsThreadSleep(seconds);;
}
String Thread::getName()
{
return pImpl->name;
}
ThreadPriority Thread::getPriority()
{
return pImpl->priority;
}
void Thread::showThreads(StringBuilder buf)
{
init();
Lock xx(globalMutex);
ThreadListNode *node = list->getHead();
while(node!=0) {
Thread *thread = node->getObject()->thread;
*buf += thread->getName();
*buf += " ";
*buf += threadPriorityNames[thread->getPriority()];
*buf += "\n";
node = list->getNext(node);
}
}
void addThread(Thread *thread)
{
Lock xx(globalMutex);
ThreadListElement *element = new ThreadListElement(thread);
list->addTail(element->node);
}
void removeThread(Thread *thread)
{
Lock xx(globalMutex);
ThreadListNode *node = list->getHead();
while(node!=0) {
if(node->getObject()->thread==thread) {
list->remove(node);
delete node;
return;
}
node = list->getNext(node);
}
fprintf(stderr,"removeThread but thread %s did not in list\n",
thread->getName().c_str());
}
}}

54
pvDataApp/misc/thread.h Normal file
View File

@@ -0,0 +1,54 @@
/* thread.h */
#ifndef THREAD_H
#define THREAD_H
#include "noDefaultMethods.h"
#include "pvType.h"
namespace epics { namespace pvData {
enum ThreadPriority {
lowestPriority,
lowerPriority,
lowPriority,
middlePriority,
highPriority,
higherPriority,
highestPriority
};
class ThreadPriorityFunc {
public:
static unsigned int const * const getEpicsPriorities();
static int getEpicsPriority(ThreadPriority threadPriority);
};
class ThreadReady {
public:
virtual void ready() = 0;
};
class RunnableReady {
public:
virtual void run(ThreadReady *threadReady) = 0;
};
class Thread;
class Thread : private NoDefaultMethods {
public:
Thread(String name,ThreadPriority priority,RunnableReady *runnableReady);
~Thread();
static ConstructDestructCallback *getConstructDestructCallback();
void start();
String getName();
ThreadPriority getPriority();
static void showThreads(StringBuilder buf);
static void sleep(double seconds);
private:
class Runnable *pImpl;
friend class Runnable;
};
}}
#endif /* THREAD_H */

View File

@@ -0,0 +1,49 @@
/* timeFunction.cpp */
#include "noDefaultMethods.h"
#include "pvType.h"
#include "timeStamp.h"
namespace epics { namespace pvData {
class TimeFunctionRequester {
public:
virtual void function() = 0;
};
class TimeFunction : private NoDefaultMethods {
public:
TimeFunction(TimeFunctionRequester *requester);
~TimeFunction();
double timeCall();
private:
TimeFunctionRequester *requester;
};
TimeFunction::TimeFunction(TimeFunctionRequester *requester)
: requester(requester) {}
TimeFunction::~TimeFunction() {}
double TimeFunction::timeCall()
{
TimeStamp startTime(0,0);
TimeStamp endTime(0,0);
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);
if(diff>=1.0) {
perCall = diff/(double)ntimes;
break;
}
ntimes *= 2;
}
return perCall;
}
}}

View File

@@ -0,0 +1,25 @@
/* timeFunction.h */
#ifndef TIMEFUNCTION_H
#define TIMEFUNCTION_H
#include "noDefaultMethods.h"
#include "pvType.h"
namespace epics { namespace pvData {
class TimeFunctionRequester {
public:
virtual void function() = 0;
};
class TimeFunction : private NoDefaultMethods {
public:
TimeFunction(TimeFunctionRequester *requester);
~TimeFunction();
double timeCall();
private:
TimeFunctionRequester *requester;
};
}}
#endif /* TIMEFUNCTION_H */

View File

@@ -0,0 +1,58 @@
/* timeStamp.cpp */
#include <epicsTime.h>
#include "noDefaultMethods.h"
#include "pvType.h"
#include "timeStamp.h"
namespace epics { namespace pvData {
static uint64 TS_EPOCH_SEC_PAST_1970=7305*86400;
TimeStamp::TimeStamp(uint64 secondsPastEpoch,uint32 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;
nanoSeconds = epicsTime.nsec;
}
double TimeStamp::diffInSeconds(TimeStamp *left,TimeStamp *right)
{
double diff = left->secondsPastEpoch - right->secondsPastEpoch;
int64 nano =left->nanoSeconds - right->nanoSeconds;
diff += ((double)nano)/1e9;
return diff;
}
int64 TimeStamp::getMilliseconds()
{
return secondsPastEpoch*1000 + nanoSeconds/1000000;
}
void TimeStamp::put(int64 milliseconds)
{
secondsPastEpoch = milliseconds/1000;
nanoSeconds = (milliseconds%1000)*1000000;
}
}}

View File

@@ -0,0 +1,29 @@
/* timeStamp.h */
#ifndef TIMESTAMP_H
#define TIMESTAMP_H
#include "noDefaultMethods.h"
#include "pvType.h"
namespace epics { namespace pvData {
class TimeStamp : private NoDefaultMethods {
public:
TimeStamp(uint64 secondsPastEpoch,uint32 nanoSeconds);
~TimeStamp();
int64 getSecondsPastEpoch(){return secondsPastEpoch;}
int32 getNanoSeconds() {return nanoSeconds;}
int64 getEpicsSecondsPastEpoch();
void put(uint64 secondsPastEpoch,uint32 nanoSeconds);
void getCurrent();
static double diffInSeconds(TimeStamp *left,TimeStamp *right);
// milliseconds since epoch
int64 getMilliseconds();
void put(int64 milliseconds);
private:
int64 secondsPastEpoch;
int32 nanoSeconds;
};
}}
#endif /* TIMESTAMP_H */

View File

@@ -6,6 +6,10 @@ PROD_HOST += testLinkedList
testLinkedList_SRCS += testLinkedList.cpp
testLinkedList_LIBS += pvMisc Com
PROD_HOST += testThread
testThread_SRCS += testThread.cpp
testThread_LIBS += pvMisc Com
PROD_HOST += testBitSet
testBitSet_SRCS += testBitSet.cpp
testBitSet_LIBS += pvMisc Com

View File

@@ -1,9 +1,9 @@
/*
* * testLinkedList.cpp
* *
* * Created on: 2010.11
* * Author: Marty Kraimer
* */
* testLinkedList.cpp
*
* Created on: 2010.11
* Author: Marty Kraimer
*/
#include <cstddef>
#include <cstdlib>
@@ -12,13 +12,12 @@
#include <cstdio>
#include <list>
#include <epicsTime.h>
#include <epicsAssert.h>
#include "lock.h"
#include "timeStamp.h"
#include "linkedList.h"
#include "pvIntrospect.h"
#include "pvData.h"
#include "showConstructDestruct.h"
using namespace epics::pvData;
@@ -271,8 +270,8 @@ static void testOrderedQueue(FILE * fd ) {
}
static void testTime(FILE *auxFd) {
epicsTimeStamp startTime;
epicsTimeStamp endTime;
TimeStamp startTime(0,0);
TimeStamp endTime(0,0);
int numNodes = 1000;
LinkedList<Basic> *basicList = new BasicList();
@@ -282,15 +281,15 @@ static void testTime(FILE *auxFd) {
}
fprintf(auxFd,"\nTime test\n");
int ntimes = 1000;
epicsTimeGetCurrent(&startTime);
startTime.getCurrent();
for(int i=0; i<ntimes; i++) {
for(int j=0;j<numNodes;j++) basicList->addTail(basics[j]->node);
BasicListNode *basicNode = basicList->removeHead();
while(basicNode!=0) basicNode = basicList->removeHead();
}
epicsTimeGetCurrent(&endTime);
double diff = epicsTimeDiffInSeconds(&endTime,&startTime);
diff *= 1000.0;
endTime.getCurrent();
double diff = TimeStamp::diffInSeconds(&endTime,&startTime);
diff /= 1000.0;
fprintf(auxFd,"diff %f milliSeconds\n",diff);
diff = diff/1000.0; // convert from milliseconds to seconds
diff = diff/ntimes; // seconds per outer loop
@@ -304,8 +303,8 @@ static void testTime(FILE *auxFd) {
}
static void testTimeLocked(FILE *auxFd) {
epicsTimeStamp startTime;
epicsTimeStamp endTime;
TimeStamp startTime(0,0);
TimeStamp endTime(0,0);
Mutex *mutex = new Mutex();
int numNodes = 1000;
@@ -316,7 +315,7 @@ static void testTimeLocked(FILE *auxFd) {
}
fprintf(auxFd,"\nTime test locked\n");
int ntimes = 1000;
epicsTimeGetCurrent(&startTime);
startTime.getCurrent();
for(int i=0; i<ntimes; i++) {
for(int j=0;j<numNodes;j++) {
Lock xx(mutex);
@@ -332,8 +331,8 @@ static void testTimeLocked(FILE *auxFd) {
basicNode = basicList->removeHead();
}
}
epicsTimeGetCurrent(&endTime);
double diff = epicsTimeDiffInSeconds(&endTime,&startTime);
endTime.getCurrent();
double diff = TimeStamp::diffInSeconds(&endTime,&startTime);
diff *= 1000.0;
fprintf(auxFd,"diff %f milliSeconds\n",diff);
diff = diff/1000.0; // convert from milliseconds to seconds
@@ -349,8 +348,8 @@ static void testTimeLocked(FILE *auxFd) {
typedef std::list<Basic *> stdList;
static void testArrayListTime(FILE *auxFd) {
epicsTimeStamp startTime;
epicsTimeStamp endTime;
TimeStamp startTime(0,0);
TimeStamp endTime(0,0);
int numNodes = 1000;
stdList basicList;
@@ -360,7 +359,7 @@ static void testArrayListTime(FILE *auxFd) {
}
fprintf(auxFd,"\nTime ArrayList test\n");
int ntimes = 1000;
epicsTimeGetCurrent(&startTime);
startTime.getCurrent();
for(int i=0; i<ntimes; i++) {
for(int j=0;j<numNodes;j++) basicList.push_back(basics[j]);
while(basicList.size()>0) {
@@ -368,8 +367,8 @@ static void testArrayListTime(FILE *auxFd) {
basicList.pop_front();
}
}
epicsTimeGetCurrent(&endTime);
double diff = epicsTimeDiffInSeconds(&endTime,&startTime);
endTime.getCurrent();
double diff = TimeStamp::diffInSeconds(&endTime,&startTime);
diff *= 1000.0;
fprintf(auxFd,"diff %f milliSeconds\n",diff);
diff = diff/1000.0; // convert from milliseconds to seconds
@@ -382,8 +381,8 @@ static void testArrayListTime(FILE *auxFd) {
}
static void testArrayListTimeLocked(FILE *auxFd) {
epicsTimeStamp startTime;
epicsTimeStamp endTime;
TimeStamp startTime(0,0);
TimeStamp endTime(0,0);
int numNodes = 1000;
Mutex *mutex = new Mutex();
@@ -394,7 +393,7 @@ static void testArrayListTimeLocked(FILE *auxFd) {
}
fprintf(auxFd,"\nTime ArrayList test locked\n");
int ntimes = 1000;
epicsTimeGetCurrent(&startTime);
startTime.getCurrent();
for(int i=0; i<ntimes; i++) {
for(int j=0;j<numNodes;j++) {
Lock xx(mutex);
@@ -406,8 +405,8 @@ static void testArrayListTimeLocked(FILE *auxFd) {
basicList.pop_front();
}
}
epicsTimeGetCurrent(&endTime);
double diff = epicsTimeDiffInSeconds(&endTime,&startTime);
endTime.getCurrent();
double diff = TimeStamp::diffInSeconds(&endTime,&startTime);
diff *= 1000.0;
fprintf(auxFd,"diff %f milliSeconds\n",diff);
diff = diff/1000.0; // convert from milliseconds to seconds
@@ -442,16 +441,7 @@ int main(int argc, char *argv[]) {
testTimeLocked(auxFd);
testArrayListTime(auxFd);
testArrayListTimeLocked(auxFd);
int totalConstructList = LinkedListVoid::getTotalConstruct();
int totalDestructList = LinkedListVoid::getTotalDestruct();
int totalConstructListNode = LinkedListVoidNode::getTotalConstruct();
int totalDestructListNode = LinkedListVoidNode::getTotalDestruct();
fprintf(fd,"totalConstructList %d totalDestructList %d",
totalConstructList,totalDestructList);
fprintf(fd," totalConstructListNode %d totalDestructListNode %d\n",
totalConstructListNode,totalDestructListNode);
assert(totalConstructList==totalDestructList);
assert(totalConstructListNode==totalDestructListNode);
getShowConstructDestruct()->constuctDestructTotals(fd);
return (0);
}

View File

@@ -0,0 +1,115 @@
/*
* testThread.cpp
*
* Created on: 2010.11
* Author: Marty Kraimer
*/
#include <cstddef>
#include <cstdlib>
#include <cstddef>
#include <string>
#include <cstdio>
#include <list>
#include <epicsAssert.h>
#include "event.h"
#include "thread.h"
#include "executor.h"
#include "showConstructDestruct.h"
#include "timeFunction.h"
using namespace epics::pvData;
class Basic : public Command {
public:
Basic(Executor *executor);
~Basic();
void run();
virtual void command();
private:
Executor *executor;
ExecutorNode *executorNode;
Event *wait;
};
Basic::Basic(Executor *executor)
: executor(executor),
executorNode(executor->createNode(this)),
wait(new Event(eventEmpty))
{
}
Basic::~Basic() {
delete wait;
}
void Basic::run()
{
executor->execute(executorNode);
bool result = wait->wait();
if(result==false) printf("basic::run wait returned true\n");
}
void Basic::command()
{
wait->signal();
}
static void testBasic(FILE *fd) {
Executor *executor = new Executor(String("basic"),middlePriority);
Basic *basic = new Basic(executor);
basic->run();
delete basic;
String buf("");
Thread::showThreads(&buf);
fprintf(fd,"threads\n%s\n",buf.c_str());
executor->destroy();
}
class MyFunc : public TimeFunctionRequester {
public:
MyFunc(Basic *basic)
: basic(basic)
{}
virtual void function()
{
basic->run();
}
private:
Basic *basic;
};
static void testThreadContext(FILE *fd,FILE *auxFd) {
Executor *executor = new Executor(String("basic"),middlePriority);
Basic *basic = new Basic(executor);
MyFunc myFunc(basic);
TimeFunction timeFunction(&myFunc);
double perCall = timeFunction.timeCall();
perCall *= 1e6;
fprintf(auxFd,"time per call %f microseconds\n",perCall);
delete basic;
executor->destroy();
}
int main(int argc, char *argv[]) {
char *fileName = 0;
if(argc>1) fileName = argv[1];
FILE * fd = stdout;
if(fileName!=0 && fileName[0]!=0) {
fd = fopen(fileName,"w+");
}
char *auxFileName = 0;
if(argc>2) auxFileName = argv[2];
FILE *auxFd = stdout;
if(auxFileName!=0 && auxFileName[0]!=0) {
auxFd = fopen(auxFileName,"w+");
}
testBasic(fd);
testThreadContext(fd,auxFd);
getShowConstructDestruct()->constuctDestructTotals(fd);
return (0);
}

View File

@@ -0,0 +1,16 @@
TOP=../..
include $(TOP)/configure/CONFIG
INC += enumerated.h
LIBSRCS += enumerated.cpp
enumerated_LIBS += pvFactory pvMisc Com
LIBRARY=pvProperty
include $(TOP)/configure/RULES
#----------------------------------------
# ADD RULES AFTER THIS LINE

View File

@@ -0,0 +1,62 @@
/* enumerated.cpp */
#include <string>
#include <stdexcept>
#include "pvType.h"
#include "pvIntrospect.h"
#include "pvData.h"
#include "enumerated.h"
#include "noDefaultMethods.h"
namespace epics { namespace pvData {
static String notStructure("field is not a structure");
static String notEqual2("structure does not have exactly two fields");
static String badIndex("structure does not have field index of type int");
static String badChoices("structure does not have field choices of type stringArray");
Enumerated* Enumerated::create(PVField *pvField){
if(pvField->getField()->getType()!=structure) {
pvField->message(notStructure,errorMessage);
return 0;
}
PVStructure *pvStructure = (PVStructure*)pvField;
int numberFields = pvStructure->getNumberFields();
if(numberFields!=2) {
pvField->message(notEqual2,errorMessage);
return 0;
}
PVFieldPtrArray pvFields = pvStructure->getPVFields();
FieldConstPtrArray fields = pvStructure->getStructure()->getFields();
FieldConstPtr field = fields[0];
if(field->getFieldName().compare("index")!=0 || field->getType()!=scalar) {
pvField->message(badIndex,errorMessage);
return 0;
}
PVInt *pvInt = (PVInt *) pvFields[0];
field = fields[1];
if(field->getFieldName().compare("choices")!=0 || field->getType()!=scalarArray) {
pvField->message(badChoices,errorMessage);
return 0;
}
ScalarArrayConstPtr pscalarArray = (ScalarArrayConstPtr)field;
if(pscalarArray->getElementType()!=pvString) {
pvField->message(badChoices,errorMessage);
return 0;
}
PVStringArray *pvStringArray = (PVStringArray *) pvFields[1];
return new Enumerated(pvStructure,pvInt,pvStringArray);
}
Enumerated::~Enumerated() {}
Enumerated::Enumerated(
PVStructure *pvStructure,PVInt *pvIndex,PVStringArray *pvChoices)
: pvStructure(pvStructure),pvIndex(pvIndex),pvChoices(pvChoices),
stringArrayData(StringArrayData()) {}
String Enumerated::getChoice() {
pvChoices->get(0, pvChoices->getLength(), &stringArrayData);
return stringArrayData.data[pvIndex->get()];
}
}}

View File

@@ -0,0 +1,29 @@
/* enumerated.h */
#include <string>
#include <stdexcept>
#ifndef ENUMERATED_H
#define ENUMERATED_H
#include "pvIntrospect.h"
#include "pvData.h"
#include "noDefaultMethods.h"
namespace epics { namespace pvData {
class Enumerated : private NoDefaultMethods {
public:
static Enumerated* create(PVField *pvField);
~Enumerated();
PVInt *getIndex() { return pvIndex;}
String getChoice();
PVStringArray *getChoices() { return pvChoices;}
PVStructure *getPV() { return pvStructure;}
private:
Enumerated(PVStructure *pvStructure,
PVInt *pvIndex,PVStringArray *pvChoices);
PVStructure *pvStructure;
PVInt *pvIndex;
PVStringArray *pvChoices;
StringArrayData stringArrayData;
};
}}
#endif /* ENUMERATED_H */

View File

@@ -9,6 +9,7 @@
#include "requester.h"
#include "byteBuffer.h"
#include "serialize.h"
#include "showConstructDestruct.h"
namespace epics { namespace pvData {
class PVAuxInfo;
@@ -57,8 +58,7 @@ namespace epics { namespace pvData {
public:
PVAuxInfo(PVField *pvField);
~PVAuxInfo();
static int64 getTotalConstruct();
static int64 getTotalDestruct();
static ConstructDestructCallback *getConstructDestructCallback();
PVField * getPVField();
PVScalar * createInfo(String key,ScalarType scalarType);
PVScalarMap getInfos();
@@ -66,7 +66,6 @@ namespace epics { namespace pvData {
void toString(StringBuilder buf);
void toString(StringBuilder buf,int indentLevel);
private:
static void init();
class PVAuxInfoPvt *pImpl;
friend class PVDataCreate;
};
@@ -76,11 +75,14 @@ namespace epics { namespace pvData {
virtual void postPut() = 0;
};
class PVField : public Requester, public Serializable ,private NoDefaultMethods{
class PVField
: public Requester,
public Serializable,
private NoDefaultMethods
{
public:
virtual ~PVField();
static int64 getTotalConstruct();
static int64 getTotalDestruct();
static ConstructDestructCallback *getConstructDestructCallback();
String getRequesterName() ;
virtual void message(String message,MessageType messageType) ;
virtual void setRequester(Requester *prequester);
@@ -107,7 +109,6 @@ namespace epics { namespace pvData {
class PVFieldPvt *pImpl;
static void computeOffset(PVField *pvField);
static void computeOffset(PVField *pvField,int offset);
static void init();
friend class PVDataCreate;
};

View File

@@ -5,6 +5,7 @@
#define PVINTROSPECT_H
#include "noDefaultMethods.h"
#include "pvType.h"
#include "showConstructDestruct.h"
namespace epics { namespace pvData {
class Field;
@@ -52,13 +53,11 @@ namespace epics { namespace pvData {
static void toString(StringBuilder buf,ScalarType scalarType);
};
class Field : private NoDefaultMethods {
class Field : private NoDefaultMethods {
public:
virtual ~Field();
Field(String fieldName,Type type);
static int getTotalReferenceCount();
static int64 getTotalConstruct();
static int64 getTotalDestruct();
static ConstructDestructCallback *getConstructDestructCallback();
int getReferenceCount() const;
String getFieldName() const;
Type getType() const;
@@ -124,7 +123,7 @@ namespace epics { namespace pvData {
FieldConstPtrArray fields;
};
class FieldCreate {
class FieldCreate : NoDefaultMethods {
public:
FieldConstPtr create(String fieldName,FieldConstPtr field) const;
ScalarConstPtr createScalar(String fieldName,ScalarType scalarType) const;

View File

@@ -54,7 +54,7 @@ namespace epics { namespace pvData {
StructureConstPtr doubleAlarm();
StructureConstPtr enumeratedAlarm();
private:
void init();
static void init();
};
extern StandardField * getStandardField();

View File

@@ -10,9 +10,11 @@
#include <epicsAssert.h>
#include "requester.h"
#include "executor.h"
#include "pvIntrospect.h"
#include "pvData.h"
#include "standardField.h"
#include "showConstructDestruct.h"
using namespace epics::pvData;
@@ -129,7 +131,6 @@ static void testStructureArray(FILE * fd) {
int main(int argc,char *argv[])
{
int initialTotalReferences,finalTotalReferences;
char *fileName = 0;
if(argc>1) fileName = argv[1];
FILE * fd = stdout;
@@ -139,34 +140,11 @@ int main(int argc,char *argv[])
fieldCreate = getFieldCreate();
pvDataCreate = getPVDataCreate();
standardField = getStandardField();
initialTotalReferences = Field::getTotalReferenceCount();
testScalar(fd);
finalTotalReferences = Field::getTotalReferenceCount();
assert(initialTotalReferences==finalTotalReferences);
initialTotalReferences = Field::getTotalReferenceCount();
testScalarArray(fd);
finalTotalReferences = Field::getTotalReferenceCount();
assert(initialTotalReferences==finalTotalReferences);
initialTotalReferences = Field::getTotalReferenceCount();
testSimpleStructure(fd);
finalTotalReferences = Field::getTotalReferenceCount();
assert(initialTotalReferences==finalTotalReferences);
initialTotalReferences = Field::getTotalReferenceCount();
testStructureArray(fd);
finalTotalReferences = Field::getTotalReferenceCount();
assert(initialTotalReferences==finalTotalReferences);
initialTotalReferences = Field::getTotalReferenceCount();
int64 totalConstruct = Field::getTotalConstruct();
int64 totalDestruct = Field::getTotalDestruct();
int totalReference = Field::getTotalReferenceCount();
fprintf(fd,"Field: totalConstruct %lli totalDestruct %lli totalReferenceCount %i\n",
totalConstruct,totalDestruct,totalReference);
assert(totalConstruct==(totalDestruct+totalReference));
totalConstruct = PVField::getTotalConstruct();
totalDestruct = PVField::getTotalDestruct();
fprintf(fd,"PVField: totalConstruct %lli totalDestruct %lli\n",
totalConstruct,totalDestruct);
assert(totalConstruct==totalDestruct);
getShowConstructDestruct()->constuctDestructTotals(fd);
return(0);
}

View File

@@ -15,6 +15,7 @@
#include "convert.h"
#include "standardField.h"
#include "standardPVField.h"
#include "showConstructDestruct.h"
using namespace epics::pvData;
@@ -74,7 +75,6 @@ static void testPVAuxInfo(FILE * fd) {
int main(int argc,char *argv[])
{
int initialTotalReferences,finalTotalReferences;
char *fileName = 0;
if(argc>1) fileName = argv[1];
FILE * fd = stdout;
@@ -86,28 +86,8 @@ int main(int argc,char *argv[])
standardField = getStandardField();
standardPVField = getStandardPVField();
convert = getConvert();
initialTotalReferences = Field::getTotalReferenceCount();
testPVAuxInfo(fd);
finalTotalReferences = Field::getTotalReferenceCount();
fprintf(fd,"Field: initialTotalReferences %d finalTotalReferences %d\n",
initialTotalReferences,finalTotalReferences);
assert(initialTotalReferences==finalTotalReferences);
int64 totalConstruct = Field::getTotalConstruct();
int64 totalDestruct = Field::getTotalDestruct();
int totalReference = Field::getTotalReferenceCount();
fprintf(fd,"Field: totalConstruct %lli totalDestruct %lli totalReferenceCount %i\n",
totalConstruct,totalDestruct,totalReference);
assert(totalConstruct==(totalDestruct+totalReference));
totalConstruct = PVField::getTotalConstruct();
totalDestruct = PVField::getTotalDestruct();
fprintf(fd,"PVField: totalConstruct %lli totalDestruct %lli\n",
totalConstruct,totalDestruct);
assert(totalConstruct==totalDestruct);
totalConstruct = PVAuxInfo::getTotalConstruct();
totalDestruct = PVAuxInfo::getTotalDestruct();
fprintf(fd,"PVAuxInfo: totalConstruct %lli totalDestruct %lli\n",
totalConstruct,totalDestruct);
assert(totalConstruct==totalDestruct);
getShowConstructDestruct()->constuctDestructTotals(fd);
return(0);
}

View File

@@ -15,6 +15,7 @@
#include "convert.h"
#include "standardField.h"
#include "standardPVField.h"
#include "showConstructDestruct.h"
using namespace epics::pvData;
@@ -247,7 +248,6 @@ static void testScalarArray(FILE * fd) {
int main(int argc,char *argv[])
{
int initialTotalReferences,finalTotalReferences;
char *fileName = 0;
if(argc>1) fileName = argv[1];
FILE * fd = stdout;
@@ -259,25 +259,9 @@ int main(int argc,char *argv[])
standardField = getStandardField();
standardPVField = getStandardPVField();
convert = getConvert();
initialTotalReferences = Field::getTotalReferenceCount();
testPVScalar(fd);
finalTotalReferences = Field::getTotalReferenceCount();
assert(initialTotalReferences==finalTotalReferences);
initialTotalReferences = Field::getTotalReferenceCount();
testScalarArray(fd);
finalTotalReferences = Field::getTotalReferenceCount();
assert(initialTotalReferences==finalTotalReferences);
int64 totalConstruct = Field::getTotalConstruct();
int64 totalDestruct = Field::getTotalDestruct();
int totalReference = Field::getTotalReferenceCount();
fprintf(fd,"Field: totalConstruct %lli totalDestruct %lli totalReferenceCount %i\n",
totalConstruct,totalDestruct,totalReference);
assert(totalConstruct==(totalDestruct+totalReference));
totalConstruct = PVField::getTotalConstruct();
totalDestruct = PVField::getTotalDestruct();
fprintf(fd,"PVField: totalConstruct %lli totalDestruct %lli\n",
totalConstruct,totalDestruct);
assert(totalConstruct==totalDestruct);
getShowConstructDestruct()->constuctDestructTotals(fd);
return(0);
}

View File

@@ -14,6 +14,7 @@
#include "pvData.h"
#include "standardField.h"
#include "standardPVField.h"
#include "showConstructDestruct.h"
using namespace epics::pvData;
@@ -69,17 +70,7 @@ int main(int argc,char *argv[])
standardField = getStandardField();
standardPVField = getStandardPVField();
testPowerSupplyArray(fd);
int64 totalConstruct = Field::getTotalConstruct();
int64 totalDestruct = Field::getTotalDestruct();
int totalReference = Field::getTotalReferenceCount();
fprintf(fd,"Field: totalConstruct %lli totalDestruct %lli totalReferenceCount %i\n",
totalConstruct,totalDestruct,totalReference);
assert(totalConstruct==(totalDestruct+totalReference));
totalConstruct = PVField::getTotalConstruct();
totalDestruct = PVField::getTotalDestruct();
fprintf(fd,"PVField: totalConstruct %lli totalDestruct %lli\n",
totalConstruct,totalDestruct);
assert(totalConstruct==totalDestruct);
getShowConstructDestruct()->constuctDestructTotals(fd);
return(0);
}

View File

@@ -1,4 +1,4 @@
/* testIntrospect.cpp */
/* testPVType.cpp */
/* Author: Marty Kraimer Date: 2010.09 */
#include <cstddef>

View File

@@ -77,5 +77,5 @@ structure value
structure timeStamp
long secondsPastEpoch
int nanoSeconds
Field: totalConstruct 156 totalDestruct 63 totalReferenceCount 93
PVField: totalConstruct 55 totalDestruct 55
field: totalConstruct 156 totalDestruct 63 totalReference 93
pvField: totalConstruct 55 totalDestruct 55

View File

@@ -77,5 +77,5 @@ structure value
structure timeStamp
long secondsPastEpoch
int nanoSeconds
Field: totalConstruct 156 totalDestruct 63 totalReferenceCount 93
PVField: totalConstruct 55 totalDestruct 55
field: totalConstruct 156 totalDestruct 63 totalReference 93
pvField: totalConstruct 55 totalDestruct 55

View File

@@ -17,4 +17,5 @@ stack 4 3 2 1 0
Ordered Queue test
list 0 1 2 3 4
totalConstructList 8 totalDestructList 8 totalConstructListNode 4038 totalDestructListNode 4038
linkedListNode: totalConstruct 4041 totalDestruct 4038
linkedList: totalConstruct 4041 totalDestruct 4038

View File

@@ -1,20 +1,20 @@
Time test
diff 23.646940 milliSeconds
time per iteration 23.646940 microseconds
time per addTail/removeHead 0.011823 microseconds
diff 0.000025 milliSeconds
time per iteration 0.000025 microseconds
time per addTail/removeHead 0.000000 microseconds
Time test locked
diff 183.897825 milliSeconds
time per iteration 183.897825 microseconds
time per addTail/removeHead 0.091949 microseconds
diff 177.872050 milliSeconds
time per iteration 177.872050 microseconds
time per addTail/removeHead 0.088936 microseconds
Time ArrayList test
diff 652.546057 milliSeconds
time per iteration 652.546057 microseconds
time per addTail/removeHead 0.326273 microseconds
diff 648.628783 milliSeconds
time per iteration 648.628783 microseconds
time per addTail/removeHead 0.324314 microseconds
Time ArrayList test locked
diff 814.756660 milliSeconds
time per iteration 814.756660 microseconds
time per addTail/removeHead 0.407378 microseconds
diff 805.752571 milliSeconds
time per iteration 805.752571 microseconds
time per addTail/removeHead 0.402876 microseconds

View File

@@ -17,4 +17,5 @@ stack 4 3 2 1 0
Ordered Queue test
list 0 1 2 3 4
totalConstructList 8 totalDestructList 8 totalConstructListNode 4038 totalDestructListNode 4038
linkedListNode: totalConstruct 4041 totalDestruct 4038
linkedList: totalConstruct 4041 totalDestruct 4038

View File

@@ -33,7 +33,6 @@ units offset 11 next 12 number 1
limit offset 12 next 15 number 3
low offset 13 next 14 number 1
high offset 14 next 15 number 1
Field: initialTotalReferences 93 finalTotalReferences 93
Field: totalConstruct 111 totalDestruct 18 totalReferenceCount 93
PVField: totalConstruct 17 totalDestruct 17
PVAuxInfo: totalConstruct 1 totalDestruct 1
field: totalConstruct 111 totalDestruct 18 totalReference 93
pvField: totalConstruct 17 totalDestruct 17
pvAuxInfo: totalConstruct 1 totalDestruct 1

View File

@@ -33,7 +33,6 @@ units offset 11 next 12 number 1
limit offset 12 next 15 number 3
low offset 13 next 14 number 1
high offset 14 next 15 number 1
Field: initialTotalReferences 93 finalTotalReferences 93
Field: totalConstruct 111 totalDestruct 18 totalReferenceCount 93
PVField: totalConstruct 17 totalDestruct 17
PVAuxInfo: totalConstruct 1 totalDestruct 1
field: totalConstruct 111 totalDestruct 18 totalReference 93
pvField: totalConstruct 17 totalDestruct 17
pvAuxInfo: totalConstruct 1 totalDestruct 1

View File

@@ -281,5 +281,5 @@ structure string
structure timeStamp
long secondsPastEpoch 0
int nanoSeconds 0
Field: totalConstruct 388 totalDestruct 295 totalReferenceCount 93
PVField: totalConstruct 279 totalDestruct 279
field: totalConstruct 388 totalDestruct 295 totalReference 93
pvField: totalConstruct 279 totalDestruct 279

View File

@@ -281,5 +281,5 @@ structure string
structure timeStamp
long secondsPastEpoch 0
int nanoSeconds 0
Field: totalConstruct 388 totalDestruct 295 totalReferenceCount 93
PVField: totalConstruct 279 totalDestruct 279
field: totalConstruct 388 totalDestruct 295 totalReference 93
pvField: totalConstruct 279 totalDestruct 279

View File

@@ -56,5 +56,5 @@ structure powerSupply
structure timeStamp
long secondsPastEpoch 0
int nanoSeconds 0
Field: totalConstruct 153 totalDestruct 60 totalReferenceCount 93
PVField: totalConstruct 56 totalDestruct 56
field: totalConstruct 153 totalDestruct 60 totalReference 93
pvField: totalConstruct 56 totalDestruct 56

View File

@@ -56,5 +56,5 @@ structure powerSupply
structure timeStamp
long secondsPastEpoch 0
int nanoSeconds 0
Field: totalConstruct 153 totalDestruct 60 totalReferenceCount 93
PVField: totalConstruct 56 totalDestruct 56
field: totalConstruct 153 totalDestruct 60 totalReference 93
pvField: totalConstruct 56 totalDestruct 56

8
test/testThread Normal file
View File

@@ -0,0 +1,8 @@
threads
basic middle
linkedListNode: totalConstruct 17 totalDestruct 10
linkedList: totalConstruct 17 totalDestruct 10
event: totalConstruct 8 totalDestruct 8
thread: totalConstruct 2 totalDestruct 2
executor: totalConstruct 2 totalDestruct 2

12
test/testThread.pl Executable file
View File

@@ -0,0 +1,12 @@
eval 'exec perl -S $0 ${1+"$@"}' # -*- Mode: perl -*-
if $running_under_some_shell; # testThread.pl
use Env;
system ("rm testThread");
system ("rm testThreadDiff");
system ("../bin/${EPICS_HOST_ARCH}/testThread testThread testThreadAux");
system ("diff testThread testThreadGold >> testThreadDiff");
if(-z "testThreadDiff") {
print "testThread OK\n";
} else {
print "testThread Failed\n";
}

1
test/testThreadAux Normal file
View File

@@ -0,0 +1 @@
time per call 25.290591 microseconds

0
test/testThreadDiff Normal file
View File

8
test/testThreadGold Normal file
View File

@@ -0,0 +1,8 @@
threads
basic middle
linkedListNode: totalConstruct 17 totalDestruct 10
linkedList: totalConstruct 17 totalDestruct 10
event: totalConstruct 8 totalDestruct 8
thread: totalConstruct 2 totalDestruct 2
executor: totalConstruct 2 totalDestruct 2