diff --git a/documentation/pvDataCpp.html b/documentation/pvDataCpp.html
index 0edca05..5e63a47 100644
--- a/documentation/pvDataCpp.html
+++ b/documentation/pvDataCpp.html
@@ -2906,7 +2906,7 @@ PVDataCreate.
Allows messages to be sent to a requester.
serialize.h
Support for serializing objects.
- showConstructDestruct.h
+ CDRMonitor.h
Provides support monitoring memory usage for objects of a class.
status.h
A way to pass status information to a client.
diff --git a/pvDataApp/Makefile b/pvDataApp/Makefile
index 8e3fcca..54de4b1 100644
--- a/pvDataApp/Makefile
+++ b/pvDataApp/Makefile
@@ -18,7 +18,7 @@ INC += serializeHelper.h
INC += event.h
INC += thread.h
INC += executor.h
-INC += showConstructDestruct.h
+INC += CDRMonitor.h
INC += timeFunction.h
INC += timer.h
INC += queueVoid.h
@@ -27,7 +27,7 @@ INC += messageQueue.h
INC += destroyable.h
INC += status.h
-LIBSRCS += showConstructDestruct.cpp
+LIBSRCS += CDRMonitor.cpp
LIBSRCS += byteBuffer.cpp
LIBSRCS += bitSet.cpp
LIBSRCS += requester.cpp
diff --git a/pvDataApp/factory/FieldCreateFactory.cpp b/pvDataApp/factory/FieldCreateFactory.cpp
index e74119b..e8164c4 100644
--- a/pvDataApp/factory/FieldCreateFactory.cpp
+++ b/pvDataApp/factory/FieldCreateFactory.cpp
@@ -12,7 +12,7 @@
#include "pvIntrospect.h"
#include "convert.h"
#include "factory.h"
-#include "showConstructDestruct.h"
+#include "CDRMonitor.h"
namespace epics { namespace pvData {
@@ -24,6 +24,8 @@ static void newLine(StringBuilder buffer, int indentLevel)
for(int i=0; ifieldName.c_str());
delete pImpl;
@@ -88,7 +55,7 @@ Field::~Field() {
}
int Field::getReferenceCount() const {
- Lock xx(&globalMutex);
+ Lock xx(&refCountMutex);
return pImpl->referenceCount;
}
@@ -102,9 +69,9 @@ void Field::renameField(String newName)
}
void Field::incReferenceCount() const {
- Lock xx(&globalMutex);
+ field_node.incRef();
+ Lock xx(&refCountMutex);
pImpl->referenceCount++;
- totalReferenceCount++;
if(pImpl->type!=structure) return;
StructureConstPtr structure = static_cast(this);
FieldConstPtrArray fields = structure->getFields();
@@ -115,14 +82,14 @@ void Field::incReferenceCount() const {
}
void Field::decReferenceCount() const {
- Lock xx(&globalMutex);
+ field_node.decRef();
+ Lock xx(&refCountMutex);
if(pImpl->referenceCount<=0) {
String message("logicError field ");
message += pImpl->fieldName;
throw std::logic_error(message);
}
pImpl->referenceCount--;
- totalReferenceCount--;
if(pImpl->type!=structure) {
if(pImpl->referenceCount==0) {
delete this;
@@ -435,7 +402,6 @@ static FieldCreate* fieldCreate = 0;
FieldCreate::FieldCreate()
{
- init();
}
FieldCreate * getFieldCreate() {
diff --git a/pvDataApp/factory/PVAuxInfoImpl.cpp b/pvDataApp/factory/PVAuxInfoImpl.cpp
index 0df4fff..57f9148 100644
--- a/pvDataApp/factory/PVAuxInfoImpl.cpp
+++ b/pvDataApp/factory/PVAuxInfoImpl.cpp
@@ -13,38 +13,11 @@
#include "convert.h"
#include "factory.h"
#include "lock.h"
-#include "showConstructDestruct.h"
+#include "CDRMonitor.h"
namespace epics { namespace pvData {
-static volatile int64 totalConstruct = 0;
-static volatile int64 totalDestruct = 0;
-static Mutex globalMutex;
-static bool notInited = true;
-
-static int64 getTotalConstruct()
-{
- Lock xx(&globalMutex);
- return totalConstruct;
-}
-
-static int64 getTotalDestruct()
-{
- Lock xx(&globalMutex);
- return totalDestruct;
-}
-
-static void init()
-{
- static Mutex mutex = Mutex();
- Lock xx(&globalMutex);
- if(notInited) {
- notInited = false;
- ShowConstructDestruct::registerCallback(
- String("pvAuxInfo"),
- getTotalConstruct,getTotalDestruct,0,0);
- }
-}
+PVDATA_REFCOUNT_MONITOR_DEFINE(pvAuxInfo);
typedef std::map::const_iterator map_iterator;
@@ -61,14 +34,11 @@ public:
PVAuxInfo::PVAuxInfo(PVField *pvField)
: pImpl(new PVAuxInfoPvt(pvField))
{
- init();
- Lock xx(&globalMutex);
- totalConstruct++;
+ PVDATA_REFCOUNT_MONITOR_CONSTRUCT(pvAuxInfo);
}
PVAuxInfo::~PVAuxInfo() {
- Lock xx(&globalMutex);
- totalDestruct++;
+ PVDATA_REFCOUNT_MONITOR_DESTRUCT(pvAuxInfo);
map_iterator i = pImpl->theMap.begin();
while(i!=pImpl->theMap.end()) {
PVScalar *value = i->second;
diff --git a/pvDataApp/factory/PVField.cpp b/pvDataApp/factory/PVField.cpp
index dc1c0bd..c7b66a9 100644
--- a/pvDataApp/factory/PVField.cpp
+++ b/pvDataApp/factory/PVField.cpp
@@ -8,41 +8,16 @@
#include
#include
#include
+#include "lock.h"
#include "pvData.h"
#include "factory.h"
-#include "showConstructDestruct.h"
+#include "CDRMonitor.h"
namespace epics { namespace pvData {
static String notImplemented("not implemented");
-static volatile int64 totalConstruct = 0;
-static volatile int64 totalDestruct = 0;
-static Mutex globalMutex;
-static bool notInited = true;
-
-static int64 getTotalConstruct()
-{
- Lock xx(&globalMutex);
- return totalConstruct;
-}
-
-static int64 getTotalDestruct()
-{
- Lock xx(&globalMutex);
- return totalDestruct;
-}
-
-static void init()
-{
- Lock xx(&globalMutex);
- if(notInited) {
- notInited = false;
- ShowConstructDestruct::registerCallback(
- String("pvField"),
- getTotalConstruct,getTotalDestruct,0,0);
- }
-}
+PVDATA_REFCOUNT_MONITOR_DEFINE(pvField);
class PVFieldPvt {
public:
@@ -77,15 +52,12 @@ PVFieldPvt::~PVFieldPvt()
PVField::PVField(PVStructure *parent,FieldConstPtr field)
: pImpl(new PVFieldPvt(parent,field))
{
- init();
- Lock xx(&globalMutex);
- totalConstruct++;
+ PVDATA_REFCOUNT_MONITOR_CONSTRUCT(pvField);
}
PVField::~PVField()
{
- Lock xx(&globalMutex);
- totalDestruct++;
+ PVDATA_REFCOUNT_MONITOR_DESTRUCT(pvField);
delete pImpl;
}
diff --git a/pvDataApp/factory/StandardField.cpp b/pvDataApp/factory/StandardField.cpp
index 0289efb..4b422a9 100644
--- a/pvDataApp/factory/StandardField.cpp
+++ b/pvDataApp/factory/StandardField.cpp
@@ -7,15 +7,15 @@
#include
#include
#include
+#include
+#include
#include
#include "pvIntrospect.h"
#include "standardField.h"
-#include "showConstructDestruct.h"
+#include "CDRMonitor.h"
namespace epics { namespace pvData {
-static Mutex globalMutex;
-static bool notInited = true;
static StandardField* standardField = 0;
static String notImplemented("not implemented");
@@ -462,7 +462,7 @@ StandardField::StandardField(){init();}
StandardField::~StandardField(){
}
-static void myDeleteStatic()
+static void myDeleteStatic(void*)
{
int count = alarmField->getReferenceCount();
if(count!=1) printf("~StandardField() alarmField reference count %d\n",count);
@@ -502,16 +502,18 @@ static void myDeleteStatic()
enumeratedAlarmField->decReferenceCount();
}
+static void myInitStatic(void*)
+{
+ standardField = new StandardField();
+ fieldCreate = getFieldCreate();
+ epicsAtExit(&myDeleteStatic,0);
+}
+
+static
+epicsThreadOnceId myInitOnce = EPICS_THREAD_ONCE_INIT;
+
StandardField * getStandardField() {
- Lock xx(&globalMutex);
- if(notInited) {
- notInited = false;
- standardField = new StandardField();
- fieldCreate = getFieldCreate();
- ShowConstructDestruct::registerCallback(
- "standardField",
- 0,0,0,myDeleteStatic);
- }
+ epicsThreadOnce(&myInitOnce,&myInitStatic,0);
return standardField;
}
diff --git a/pvDataApp/factory/StandardPVField.cpp b/pvDataApp/factory/StandardPVField.cpp
index a24cb20..1ba7cb1 100644
--- a/pvDataApp/factory/StandardPVField.cpp
+++ b/pvDataApp/factory/StandardPVField.cpp
@@ -6,18 +6,18 @@
*/
#include
#include
+#include
+#include
#include
#include "pvIntrospect.h"
#include "pvData.h"
#include "convert.h"
#include "standardField.h"
#include "standardPVField.h"
-#include "showConstructDestruct.h"
+#include "CDRMonitor.h"
namespace epics { namespace pvData {
-static Mutex globalMutex;
-static bool notInited = true;
static StandardField *standardField = 0;
static String notImplemented("not implemented");
@@ -329,23 +329,25 @@ public:
StandardPVFieldExt(): StandardPVField(){};
};
-static void myDeleteStatic()
+static void myDeleteStatic(void*)
{
delete standardPVField;
}
+static void myInitStatic(void*)
+{
+ fieldCreate = getFieldCreate();
+ pvDataCreate = getPVDataCreate();
+ standardField = getStandardField();
+ standardPVField = new StandardPVFieldExt();
+ epicsAtExit(&myDeleteStatic, 0);
+}
+
+static
+epicsThreadOnceId myInitOnce = EPICS_THREAD_ONCE_INIT;
+
StandardPVField * getStandardPVField() {
- Lock xx(&globalMutex);
- if(notInited) {
- notInited = false;
- fieldCreate = getFieldCreate();
- pvDataCreate = getPVDataCreate();
- standardField = getStandardField();
- standardPVField = new StandardPVFieldExt();
- ShowConstructDestruct::registerCallback(
- "standardPVField",
- 0,0,0,myDeleteStatic);
- }
+ epicsThreadOnce(&myInitOnce, &myInitStatic, 0);
return standardPVField;
}
diff --git a/pvDataApp/misc/CDRMonitor.cpp b/pvDataApp/misc/CDRMonitor.cpp
new file mode 100644
index 0000000..7d9c1a4
--- /dev/null
+++ b/pvDataApp/misc/CDRMonitor.cpp
@@ -0,0 +1,90 @@
+/* CDRMonitor.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
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#include "noDefaultMethods.h"
+#include "lock.h"
+#include "pvType.h"
+#include "linkedList.h"
+#include "CDRMonitor.h"
+
+namespace epics { namespace pvData {
+
+static
+epicsThreadOnceId monitorInit = EPICS_THREAD_ONCE_INIT;
+
+// Must use a pointer w/ lazy init due to lack of
+// initialization order guarantees
+CDRMonitor* CDRMonitor::theone = 0;
+
+CDRMonitor&
+CDRMonitor::get()
+{
+ epicsThreadOnce(&monitorInit, &CDRMonitor::init, 0);
+ assert(theone);
+ return *theone;
+}
+
+void
+CDRMonitor::init(void *)
+{
+ //BUG: No idea how to handle allocation failure at this stage.
+ theone=new CDRMonitor;
+}
+
+CDRMonitor::CDRMonitor()
+ :firstNode(0)
+{}
+
+CDRCount
+CDRMonitor::current()
+{
+ CDRCount total;
+ for(CDRNode *cur=first(); !!cur; cur=cur->next())
+ {
+ total+=cur->get();
+ }
+ return total;
+}
+
+void
+CDRMonitor::show(FILE *fd)
+{
+ for(CDRNode *cur=first(); !!cur; cur=cur->next())
+ {
+ cur->show(fd);
+ }
+}
+
+void
+CDRNode::show(FILE *fd)
+{
+ Lock x(&guard);
+ if(!current.cons && !current.dtys && !current.refs)
+ return;
+ fprintf(fd,"%s: totalConstruct %lu totalDestruct %lu",
+ nodeName.c_str(), (unsigned long)current.cons,
+ (unsigned long)current.dtys);
+ ssize_t alive=current.cons;
+ alive-=current.dtys;
+ if(current.refs)
+ fprintf(fd," totalReference %ld", current.refs);
+ if(alive)
+ fprintf(fd," ACTIVE %ld\n", (long)alive);
+ else
+ fprintf(fd,"\n");
+}
+
+
+}}
diff --git a/pvDataApp/misc/CDRMonitor.h b/pvDataApp/misc/CDRMonitor.h
new file mode 100644
index 0000000..cd3feb1
--- /dev/null
+++ b/pvDataApp/misc/CDRMonitor.h
@@ -0,0 +1,94 @@
+/* CDRMonitor.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
+#include
+#include
+#include
+#include
+
+#include "noDefaultMethods.h"
+#include "lock.h"
+#include "pvType.h"
+
+namespace epics { namespace pvData {
+
+//! Used to pass around snapshots
+struct CDRCount { // default copy and assignment are ok
+ size_t cons, dtys;
+ long refs;
+ CDRCount():cons(0),dtys(0),refs(0){}
+ CDRCount& operator+=(const CDRCount& o)
+ {cons+=o.cons; dtys+=o.dtys; refs+=o.refs; return *this;}
+ CDRCount& operator=(size_t count) // reset counters
+ {cons=count; dtys=count; refs=count; return *this;}
+};
+
+class CDRNode;
+
+//! @brief Global registrar for CDRNodes
+class CDRMonitor : private NoDefaultMethods {
+public:
+ static CDRMonitor& get();
+
+ CDRNode* addNode(CDRNode& next)
+ {
+ CDRNode *ret=firstNode;
+ firstNode=&next;
+ return ret;
+ }
+
+ CDRCount current(); //!< current global count
+
+ CDRNode* first(){return firstNode;}
+
+ void show(FILE*);
+private:
+ // Private ctor for singleton
+ CDRMonitor();
+ CDRNode *firstNode;
+
+ static CDRMonitor *theone;
+ static void init(void*);
+};
+
+//! Counters for Construction, Destruction, and References of one class
+class CDRNode : private NoDefaultMethods {
+public:
+ CDRNode(const String& name)
+ :nodeName(name)
+ ,current()
+ ,guard()
+ ,nextNode(CDRMonitor::get().addNode(*this))
+ {}
+ void construct(){Lock x(&guard); current.cons++;}
+ void destruct(){Lock x(&guard); current.dtys++;}
+ void incRef(){Lock x(&guard); current.refs++;}
+ void decRef(){Lock x(&guard); current.refs--;}
+
+ CDRNode* next() const{return nextNode;}
+
+ CDRCount get() const{Lock x(&guard); return current;}
+
+ void show(FILE*);
+private:
+ const String nodeName;
+ CDRCount current;
+ mutable Mutex guard;
+ CDRNode * const nextNode;
+};
+
+#define PVDATA_REFCOUNT_MONITOR_DEFINE(NAME) static CDRNode NAME ## _node(#NAME)
+
+#define PVDATA_REFCOUNT_MONITOR_DESTRUCT(NAME) NAME ## _node.destruct()
+
+#define PVDATA_REFCOUNT_MONITOR_CONSTRUCT(NAME) NAME ## _node.construct()
+
+
+}}
+#endif /* SHOWCONSTRUCTDESTRUCT_H */
diff --git a/pvDataApp/misc/StatusCreateFactory.cpp b/pvDataApp/misc/StatusCreateFactory.cpp
index f78de6d..1df4157 100644
--- a/pvDataApp/misc/StatusCreateFactory.cpp
+++ b/pvDataApp/misc/StatusCreateFactory.cpp
@@ -11,7 +11,7 @@
#include "lock.h"
#include "factory.h"
#include "byteBuffer.h"
-#include "showConstructDestruct.h"
+#include "CDRMonitor.h"
#include "status.h"
#include "serializeHelper.h"
diff --git a/pvDataApp/misc/bitSet.cpp b/pvDataApp/misc/bitSet.cpp
index 83a81ca..353b42b 100644
--- a/pvDataApp/misc/bitSet.cpp
+++ b/pvDataApp/misc/bitSet.cpp
@@ -8,7 +8,7 @@
#include "stdio.h"
#include "bitSet.h"
#include "lock.h"
-#include "showConstructDestruct.h"
+#include "CDRMonitor.h"
#include "serializeHelper.h"
namespace epics { namespace pvData {
diff --git a/pvDataApp/misc/event.cpp b/pvDataApp/misc/event.cpp
index 52b5fa3..0ecb649 100644
--- a/pvDataApp/misc/event.cpp
+++ b/pvDataApp/misc/event.cpp
@@ -20,54 +20,24 @@
#include "pvType.h"
#include "lock.h"
#include "event.h"
-#include "showConstructDestruct.h"
+#include "CDRMonitor.h"
namespace epics { namespace pvData {
-static Mutex globalMutex;
-static volatile int64 totalConstruct = 0;
-static volatile int64 totalDestruct = 0;
-static bool notInited = true;
+PVDATA_REFCOUNT_MONITOR_DEFINE(event);
static String alreadyOn("already on list");
-
-static int64 getTotalConstruct()
-{
- Lock xx(&globalMutex);
- return totalConstruct;
-}
-
-static int64 getTotalDestruct()
-{
- Lock xx(&globalMutex);
- return totalDestruct;
-}
-
-static void init()
-{
- Lock xx(&globalMutex);
- if(notInited) {
- notInited = false;
- ShowConstructDestruct::registerCallback(
- String("event"),
- getTotalConstruct,getTotalDestruct,0,0);
- }
-}
-
Event::~Event() {
epicsEventDestroy(id);
id = 0;
- Lock xx(&globalMutex);
- totalDestruct++;
+ PVDATA_REFCOUNT_MONITOR_DESTRUCT(event);
}
Event::Event(bool full)
: id(epicsEventCreate(full?epicsEventFull : epicsEventEmpty))
{
- init();
- Lock xx(&globalMutex);
- totalConstruct++;
+ PVDATA_REFCOUNT_MONITOR_CONSTRUCT(event);
}
void Event::signal()
diff --git a/pvDataApp/misc/executor.cpp b/pvDataApp/misc/executor.cpp
index 7ec1e04..5e44b8d 100644
--- a/pvDataApp/misc/executor.cpp
+++ b/pvDataApp/misc/executor.cpp
@@ -17,37 +17,11 @@
#include "thread.h"
#include "event.h"
#include "executor.h"
-#include "showConstructDestruct.h"
+#include "CDRMonitor.h"
namespace epics { namespace pvData {
-static volatile int64 totalConstruct = 0;
-static volatile int64 totalDestruct = 0;
-static Mutex globalMutex;
-static bool notInited = true;
-
-static int64 getTotalConstruct()
-{
- Lock xx(&globalMutex);
- return totalConstruct;
-}
-
-static int64 getTotalDestruct()
-{
- Lock xx(&globalMutex);
- return totalDestruct;
-}
-
-static void init() {
- Lock xx(&globalMutex);
- if(notInited) {
- notInited = false;
- ShowConstructDestruct::registerCallback(
- String("executor"),
- getTotalConstruct,getTotalDestruct,0,0);
- }
-}
-
+PVDATA_REFCOUNT_MONITOR_DEFINE(executor);
typedef LinkedListNode ExecutorListNode;
typedef LinkedList ExecutorList;
@@ -55,25 +29,18 @@ typedef LinkedList ExecutorList;
class ExecutorNode {
public:
ExecutorNode(Command *command);
- ~ExecutorNode();
Command *command;
- ExecutorListNode *node;
- ExecutorListNode *runNode;
+ ExecutorListNode node;
+ ExecutorListNode runNode;
};
ExecutorNode::ExecutorNode(Command *command)
: command(command),
- node(new ExecutorListNode(this)),
- runNode(new ExecutorListNode(this))
+ node(this),
+ runNode(this)
{}
-ExecutorNode::~ExecutorNode()
-{
- delete node;
- delete runNode;
-}
-
class ExecutorPvt : public Runnable{
public:
ExecutorPvt(String threadName,ThreadPriority priority);
@@ -82,23 +49,23 @@ public:
void execute(ExecutorNode *node);
virtual void run();
private:
- ExecutorList *executorList;
- ExecutorList *runList;
- Event *moreWork;
- Event *stopped;
+ ExecutorList executorList;
+ ExecutorList runList;
+ Event moreWork;
+ Event stopped;
Mutex mutex;
volatile bool alive;
- Thread *thread;
+ Thread thread;
};
ExecutorPvt::ExecutorPvt(String threadName,ThreadPriority priority)
-: executorList(new ExecutorList()),
- runList(new ExecutorList()),
- moreWork(new Event(false)),
- stopped(new Event(false)),
- mutex(Mutex()),
+: executorList(),
+ runList(),
+ moreWork(),
+ stopped(),
+ mutex(),
alive(true),
- thread(new Thread(threadName,priority,this))
+ thread(threadName,priority,this)
{}
ExecutorPvt::~ExecutorPvt()
@@ -107,69 +74,61 @@ ExecutorPvt::~ExecutorPvt()
Lock xx(&mutex);
alive = false;
}
- moreWork->signal();
+ moreWork.signal();
{
Lock xx(&mutex);
- stopped->wait();
+ stopped.wait();
}
ExecutorListNode *node;
- while((node=executorList->removeHead())!=0) {
+ while((node=executorList.removeHead())!=0) {
delete node->getObject();
}
- delete thread;
- delete stopped;
- delete moreWork;
- delete runList;
- delete executorList;
}
void ExecutorPvt::run()
{
while(alive) {
ExecutorListNode * executorListNode = 0;
- while(alive && runList->isEmpty()) {
- moreWork->wait();
+ while(alive && runList.isEmpty()) {
+ moreWork.wait();
}
if(alive) {
Lock xx(&mutex);
- executorListNode = runList->removeHead();
+ executorListNode = runList.removeHead();
}
if(alive && executorListNode!=0) {
executorListNode->getObject()->command->command();
}
}
- stopped->signal();
+ stopped.signal();
}
ExecutorNode * ExecutorPvt::createNode(Command *command)
{
Lock xx(&mutex);
ExecutorNode *executorNode = new ExecutorNode(command);
- executorList->addTail(executorNode->node);
+ 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();
+ if(!alive || node->runNode.isOnList()) return;
+ bool isEmpty = runList.isEmpty();
+ runList.addTail(&node->runNode);
+ if(isEmpty) moreWork.signal();
}
Executor::Executor(String threadName,ThreadPriority priority)
: pImpl(new ExecutorPvt(threadName,priority))
{
- init();
- Lock xx(&globalMutex);
- totalConstruct++;
+ PVDATA_REFCOUNT_MONITOR_CONSTRUCT(executor);
}
Executor::~Executor() {
delete pImpl;
- Lock xx(&globalMutex);
- totalDestruct++;
+ PVDATA_REFCOUNT_MONITOR_DESTRUCT(executor);
}
ExecutorNode * Executor::createNode(Command*command)
diff --git a/pvDataApp/misc/linkedListVoid.cpp b/pvDataApp/misc/linkedListVoid.cpp
index 7b1d6e4..a94c6b8 100644
--- a/pvDataApp/misc/linkedListVoid.cpp
+++ b/pvDataApp/misc/linkedListVoid.cpp
@@ -14,80 +14,31 @@
#include "lock.h"
#include "pvType.h"
#include "linkedListVoid.h"
-#include "showConstructDestruct.h"
+#include "CDRMonitor.h"
namespace epics { namespace pvData {
-static Mutex globalMutex;
static String alreadyOnList("already on list");
-static volatile int64 totalNodeConstruct = 0;
-static volatile int64 totalNodeDestruct = 0;
-static volatile int64 totalListConstruct = 0;
-static volatile int64 totalListDestruct = 0;
-static bool notInited = true;
-
-static int64 getTotalNodeConstruct()
-{
- Lock xx(&globalMutex);
- return totalNodeConstruct;
-}
-
-static int64 getTotalNodeDestruct()
-{
- Lock xx(&globalMutex);
- return totalNodeDestruct;
-}
-
-static int64 getTotalListConstruct()
-{
- Lock xx(&globalMutex);
- return totalListConstruct;
-}
-
-static int64 getTotalListDestruct()
-{
- Lock xx(&globalMutex);
- return totalListDestruct;
-}
-
-static void initPvt()
-{
- Lock xx(&globalMutex);
- if(notInited) {
- notInited = false;
- ShowConstructDestruct::registerCallback(
- "linkedListNode",
- getTotalNodeConstruct,getTotalNodeDestruct,0,0);
-
- ShowConstructDestruct::registerCallback(
- "linkedList",
- getTotalListConstruct,getTotalListDestruct,0,0);
- }
-}
-
+PVDATA_REFCOUNT_MONITOR_DEFINE(LinkedListNode);
+PVDATA_REFCOUNT_MONITOR_DEFINE(LinkedList);
LinkedListVoidNode::LinkedListVoidNode(void *object)
: object(object),before(0),after(0),linkedListVoid(0)
{
- initPvt();
- Lock xx(&globalMutex);
- totalNodeConstruct++;
+ PVDATA_REFCOUNT_MONITOR_CONSTRUCT(LinkedListNode);
}
LinkedListVoidNode::LinkedListVoidNode(bool isHead)
: object(this),before(this),after(this)
{
- initPvt();
- Lock xx(&globalMutex);
- totalNodeConstruct++;
+ PVDATA_REFCOUNT_MONITOR_CONSTRUCT(LinkedListNode);
}
LinkedListVoidNode::~LinkedListVoidNode()
{
- Lock xx(&globalMutex);
- totalNodeDestruct++;
+ PVDATA_REFCOUNT_MONITOR_DESTRUCT(LinkedListNode);
}
void *LinkedListVoidNode::getObject() {
@@ -103,16 +54,13 @@ bool LinkedListVoidNode::isOnList()
LinkedListVoid::LinkedListVoid()
: head(new LinkedListVoidNode(true)),length(0)
{
- initPvt();
- Lock xx(&globalMutex);
- totalListConstruct++;
+ PVDATA_REFCOUNT_MONITOR_CONSTRUCT(LinkedList);
}
LinkedListVoid::~LinkedListVoid()
{
- Lock xx(&globalMutex);
delete head;
- totalListDestruct++;
+ PVDATA_REFCOUNT_MONITOR_DESTRUCT(LinkedList);
}
int LinkedListVoid::getLength()
diff --git a/pvDataApp/misc/lock.h b/pvDataApp/misc/lock.h
index 70e7a2d..485dc84 100644
--- a/pvDataApp/misc/lock.h
+++ b/pvDataApp/misc/lock.h
@@ -6,6 +6,7 @@
*/
#ifndef LOCK_H
#define LOCK_H
+#include
#include
#include "noDefaultMethods.h"
/* This is based on item 14 of
@@ -14,25 +15,101 @@
namespace epics { namespace pvData {
+typedef epicsMutexId native_handle_type;
+
+/** @brief Acquires and holds a mutex until destructed
+ *
+ * Partial implementation of boost::lock_guard<>
+ */
+template
+class lock_guard : private NoDefaultMethods {
+public:
+ typedef Lockable mutex_type;
+ explicit lock_guard(Lockable &m)
+ : mutex(m)
+ {mutex.lock();}
+ explicit lock_guard(Lockable *pm)
+ : mutex(*pm)
+ {mutex.lock();}
+ ~lock_guard(){mutex.unlock();}
+private:
+ Lockable& mutex;
+};
+
+/* Lock action tags.
+ * Used to select construction behaviour of locks
+ */
+struct defer_lock_t{};
+//struct adopt_lock_t{};
+
+const defer_lock_t defer_lock={};
+//const adopt_lock_t adopt_lock={};
+
+/** @brief Acquires a mutex. Always releases destructed
+ *
+ * May release and re-acquire.
+ * Partial implementation of boost::unique_lock<>
+ */
+template
+class unique_lock : private NoDefaultMethods {
+public:
+ typedef Lockable mutex_type;
+ explicit unique_lock(Lockable &m)
+ : mutexPtr(&m), locked(true)
+ {mutex->lock();}
+ unique_lock(Lockable &m, defer_lock_t)
+ : mutexPtr(m), locked(false)
+ {}
+ void swap(unique_lock& O)
+ {
+ Lockable *t=O.mutexPtr;
+ bool tl=O.locked;
+ O.mutexPtr=mutexPtr;
+ O.locked=locked;
+ mutexPtr=t;
+ locked=tl;
+ }
+ void lock()
+ {
+ if(!locked)
+ mutexPtr->lock();
+ locked=true;
+ }
+ void unlock()
+ {
+ if(locked)
+ mutexPtr->unlock();
+ locked=false;
+ }
+ bool owns_lock() const{return locked;}
+
+ Lockable* mutex() const{return mutex;}
+ Lockable* release(){locked=false; return mutex;}
+
+private:
+ Lockable *mutexPtr;
+ bool locked;
+};
+
class Mutex {
public:
- Mutex() : id(epicsMutexMustCreate()){}
+ typedef unique_lock scoped_lock;
+ Mutex() : id(epicsMutexCreate())
+ {if(!id) throw std::bad_alloc();}
~Mutex() { epicsMutexDestroy(id) ;}
- void lock(){epicsMutexMustLock(id);}
+ void lock(){
+ if(epicsMutexLock(id)!=epicsMutexLockOK)
+ throw std::logic_error("Failed to acquire Mutex");
+ }
void unlock(){epicsMutexUnlock(id);}
+
+ native_handle_type native_handle(){return id;}
private:
epicsMutexId id;
};
+typedef lock_guard Lock;
+
-class Lock : private NoDefaultMethods {
-public:
- explicit Lock(Mutex *pm)
- : mutexPtr(pm)
- {mutexPtr->lock();}
- ~Lock(){mutexPtr->unlock();}
-private:
- Mutex *mutexPtr;
-};
}}
#endif /* LOCK_H */
diff --git a/pvDataApp/misc/messageQueue.cpp b/pvDataApp/misc/messageQueue.cpp
index eea6deb..e2dc4bf 100644
--- a/pvDataApp/misc/messageQueue.cpp
+++ b/pvDataApp/misc/messageQueue.cpp
@@ -15,39 +15,13 @@
#include "lock.h"
#include "requester.h"
#include "noDefaultMethods.h"
-#include "showConstructDestruct.h"
+#include "CDRMonitor.h"
#include "queue.h"
#include "messageQueue.h"
namespace epics { namespace pvData {
-static volatile int64 totalQueueConstruct = 0;
-static volatile int64 totalQueueDestruct = 0;
-static Mutex globalMutex;
-static bool notInited = true;
-
-static int64 getTotalQueueConstruct()
-{
- Lock xx(&globalMutex);
- return totalQueueConstruct;
-}
-
-static int64 getTotalQueueDestruct()
-{
- Lock xx(&globalMutex);
- return totalQueueDestruct;
-}
-
-static void initPvt()
-{
- Lock xx(&globalMutex);
- if(notInited) {
- notInited = false;
- ShowConstructDestruct::registerCallback(
- "messageQueue",
- getTotalQueueConstruct,getTotalQueueDestruct,0,0);
- }
-}
+PVDATA_REFCOUNT_MONITOR_DEFINE(messageQueue);
typedef MessageNode * MessageNodePtr;
typedef QueueElement MessageElement;
@@ -79,9 +53,7 @@ public:
MessageQueue::MessageQueue(int size)
: pImpl(new MessageQueuePvt)
{
- initPvt();
- Lock xx(&globalMutex);
- totalQueueConstruct++;
+ PVDATA_REFCOUNT_MONITOR_CONSTRUCT(messageQueue);
pImpl->size = size;
pImpl->overrun = 0;
pImpl->lastPut = 0;
@@ -100,8 +72,7 @@ MessageQueue::~MessageQueue()
delete pImpl->messageNodeArray[i];
}
delete[] pImpl->messageNodeArray;
- Lock xx(&globalMutex);
- totalQueueDestruct++;
+ PVDATA_REFCOUNT_MONITOR_DESTRUCT(messageQueue);
}
MessageNode *MessageQueue::get() {
diff --git a/pvDataApp/misc/queueVoid.cpp b/pvDataApp/misc/queueVoid.cpp
index c8274eb..c263758 100644
--- a/pvDataApp/misc/queueVoid.cpp
+++ b/pvDataApp/misc/queueVoid.cpp
@@ -14,69 +14,23 @@
#include "lock.h"
#include "pvType.h"
#include "queueVoid.h"
-#include "showConstructDestruct.h"
+#include "CDRMonitor.h"
namespace epics { namespace pvData {
-static volatile int64 totalElementConstruct = 0;
-static volatile int64 totalElementDestruct = 0;
-static volatile int64 totalQueueConstruct = 0;
-static volatile int64 totalQueueDestruct = 0;
-static Mutex globalMutex;
-static bool notInited = true;
-
-static int64 getTotalNodeConstruct()
-{
- Lock xx(&globalMutex);
- return totalElementConstruct;
-}
-
-static int64 getTotalNodeDestruct()
-{
- Lock xx(&globalMutex);
- return totalElementDestruct;
-}
-
-static int64 getTotalListConstruct()
-{
- Lock xx(&globalMutex);
- return totalQueueConstruct;
-}
-
-static int64 getTotalListDestruct()
-{
- Lock xx(&globalMutex);
- return totalQueueDestruct;
-}
-
-static void initPvt()
-{
- Lock xx(&globalMutex);
- if(notInited) {
- notInited = false;
- ShowConstructDestruct::registerCallback(
- "queueElement",
- getTotalNodeConstruct,getTotalNodeDestruct,0,0);
- ShowConstructDestruct::registerCallback(
- "queue",
- getTotalListConstruct,getTotalListDestruct,0,0);
- }
-}
-
+PVDATA_REFCOUNT_MONITOR_DEFINE(queueElement);
+PVDATA_REFCOUNT_MONITOR_DEFINE(queue);
QueueElementVoid::QueueElementVoid(ObjectPtr object)
: object(object)
{
- initPvt();
- Lock xx(&globalMutex);
- totalElementConstruct++;
+ PVDATA_REFCOUNT_MONITOR_CONSTRUCT(queueElement);
}
QueueElementVoid::~QueueElementVoid()
{
- Lock xx(&globalMutex);
- totalElementDestruct++;
+ PVDATA_REFCOUNT_MONITOR_DESTRUCT(queueElement);
}
ObjectPtr QueueElementVoid::getObject() {
@@ -94,9 +48,7 @@ QueueVoid::QueueVoid(ObjectPtr object[],int number)
for(int i=0; i
-#include
-#include
-#include
-#include
-#include
-
-#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;
-static bool notInited = true;
-typedef LinkedListNode ListNode;
-typedef LinkedList List;
-static List *list;
-
-/* list callbacks are special because showConstructDestruct creates a list
- Thus list can be null when list calls registerCallback
- The list callbacks are not put on the list but handled separately
- */
-static ConstructDestructCallback *listCallback = 0;
-static ConstructDestructCallback *listNodeCallback = 0;
-
-ConstructDestructCallback::ConstructDestructCallback(
- String name,
- getTotalFunc construct,
- getTotalFunc destruct,
- getTotalFunc reference,
- deleteStaticFunc deleteFunc)
-: name(name), construct(construct), destruct(destruct) ,reference(reference),
- deleteFunc(deleteFunc)
-{ }
-
-ConstructDestructCallback::~ConstructDestructCallback() {}
-
-String ConstructDestructCallback::getConstructName()
-{
- return name;
-}
-
-int64 ConstructDestructCallback::getTotalConstruct()
-{
- if(construct==0) return 0;
- return construct();
-}
-
-int64 ConstructDestructCallback:: getTotalDestruct()
-{
- if(destruct==0) return 0;
- return destruct();
-}
-
-int64 ConstructDestructCallback::getTotalReferenceCount()
-{
- if(reference==0) return 0;
- return reference();
-}
-
-void ConstructDestructCallback::deleteStatic()
-{
- if(deleteFunc==0) return;
- deleteFunc();
-}
-
-ShowConstructDestruct::ShowConstructDestruct() {}
-
-ShowConstructDestruct::~ShowConstructDestruct() {
- delete listCallback;
- delete listNodeCallback;
- listCallback = 0;
- listNodeCallback = 0;
-}
-
-void ShowConstructDestruct::registerCallback(
- String name,
- getTotalFunc construct,
- getTotalFunc destruct,
- getTotalFunc reference,
- deleteStaticFunc deleteFunc)
-{
- getShowConstructDestruct(); // make it initialize
- Lock xx(&globalMutex);
- if(name.compare("linkedList")==0) {
- listCallback = new ConstructDestructCallback(
- name,construct,destruct,reference,deleteFunc);
- return;
- } else if(name.compare("linkedListNode")==0) {
- listNodeCallback = new ConstructDestructCallback(
- name,construct,destruct,reference,deleteFunc);
- return;
- }
- if(list==0) {
- throw std::logic_error(String(
- "ShowConstructDestruct::registerCallback"));
- }
- ConstructDestructCallback *callback = new ConstructDestructCallback(
- name,construct,destruct,reference,deleteFunc);
- ListNode *listNode = new ListNode(callback);
- list->addTail(listNode);
-}
-static void showOne(ConstructDestructCallback *callback,FILE *fd)
-{
- String name = callback->getConstructName();
- int64 reference = callback->getTotalReferenceCount();
- int64 construct = callback->getTotalConstruct();
- int64 destruct = callback->getTotalDestruct();
- if(reference==0&&construct==0&&destruct==0) return;
- fprintf(fd,"%s: ", name.c_str());
- if(construct>0 || destruct>0) {
- fprintf(fd," totalConstruct %lli totalDestruct %lli",
- construct,destruct);
- }
- if(reference>0) fprintf(fd," totalReference %lli",reference);
- int64 diff = construct - destruct;
- if(diff!=0) fprintf(fd," ACTIVE %lli",diff);
- fprintf(fd,"\n");
-}
-
-ConstructDestructCallback* ShowConstructDestruct::getConstructDestructCallback(
- String name)
-{
- if(name.compare(listNodeCallback->getConstructName())==0) {
- return listNodeCallback;
- }
- if(name.compare(listCallback->getConstructName())==0) {
- return listCallback;
- }
- Lock xx(&globalMutex);
- ListNode *node = list->getHead();
- while(node!=0) {
- ConstructDestructCallback *callback = node->getObject();
- if(name.compare(callback->getConstructName())==0) {
- return callback;
- }
- node = list->getNext(node);
- }
- return 0;
-}
-
-void ShowConstructDestruct::constuctDestructTotals(FILE *fd)
-{
- getShowConstructDestruct(); // make it initialize
- Lock xx(&globalMutex);
- ListNode *node = list->getHead();
- while(node!=0) {
- ConstructDestructCallback *callback = node->getObject();
- showOne(callback,fd);
- node = list->getNext(node);
- }
- showOne(listNodeCallback,fd);
- showOne(listCallback,fd);
-}
-
-void ShowConstructDestruct::showDeleteStaticExit(FILE *fd)
-{
- getShowConstructDestruct(); // make it initialize
- {
- Lock xx(&globalMutex);
- ListNode *node = list->getHead();
- while(node!=0) {
- ConstructDestructCallback *callback = node->getObject();
- if(callback->deleteFunc!=0) callback->deleteFunc();
- node = list->getNext(node);
- }
- node = list->getHead();
- while(node!=0) {
- ConstructDestructCallback *callback = node->getObject();
- showOne(callback,fd);
- list->removeHead();
- delete callback;
- delete node;
- node = list->getHead();
- }
- delete list;
- if(listNodeCallback->deleteFunc!=0) listNodeCallback->deleteFunc();
- if(listCallback->deleteFunc!=0) listCallback->deleteFunc();
- showOne(listNodeCallback,fd);
- showOne(listCallback,fd);
- delete pShowConstructDestruct;
- pShowConstructDestruct = 0;
- }
- exit( 0);
-}
-
-ShowConstructDestruct * getShowConstructDestruct()
-{
- static Mutex mutex;
- Lock xx(&mutex);
- if(notInited) {
- notInited = false;
- pShowConstructDestruct = new ShowConstructDestruct();
- List *listTemp;
- listTemp = new List();
- list = listTemp;
- }
- return pShowConstructDestruct;
-}
-
-}}
diff --git a/pvDataApp/misc/showConstructDestruct.h b/pvDataApp/misc/showConstructDestruct.h
deleted file mode 100644
index 643b9ac..0000000
--- a/pvDataApp/misc/showConstructDestruct.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/* 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
-#include
-#include
-#include
-#include
-
-#include "noDefaultMethods.h"
-#include "pvType.h"
-
-namespace epics { namespace pvData {
-
-typedef int64 (*getTotalFunc)();
-typedef void (*deleteStaticFunc)();
-
-class ConstructDestructCallback : private NoDefaultMethods {
-public:
- String getConstructName();
- int64 getTotalConstruct();
- int64 getTotalDestruct();
- int64 getTotalReferenceCount();
-private:
- ConstructDestructCallback(
- String name,
- getTotalFunc construct,
- getTotalFunc destruct,
- getTotalFunc reference,
- deleteStaticFunc deleteFunc);
- ~ConstructDestructCallback();
- void deleteStatic();
- String name;
- getTotalFunc construct;
- getTotalFunc destruct;
- getTotalFunc reference;
- deleteStaticFunc deleteFunc;
- friend class ShowConstructDestruct;
-};
-
-class ShowConstructDestruct : private NoDefaultMethods {
-public:
- static void registerCallback(
- String name,
- getTotalFunc construct,
- getTotalFunc destruct,
- getTotalFunc reference,
- deleteStaticFunc deleteFunc);
- ConstructDestructCallback* getConstructDestructCallback(String name);
- void constuctDestructTotals(FILE *fd);
- static void showDeleteStaticExit(FILE *fd);
-private:
- ShowConstructDestruct();
- ~ShowConstructDestruct();
- friend ShowConstructDestruct* getShowConstructDestruct();
-};
-
-extern ShowConstructDestruct* getShowConstructDestruct();
-
-
-
-/* convenience macros - no getTotalReferenceCount() support */
-
-#define PVDATA_REFCOUNT_MONITOR_DEFINE(NAME) \
- static volatile int64 NAME ## _totalConstruct = 0; \
- static volatile int64 NAME ## _totalDestruct = 0; \
- static Mutex NAME ## _globalMutex; \
- \
- static bool NAME ## _notInited = true; \
- static int64 NAME ## _processTotalConstruct() \
- { \
- Lock xx(&NAME ## _globalMutex); \
- return NAME ## _totalConstruct; \
- } \
- \
- static int64 NAME ## _processTotalDestruct() \
- { \
- Lock xx(&NAME ## _globalMutex); \
- return NAME ## _totalDestruct; \
- } \
- \
- static void NAME ## _init() \
- { \
- Lock xx(&NAME ## _globalMutex); \
- if(NAME ## _notInited) { \
- NAME ## _notInited = false; \
- ShowConstructDestruct::registerCallback( \
- String(#NAME), \
- NAME ## _processTotalConstruct,NAME ## _processTotalDestruct,0,0); \
- } \
- }
-
-#define PVDATA_REFCOUNT_MONITOR_DESTRUCT(NAME) \
- Lock xx(&NAME ## _globalMutex); \
- NAME ## _totalDestruct++;
-
-#define PVDATA_REFCOUNT_MONITOR_CONSTRUCT(NAME) \
- NAME ## _init(); \
- Lock xx(&NAME ## _globalMutex); \
- NAME ## _totalConstruct++;
-
-
-}}
-#endif /* SHOWCONSTRUCTDESTRUCT_H */
diff --git a/pvDataApp/misc/thread.cpp b/pvDataApp/misc/thread.cpp
index feb10b8..587ec55 100644
--- a/pvDataApp/misc/thread.cpp
+++ b/pvDataApp/misc/thread.cpp
@@ -13,11 +13,12 @@
#include
#include
+#include
#include "lock.h"
#include "event.h"
#include "thread.h"
#include "linkedList.h"
-#include "showConstructDestruct.h"
+#include "CDRMonitor.h"
namespace epics { namespace pvData {
@@ -47,41 +48,25 @@ class ThreadListElement;
typedef LinkedListNode ThreadListNode;
typedef LinkedList ThreadList;
-static volatile int64 totalConstruct = 0;
-static volatile int64 totalDestruct = 0;
-static Mutex globalMutex;
-static bool notInited = true;
+PVDATA_REFCOUNT_MONITOR_DEFINE(thread);
+
+static Mutex listGuard;
static ThreadList *threadList;
-static int64 getTotalConstruct()
-{
- Lock xx(&globalMutex);
- return totalConstruct;
-}
-
-static int64 getTotalDestruct()
-{
- Lock xx(&globalMutex);
- return totalDestruct;
-}
-
-static void deleteStatic()
+static void deleteStatic(void*)
{
delete threadList;
}
-static void init()
+static void init(void*)
{
- Lock xx(&globalMutex);
- if(notInited) {
- notInited = false;
- threadList = new ThreadList();
- ShowConstructDestruct::registerCallback(
- String("thread"),
- getTotalConstruct,getTotalDestruct,0,deleteStatic);
- }
+ threadList = new ThreadList();
+ epicsAtExit(&deleteStatic,0);
}
+static
+epicsThreadOnceId initOnce = EPICS_THREAD_ONCE_INIT;
+
class ThreadListElement {
public:
@@ -136,10 +121,10 @@ ThreadPvt::ThreadPvt(Thread *thread,String name,
epicsThreadGetStackSize(epicsThreadStackSmall),
myFunc,this))
{
- init();
- Lock xx(&globalMutex);
+ epicsThreadOnce(&initOnce, &init, 0);
+ PVDATA_REFCOUNT_MONITOR_CONSTRUCT(thread);
+ Lock x(&listGuard);
threadList->addTail(threadListElement->node);
- totalConstruct++;
}
ThreadPvt::~ThreadPvt()
@@ -158,11 +143,11 @@ ThreadPvt::~ThreadPvt()
message += " is not on threadlist";
throw std::logic_error(message);
}
+ Lock x(&listGuard);
threadList->remove(threadListElement->node);
delete waitDone;
delete threadListElement;
- Lock xx(&globalMutex);
- totalDestruct++;
+ PVDATA_REFCOUNT_MONITOR_DESTRUCT(thread);
}
Thread::Thread(String name,ThreadPriority priority,Runnable *runnable)
@@ -192,8 +177,7 @@ ThreadPriority Thread::getPriority()
void Thread::showThreads(StringBuilder buf)
{
- init();
- Lock xx(&globalMutex);
+ Lock x(&listGuard);
ThreadListNode *node = threadList->getHead();
while(node!=0) {
Thread *thread = node->getObject()->thread;
diff --git a/pvDataApp/misc/timer.cpp b/pvDataApp/misc/timer.cpp
index 9750246..dd5483f 100644
--- a/pvDataApp/misc/timer.cpp
+++ b/pvDataApp/misc/timer.cpp
@@ -14,7 +14,7 @@
#include "pvType.h"
#include "lock.h"
#include "noDefaultMethods.h"
-#include "showConstructDestruct.h"
+#include "CDRMonitor.h"
#include "linkedList.h"
#include "thread.h"
#include "timeStamp.h"
@@ -23,51 +23,8 @@
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;
-static bool notInited = true;
-
-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 void init()
-{
- Lock xx(&globalMutex);
- if(notInited) {
- notInited = false;
- ShowConstructDestruct::registerCallback(
- "timerNode",
- getTotalTimerNodeConstruct,getTotalTimerNodeDestruct,0,0);
- ShowConstructDestruct::registerCallback(
- "timer",
- getTotalTimerConstruct,getTotalTimerDestruct,0,0);
- }
-}
+PVDATA_REFCOUNT_MONITOR_DEFINE(timerNode);
+PVDATA_REFCOUNT_MONITOR_DEFINE(timer);
class TimerNodePvt;
@@ -154,9 +111,7 @@ static void addElement(TimerPvt *timer,TimerNodePvt *node)
TimerNode::TimerNode(TimerCallback *callback)
: pImpl(new TimerNodePvt(this,callback))
{
- init();
- Lock xx(&globalMutex);
- totalNodeConstruct++;
+ PVDATA_REFCOUNT_MONITOR_CONSTRUCT(timerNode);
}
@@ -164,8 +119,7 @@ TimerNode::~TimerNode()
{
cancel();
delete pImpl;
- Lock xx(&globalMutex);
- totalNodeDestruct++;
+ PVDATA_REFCOUNT_MONITOR_DESTRUCT(timerNode);
}
void TimerNode::cancel()
@@ -240,9 +194,7 @@ void TimerPvt::run()
Timer::Timer(String threadName, ThreadPriority priority)
: pImpl(new TimerPvt(threadName,priority))
{
- init();
- Lock xx(&globalMutex);
- totalTimerConstruct++;
+ PVDATA_REFCOUNT_MONITOR_CONSTRUCT(timer);
}
Timer::~Timer() {
@@ -258,8 +210,7 @@ Timer::~Timer() {
node->getObject()->callback->timerStopped();
}
delete pImpl;
- Lock xx(&globalMutex);
- totalTimerDestruct++;
+ PVDATA_REFCOUNT_MONITOR_DESTRUCT(timer);
}
void Timer::scheduleAfterDelay(TimerNode *timerNode,double delay)
diff --git a/test/testIntrospect b/test/testIntrospect
index 9c5f4e7..591b0fe 100644
--- a/test/testIntrospect
+++ b/test/testIntrospect
@@ -79,5 +79,3 @@ structure value
int nanoSeconds
field: totalConstruct 120 totalDestruct 120
pvField: totalConstruct 47 totalDestruct 47
-linkedListNode: totalConstruct 4 totalDestruct 4
-linkedList: totalConstruct 1 totalDestruct 1
diff --git a/test/testIntrospectGold b/test/testIntrospectGold
index 9c5f4e7..591b0fe 100644
--- a/test/testIntrospectGold
+++ b/test/testIntrospectGold
@@ -79,5 +79,3 @@ structure value
int nanoSeconds
field: totalConstruct 120 totalDestruct 120
pvField: totalConstruct 47 totalDestruct 47
-linkedListNode: totalConstruct 4 totalDestruct 4
-linkedList: totalConstruct 1 totalDestruct 1
diff --git a/test/testLinkedList b/test/testLinkedList
index e149909..af50c54 100644
--- a/test/testLinkedList
+++ b/test/testLinkedList
@@ -17,5 +17,5 @@ stack 4 3 2 1 0
Ordered Queue test
list 0 1 2 3 4
-linkedListNode: totalConstruct 4039 totalDestruct 4039
-linkedList: totalConstruct 9 totalDestruct 9
+LinkedList: totalConstruct 8 totalDestruct 8
+LinkedListNode: totalConstruct 4038 totalDestruct 4038
diff --git a/test/testLinkedListGold b/test/testLinkedListGold
index e149909..af50c54 100644
--- a/test/testLinkedListGold
+++ b/test/testLinkedListGold
@@ -17,5 +17,5 @@ stack 4 3 2 1 0
Ordered Queue test
list 0 1 2 3 4
-linkedListNode: totalConstruct 4039 totalDestruct 4039
-linkedList: totalConstruct 9 totalDestruct 9
+LinkedList: totalConstruct 8 totalDestruct 8
+LinkedListNode: totalConstruct 4038 totalDestruct 4038
diff --git a/test/testMessageQueue b/test/testMessageQueue
index 36d38b1..ff56a18 100644
--- a/test/testMessageQueue
+++ b/test/testMessageQueue
@@ -1,7 +1,5 @@
message 1 messageType info
message 4 messageType info
-messageQueue: totalConstruct 1 totalDestruct 1
-queueElement: totalConstruct 3 totalDestruct 3
queue: totalConstruct 1 totalDestruct 1
-linkedListNode: totalConstruct 4 totalDestruct 4
-linkedList: totalConstruct 1 totalDestruct 1
+queueElement: totalConstruct 3 totalDestruct 3
+messageQueue: totalConstruct 1 totalDestruct 1
diff --git a/test/testMessageQueueGold b/test/testMessageQueueGold
index 36d38b1..ff56a18 100644
--- a/test/testMessageQueueGold
+++ b/test/testMessageQueueGold
@@ -1,7 +1,5 @@
message 1 messageType info
message 4 messageType info
-messageQueue: totalConstruct 1 totalDestruct 1
-queueElement: totalConstruct 3 totalDestruct 3
queue: totalConstruct 1 totalDestruct 1
-linkedListNode: totalConstruct 4 totalDestruct 4
-linkedList: totalConstruct 1 totalDestruct 1
+queueElement: totalConstruct 3 totalDestruct 3
+messageQueue: totalConstruct 1 totalDestruct 1
diff --git a/test/testPVAppend b/test/testPVAppend
index d742b1f..f0643db 100644
--- a/test/testPVAppend
+++ b/test/testPVAppend
@@ -30,5 +30,3 @@ structure parent
string Jane Bad Girl
field: totalConstruct 108 totalDestruct 108
pvField: totalConstruct 15 totalDestruct 14 ACTIVE 1
-linkedListNode: totalConstruct 5 totalDestruct 5
-linkedList: totalConstruct 1 totalDestruct 1
diff --git a/test/testPVAppendGold b/test/testPVAppendGold
index d742b1f..f0643db 100644
--- a/test/testPVAppendGold
+++ b/test/testPVAppendGold
@@ -30,5 +30,3 @@ structure parent
string Jane Bad Girl
field: totalConstruct 108 totalDestruct 108
pvField: totalConstruct 15 totalDestruct 14 ACTIVE 1
-linkedListNode: totalConstruct 5 totalDestruct 5
-linkedList: totalConstruct 1 totalDestruct 1
diff --git a/test/testPVAuxInfo b/test/testPVAuxInfo
index 37c78f5..b132b12 100644
--- a/test/testPVAuxInfo
+++ b/test/testPVAuxInfo
@@ -33,8 +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
+pvAuxInfo: totalConstruct 1 totalDestruct 1
field: totalConstruct 97 totalDestruct 97
pvField: totalConstruct 17 totalDestruct 17
-pvAuxInfo: totalConstruct 1 totalDestruct 1
-linkedListNode: totalConstruct 6 totalDestruct 6
-linkedList: totalConstruct 1 totalDestruct 1
diff --git a/test/testPVAuxInfoGold b/test/testPVAuxInfoGold
index 37c78f5..b132b12 100644
--- a/test/testPVAuxInfoGold
+++ b/test/testPVAuxInfoGold
@@ -33,8 +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
+pvAuxInfo: totalConstruct 1 totalDestruct 1
field: totalConstruct 97 totalDestruct 97
pvField: totalConstruct 17 totalDestruct 17
-pvAuxInfo: totalConstruct 1 totalDestruct 1
-linkedListNode: totalConstruct 6 totalDestruct 6
-linkedList: totalConstruct 1 totalDestruct 1
diff --git a/test/testPVData b/test/testPVData
index 029b329..a05b830 100644
--- a/test/testPVData
+++ b/test/testPVData
@@ -285,5 +285,3 @@ structure string
int nanoSeconds 0
field: totalConstruct 135 totalDestruct 135
pvField: totalConstruct 281 totalDestruct 281
-linkedListNode: totalConstruct 5 totalDestruct 5
-linkedList: totalConstruct 1 totalDestruct 1
diff --git a/test/testPVDataGold b/test/testPVDataGold
index 029b329..a05b830 100644
--- a/test/testPVDataGold
+++ b/test/testPVDataGold
@@ -285,5 +285,3 @@ structure string
int nanoSeconds 0
field: totalConstruct 135 totalDestruct 135
pvField: totalConstruct 281 totalDestruct 281
-linkedListNode: totalConstruct 5 totalDestruct 5
-linkedList: totalConstruct 1 totalDestruct 1
diff --git a/test/testPVStructureArray b/test/testPVStructureArray
index f50783e..3f8e332 100644
--- a/test/testPVStructureArray
+++ b/test/testPVStructureArray
@@ -172,5 +172,3 @@ after compressstructure powerSupply
int nanoSeconds 0
field: totalConstruct 102 totalDestruct 102
pvField: totalConstruct 88 totalDestruct 88
-linkedListNode: totalConstruct 5 totalDestruct 5
-linkedList: totalConstruct 1 totalDestruct 1
diff --git a/test/testPVStructureArrayGold b/test/testPVStructureArrayGold
index f50783e..3f8e332 100644
--- a/test/testPVStructureArrayGold
+++ b/test/testPVStructureArrayGold
@@ -172,5 +172,3 @@ after compressstructure powerSupply
int nanoSeconds 0
field: totalConstruct 102 totalDestruct 102
pvField: totalConstruct 88 totalDestruct 88
-linkedListNode: totalConstruct 5 totalDestruct 5
-linkedList: totalConstruct 1 totalDestruct 1
diff --git a/test/testQueue b/test/testQueue
index 0b0f26d..14669ad 100644
--- a/test/testQueue
+++ b/test/testQueue
@@ -1,6 +1,6 @@
-queueElement: totalConstruct 5 totalDestruct 5
-queue: totalConstruct 1 totalDestruct 1
+LinkedList: totalConstruct 1 totalDestruct 1
+LinkedListNode: totalConstruct 2 totalDestruct 2
event: totalConstruct 5 totalDestruct 5
thread: totalConstruct 1 totalDestruct 1
-linkedListNode: totalConstruct 7 totalDestruct 7
-linkedList: totalConstruct 2 totalDestruct 2
+queue: totalConstruct 1 totalDestruct 1
+queueElement: totalConstruct 5 totalDestruct 5
diff --git a/test/testQueueGold b/test/testQueueGold
index 0b0f26d..14669ad 100644
--- a/test/testQueueGold
+++ b/test/testQueueGold
@@ -1,6 +1,6 @@
-queueElement: totalConstruct 5 totalDestruct 5
-queue: totalConstruct 1 totalDestruct 1
+LinkedList: totalConstruct 1 totalDestruct 1
+LinkedListNode: totalConstruct 2 totalDestruct 2
event: totalConstruct 5 totalDestruct 5
thread: totalConstruct 1 totalDestruct 1
-linkedListNode: totalConstruct 7 totalDestruct 7
-linkedList: totalConstruct 2 totalDestruct 2
+queue: totalConstruct 1 totalDestruct 1
+queueElement: totalConstruct 5 totalDestruct 5
diff --git a/test/testThread b/test/testThread
index 8766374..6110dea 100644
--- a/test/testThread
+++ b/test/testThread
@@ -1,8 +1,8 @@
threads
basic middle
+LinkedList: totalConstruct 5 totalDestruct 5
+LinkedListNode: totalConstruct 11 totalDestruct 11
event: totalConstruct 8 totalDestruct 8
thread: totalConstruct 2 totalDestruct 2
executor: totalConstruct 2 totalDestruct 2
-linkedListNode: totalConstruct 15 totalDestruct 15
-linkedList: totalConstruct 6 totalDestruct 6
diff --git a/test/testThreadGold b/test/testThreadGold
index 8766374..6110dea 100644
--- a/test/testThreadGold
+++ b/test/testThreadGold
@@ -1,8 +1,8 @@
threads
basic middle
+LinkedList: totalConstruct 5 totalDestruct 5
+LinkedListNode: totalConstruct 11 totalDestruct 11
event: totalConstruct 8 totalDestruct 8
thread: totalConstruct 2 totalDestruct 2
executor: totalConstruct 2 totalDestruct 2
-linkedListNode: totalConstruct 15 totalDestruct 15
-linkedList: totalConstruct 6 totalDestruct 6
diff --git a/test/testTimer b/test/testTimer
index 9e1d103..116398a 100644
--- a/test/testTimer
+++ b/test/testTimer
@@ -1,6 +1,6 @@
+LinkedList: totalConstruct 4 totalDestruct 4
+LinkedListNode: totalConstruct 13 totalDestruct 13
event: totalConstruct 15 totalDestruct 15
thread: totalConstruct 3 totalDestruct 3
-timerNode: totalConstruct 6 totalDestruct 6
timer: totalConstruct 3 totalDestruct 3
-linkedListNode: totalConstruct 18 totalDestruct 18
-linkedList: totalConstruct 5 totalDestruct 5
+timerNode: totalConstruct 6 totalDestruct 6
diff --git a/test/testTimerGold b/test/testTimerGold
index 9e1d103..116398a 100644
--- a/test/testTimerGold
+++ b/test/testTimerGold
@@ -1,6 +1,6 @@
+LinkedList: totalConstruct 4 totalDestruct 4
+LinkedListNode: totalConstruct 13 totalDestruct 13
event: totalConstruct 15 totalDestruct 15
thread: totalConstruct 3 totalDestruct 3
-timerNode: totalConstruct 6 totalDestruct 6
timer: totalConstruct 3 totalDestruct 3
-linkedListNode: totalConstruct 18 totalDestruct 18
-linkedList: totalConstruct 5 totalDestruct 5
+timerNode: totalConstruct 6 totalDestruct 6
diff --git a/testApp/misc/testBitSet.cpp b/testApp/misc/testBitSet.cpp
index a5a2fb3..372689e 100644
--- a/testApp/misc/testBitSet.cpp
+++ b/testApp/misc/testBitSet.cpp
@@ -12,9 +12,10 @@
#include
#include
#include
-#include
+#include
#include
+#include
using namespace epics::pvData;
@@ -149,7 +150,8 @@ int main(int argc,char *argv[])
}
testGetSetClearFlip();
testOperators();
- getShowConstructDestruct()->showDeleteStaticExit(fd);
+ epicsExitCallAtExits();
+ CDRMonitor::get().show(fd);
return(0);
}
diff --git a/testApp/misc/testLinkedList.cpp b/testApp/misc/testLinkedList.cpp
index 1e39614..5f9e00e 100644
--- a/testApp/misc/testLinkedList.cpp
+++ b/testApp/misc/testLinkedList.cpp
@@ -18,11 +18,12 @@
#include
#include
+#include
#include "lock.h"
#include "timeStamp.h"
#include "linkedList.h"
-#include "showConstructDestruct.h"
+#include "CDRMonitor.h"
using namespace epics::pvData;
@@ -448,7 +449,8 @@ int main(int argc, char *argv[]) {
testTimeLocked(auxFd);
testStdListTime(auxFd);
testStdListTimeLocked(auxFd);
- getShowConstructDestruct()->showDeleteStaticExit(fd);
+ epicsExitCallAtExits();
+ CDRMonitor::get().show(fd);
return (0);
}
diff --git a/testApp/misc/testMessageQueue.cpp b/testApp/misc/testMessageQueue.cpp
index 5e0e3bd..4acb81d 100644
--- a/testApp/misc/testMessageQueue.cpp
+++ b/testApp/misc/testMessageQueue.cpp
@@ -17,12 +17,13 @@
#include
#include
+#include
#include "lock.h"
#include "timeStamp.h"
#include "requester.h"
#include "messageQueue.h"
-#include "showConstructDestruct.h"
+#include "CDRMonitor.h"
#include "event.h"
#include "thread.h"
#include "executor.h"
@@ -86,7 +87,8 @@ int main(int argc, char *argv[]) {
auxfd = fopen(auxFileName,"w+");
}
testBasic(fd,auxfd);
- getShowConstructDestruct()->showDeleteStaticExit(fd);
+ epicsExitCallAtExits();
+ CDRMonitor::get().show(fd);
return (0);
}
diff --git a/testApp/misc/testQueue.cpp b/testApp/misc/testQueue.cpp
index c519877..513d043 100644
--- a/testApp/misc/testQueue.cpp
+++ b/testApp/misc/testQueue.cpp
@@ -17,11 +17,12 @@
#include
#include
+#include
#include "lock.h"
#include "timeStamp.h"
#include "queue.h"
-#include "showConstructDestruct.h"
+#include "CDRMonitor.h"
#include "event.h"
#include "thread.h"
#include "executor.h"
@@ -155,7 +156,8 @@ int main(int argc, char *argv[]) {
auxfd = fopen(auxFileName,"w+");
}
testBasic(fd,auxfd);
- getShowConstructDestruct()->showDeleteStaticExit(fd);
+ epicsExitCallAtExits();
+ CDRMonitor::get().show(fd);
return (0);
}
diff --git a/testApp/misc/testSerialization.cpp b/testApp/misc/testSerialization.cpp
index 29999b1..c284e48 100644
--- a/testApp/misc/testSerialization.cpp
+++ b/testApp/misc/testSerialization.cpp
@@ -13,12 +13,13 @@
#include
+#include
#include "pvIntrospect.h"
#include "pvData.h"
#include "serialize.h"
#include "noDefaultMethods.h"
#include "byteBuffer.h"
-#include "showConstructDestruct.h"
+#include "CDRMonitor.h"
#define BYTE_MAX_VALUE 127
#define BYTE_MIN_VALUE -128
@@ -639,7 +640,8 @@ int main(int argc, char *argv[]) {
delete control;
delete flusher;
- getShowConstructDestruct()->showDeleteStaticExit(stdout);
+ epicsExitCallAtExits();
+ CDRMonitor::get().show(stdout);
cout<<"\nDone!\n";
return (0);
diff --git a/testApp/misc/testThread.cpp b/testApp/misc/testThread.cpp
index 5c37290..ce046da 100644
--- a/testApp/misc/testThread.cpp
+++ b/testApp/misc/testThread.cpp
@@ -18,11 +18,12 @@
#include
#include
+#include
#include "event.h"
#include "thread.h"
#include "executor.h"
-#include "showConstructDestruct.h"
+#include "CDRMonitor.h"
#include "timeFunction.h"
using namespace epics::pvData;
@@ -115,6 +116,7 @@ int main(int argc, char *argv[]) {
}
testBasic(fd);
testThreadContext(fd,auxFd);
- getShowConstructDestruct()->showDeleteStaticExit(fd);
+ epicsExitCallAtExits();
+ CDRMonitor::get().show(fd);
return (0);
}
diff --git a/testApp/misc/testTimer.cpp b/testApp/misc/testTimer.cpp
index 8e69e02..f9bff9d 100644
--- a/testApp/misc/testTimer.cpp
+++ b/testApp/misc/testTimer.cpp
@@ -17,11 +17,12 @@
#include
#include
+#include
#include "timeStamp.h"
#include "event.h"
#include "timer.h"
#include "thread.h"
-#include "showConstructDestruct.h"
+#include "CDRMonitor.h"
using namespace epics::pvData;
@@ -112,6 +113,7 @@ int main(int argc, char *argv[]) {
oneDelay = .0;
twoDelay = .0;
testBasic(fd,auxfd);
- getShowConstructDestruct()->showDeleteStaticExit(fd);
+ epicsExitCallAtExits();
+ CDRMonitor::get().show(fd);
return (0);
}
diff --git a/testApp/property/testProperty.cpp b/testApp/property/testProperty.cpp
index b34032c..f9abcfd 100644
--- a/testApp/property/testProperty.cpp
+++ b/testApp/property/testProperty.cpp
@@ -13,6 +13,7 @@
#include
#include
+#include
#include "requester.h"
#include "pvIntrospect.h"
@@ -29,7 +30,7 @@
#include "pvDisplay.h"
#include "pvEnumerated.h"
#include "pvTimeStamp.h"
-#include "showConstructDestruct.h"
+#include "CDRMonitor.h"
using namespace epics::pvData;
@@ -243,7 +244,8 @@ int main(int argc,char *argv[])
testDisplay(fd,auxfd);
testEnumerated(fd,auxfd);
deleteRecords(fd,auxfd);
- getShowConstructDestruct()->showDeleteStaticExit(fd);
+ epicsExitCallAtExits();
+ CDRMonitor::get().show(fd);
return(0);
}
diff --git a/testApp/pv/temp.cpp b/testApp/pv/temp.cpp
index 86541c0..e85f9fe 100644
--- a/testApp/pv/temp.cpp
+++ b/testApp/pv/temp.cpp
@@ -20,7 +20,7 @@
#include "convert.h"
#include "standardField.h"
#include "standardPVField.h"
-#include "showConstructDestruct.h"
+#include "CDRMonitor.h"
using namespace epics::pvData;
diff --git a/testApp/pv/testIntrospect.cpp b/testApp/pv/testIntrospect.cpp
index f43d884..8eced01 100644
--- a/testApp/pv/testIntrospect.cpp
+++ b/testApp/pv/testIntrospect.cpp
@@ -13,13 +13,14 @@
#include
#include
+#include
#include "requester.h"
#include "executor.h"
#include "pvIntrospect.h"
#include "pvData.h"
#include "standardField.h"
-#include "showConstructDestruct.h"
+#include "CDRMonitor.h"
using namespace epics::pvData;
@@ -147,7 +148,8 @@ int main(int argc,char *argv[])
testScalarArray(fd);
testSimpleStructure(fd);
testStructureArray(fd);
- getShowConstructDestruct()->showDeleteStaticExit(fd);
+ epicsExitCallAtExits();
+ CDRMonitor::get().show(fd);
return(0);
}
diff --git a/testApp/pv/testPVAppend.cpp b/testApp/pv/testPVAppend.cpp
index 5f70523..50e716e 100644
--- a/testApp/pv/testPVAppend.cpp
+++ b/testApp/pv/testPVAppend.cpp
@@ -13,6 +13,7 @@
#include
#include
+#include
#include "requester.h"
#include "pvIntrospect.h"
@@ -20,7 +21,7 @@
#include "convert.h"
#include "standardField.h"
#include "standardPVField.h"
-#include "showConstructDestruct.h"
+#include "CDRMonitor.h"
using namespace epics::pvData;
@@ -142,7 +143,8 @@ int main(int argc,char *argv[])
testAppendSimple(fd);
testAppendMore(fd);
testAppends(fd);
- getShowConstructDestruct()->showDeleteStaticExit(fd);
+ epicsExitCallAtExits();
+ CDRMonitor::get().show(fd);
return(0);
}
diff --git a/testApp/pv/testPVAuxInfo.cpp b/testApp/pv/testPVAuxInfo.cpp
index 2456800..f4913cc 100644
--- a/testApp/pv/testPVAuxInfo.cpp
+++ b/testApp/pv/testPVAuxInfo.cpp
@@ -13,6 +13,7 @@
#include
#include
+#include
#include "requester.h"
#include "pvIntrospect.h"
@@ -20,7 +21,7 @@
#include "convert.h"
#include "standardField.h"
#include "standardPVField.h"
-#include "showConstructDestruct.h"
+#include "CDRMonitor.h"
using namespace epics::pvData;
@@ -92,7 +93,8 @@ int main(int argc,char *argv[])
standardPVField = getStandardPVField();
convert = getConvert();
testPVAuxInfo(fd);
- getShowConstructDestruct()->showDeleteStaticExit(fd);
+ epicsExitCallAtExits();
+ CDRMonitor::get().show(fd);
return(0);
}
diff --git a/testApp/pv/testPVData.cpp b/testApp/pv/testPVData.cpp
index 744cae8..d2321a8 100644
--- a/testApp/pv/testPVData.cpp
+++ b/testApp/pv/testPVData.cpp
@@ -13,6 +13,7 @@
#include
#include
+#include
#include "requester.h"
#include "pvIntrospect.h"
@@ -20,7 +21,7 @@
#include "convert.h"
#include "standardField.h"
#include "standardPVField.h"
-#include "showConstructDestruct.h"
+#include "CDRMonitor.h"
using namespace epics::pvData;
@@ -282,7 +283,8 @@ int main(int argc,char *argv[])
testAppend(fd);
testPVScalar(fd);
testScalarArray(fd);
- getShowConstructDestruct()->showDeleteStaticExit(fd);
+ epicsExitCallAtExits();
+ CDRMonitor::get().show(fd);
return(0);
}
diff --git a/testApp/pv/testPVStructureArray.cpp b/testApp/pv/testPVStructureArray.cpp
index f27120d..94464d6 100644
--- a/testApp/pv/testPVStructureArray.cpp
+++ b/testApp/pv/testPVStructureArray.cpp
@@ -13,13 +13,14 @@
#include
#include
+#include
#include "requester.h"
#include "pvIntrospect.h"
#include "pvData.h"
#include "standardField.h"
#include "standardPVField.h"
-#include "showConstructDestruct.h"
+#include "CDRMonitor.h"
using namespace epics::pvData;
@@ -79,7 +80,8 @@ int main(int argc,char *argv[])
standardField = getStandardField();
standardPVField = getStandardPVField();
testPowerSupplyArray(fd);
- getShowConstructDestruct()->showDeleteStaticExit(fd);
+ epicsExitCallAtExits();
+ CDRMonitor::get().show(fd);
return(0);
}