Merge
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:
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
90
pvDataApp/misc/CDRMonitor.cpp
Normal file
90
pvDataApp/misc/CDRMonitor.cpp
Normal 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");
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
94
pvDataApp/misc/CDRMonitor.h
Normal file
94
pvDataApp/misc/CDRMonitor.h
Normal 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 */
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include "convert.h"
|
||||
#include "standardField.h"
|
||||
#include "standardPVField.h"
|
||||
#include "showConstructDestruct.h"
|
||||
#include "CDRMonitor.h"
|
||||
|
||||
using namespace epics::pvData;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user