update test baselines
  rename showConstructDestruct.h to CDRMonitor.h
  undercounting field
  switch tests to CDRMonitor
  switch remaining to use REFCOUNT macros
  Use epicsThreadOnce for safe lazy initialization
  replace ShowConstructDestruct with simpler CDRMonitor
  executor: remove redundant allocations
  lock: Partial implementation of Boost lock templates

Conflicts:
	pvDataApp/misc/StatusCreateFactory.cpp
	pvDataApp/misc/bitSet.cpp
This commit is contained in:
Michael Davidsaver
2011-02-02 11:16:03 -05:00
55 changed files with 491 additions and 902 deletions

View File

@@ -2906,7 +2906,7 @@ PVDataCreate.</p>
<dd>Allows messages to be sent to a requester.</dd>
<dt style="font-family: courier;">serialize.h</dt>
<dd>Support for serializing objects.</dd>
<dt style="font-family: courier;">showConstructDestruct.h</dt>
<dt style="font-family: courier;">CDRMonitor.h</dt>
<dd>Provides support monitoring memory usage for objects of a class.</dd>
<dt style="font-family: courier;">status.h</dt>
<dd>A way to pass status information to a client.</dd>

View File

@@ -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

View File

@@ -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; i<indentLevel; i++) *buffer += " ";
}
PVDATA_REFCOUNT_MONITOR_DEFINE(field);
class FieldPvt {
public :
FieldPvt(String fieldName,Type type);
@@ -33,54 +35,19 @@ public :
};
FieldPvt::FieldPvt(String fieldName,Type type)
: fieldName(fieldName),type(type),referenceCount(1) { }
static volatile int64 totalReferenceCount = 0;
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 int64 getTotalReferenceCount()
{
return totalReferenceCount;
}
static void init()
{
static Mutex mutex;
Lock xx(&mutex);
if(notInited) {
notInited = false;
ShowConstructDestruct::registerCallback(
String("field"),
getTotalConstruct,getTotalDestruct,getTotalReferenceCount,0);
}
}
: fieldName(fieldName),type(type),referenceCount(1)
{field_node.incRef();}
static Mutex refCountMutex;
Field::Field(String fieldName,Type type)
: pImpl(new FieldPvt(fieldName,type))
{
Lock xx(&globalMutex);
totalConstruct++;
PVDATA_REFCOUNT_MONITOR_CONSTRUCT(field);
}
Field::~Field() {
Lock xx(&globalMutex);
totalDestruct++;
PVDATA_REFCOUNT_MONITOR_DESTRUCT(field);
// note that compiler automatically calls destructor for fieldName
if(debugLevel==highDebug) printf("~Field %s\n",pImpl->fieldName.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<StructureConstPtr>(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() {

View File

@@ -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<String,PVScalar * >::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;

View File

@@ -8,41 +8,16 @@
#include <cstdlib>
#include <string>
#include <cstdio>
#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;
}

View File

@@ -7,15 +7,15 @@
#include <string>
#include <cstdio>
#include <stdexcept>
#include <epicsThread.h>
#include <epicsExit.h>
#include <lock.h>
#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;
}

View File

@@ -6,18 +6,18 @@
*/
#include <string>
#include <stdexcept>
#include <epicsThread.h>
#include <epicsExit.h>
#include <lock.h>
#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;
}

View File

@@ -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 <stddef.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include <stdexcept>
#include <epicsThread.h>
#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");
}
}}

View File

@@ -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 <stddef.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#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 */

View File

@@ -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"

View File

@@ -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 {

View File

@@ -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()

View File

@@ -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<ExecutorNode> ExecutorListNode;
typedef LinkedList<ExecutorNode> ExecutorList;
@@ -55,25 +29,18 @@ typedef LinkedList<ExecutorNode> 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)

View File

@@ -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()

View File

@@ -6,6 +6,7 @@
*/
#ifndef LOCK_H
#define LOCK_H
#include <stdexcept>
#include <epicsMutex.h>
#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<typename Lockable>
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<typename Lockable>
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<Mutex> 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<Mutex> Lock;
class Lock : private NoDefaultMethods {
public:
explicit Lock(Mutex *pm)
: mutexPtr(pm)
{mutexPtr->lock();}
~Lock(){mutexPtr->unlock();}
private:
Mutex *mutexPtr;
};
}}
#endif /* LOCK_H */

View File

@@ -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<MessageNode> 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() {

View File

@@ -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<number; i++) {
array[i] = new QueueElementVoid(object[i]);
}
initPvt();
Lock xx(&globalMutex);
totalQueueConstruct++;
PVDATA_REFCOUNT_MONITOR_CONSTRUCT(queue);
}
QueueVoid::~QueueVoid()
@@ -105,8 +57,7 @@ QueueVoid::~QueueVoid()
delete array[i];
}
delete[]array;
Lock xx(&globalMutex);
totalQueueDestruct++;
PVDATA_REFCOUNT_MONITOR_DESTRUCT(queue);
}
void QueueVoid::clear()

View File

@@ -1,211 +0,0 @@
/* showConstructDestruct.cpp */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <stddef.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include <stdexcept>
#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<ConstructDestructCallback> ListNode;
typedef LinkedList<ConstructDestructCallback> 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;
}
}}

View File

@@ -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 <stddef.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#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 */

View File

@@ -13,11 +13,12 @@
#include <epicsThread.h>
#include <epicsEvent.h>
#include <epicsExit.h>
#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<ThreadListElement> ThreadListNode;
typedef LinkedList<ThreadListElement> 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;

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -12,9 +12,10 @@
#include <string.h>
#include <stdio.h>
#include <bitSet.h>
#include <showConstructDestruct.h>
#include <CDRMonitor.h>
#include <epicsAssert.h>
#include <epicsExit.h>
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);
}

View File

@@ -18,11 +18,12 @@
#include <list>
#include <epicsAssert.h>
#include <epicsExit.h>
#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);
}

View File

@@ -17,12 +17,13 @@
#include <cstdio>
#include <epicsAssert.h>
#include <epicsExit.h>
#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);
}

View File

@@ -17,11 +17,12 @@
#include <cstdio>
#include <epicsAssert.h>
#include <epicsExit.h>
#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);
}

View File

@@ -13,12 +13,13 @@
#include <epicsAssert.h>
#include <epicsExit.h>
#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);

View File

@@ -18,11 +18,12 @@
#include <list>
#include <epicsAssert.h>
#include <epicsExit.h>
#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);
}

View File

@@ -17,11 +17,12 @@
#include <cstdio>
#include <epicsAssert.h>
#include <epicsExit.h>
#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);
}

View File

@@ -13,6 +13,7 @@
#include <cstdio>
#include <epicsAssert.h>
#include <epicsExit.h>
#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);
}

View File

@@ -20,7 +20,7 @@
#include "convert.h"
#include "standardField.h"
#include "standardPVField.h"
#include "showConstructDestruct.h"
#include "CDRMonitor.h"
using namespace epics::pvData;

View File

@@ -13,13 +13,14 @@
#include <cstdio>
#include <epicsAssert.h>
#include <epicsExit.h>
#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);
}

View File

@@ -13,6 +13,7 @@
#include <cstdio>
#include <epicsAssert.h>
#include <epicsExit.h>
#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);
}

View File

@@ -13,6 +13,7 @@
#include <cstdio>
#include <epicsAssert.h>
#include <epicsExit.h>
#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);
}

View File

@@ -13,6 +13,7 @@
#include <cstdio>
#include <epicsAssert.h>
#include <epicsExit.h>
#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);
}

View File

@@ -13,13 +13,14 @@
#include <cstdio>
#include <epicsAssert.h>
#include <epicsExit.h>
#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);
}