CDRMonitor: lazy node creation
This commit is contained in:
@@ -36,7 +36,7 @@ public :
|
||||
|
||||
FieldPvt::FieldPvt(String fieldName,Type type)
|
||||
: fieldName(fieldName),type(type),referenceCount(1)
|
||||
{field_node.incRef();}
|
||||
{PVDATA_REFCOUNT_MONITOR_INCREF(field);}
|
||||
|
||||
static Mutex refCountMutex;
|
||||
|
||||
@@ -69,7 +69,7 @@ void Field::renameField(String newName)
|
||||
}
|
||||
|
||||
void Field::incReferenceCount() const {
|
||||
field_node.incRef();
|
||||
PVDATA_REFCOUNT_MONITOR_INCREF(field);
|
||||
Lock xx(&refCountMutex);
|
||||
pImpl->referenceCount++;
|
||||
if(pImpl->type!=structure) return;
|
||||
@@ -82,7 +82,7 @@ void Field::incReferenceCount() const {
|
||||
}
|
||||
|
||||
void Field::decReferenceCount() const {
|
||||
field_node.decRef();
|
||||
PVDATA_REFCOUNT_MONITOR_DECREF(field);
|
||||
Lock xx(&refCountMutex);
|
||||
if(pImpl->referenceCount<=0) {
|
||||
String message("logicError field ");
|
||||
|
||||
@@ -86,5 +86,11 @@ CDRNode::show(FILE *fd)
|
||||
fprintf(fd,"\n");
|
||||
}
|
||||
|
||||
void
|
||||
onceNode(void* raw)
|
||||
{
|
||||
CDRNodeInstance* inst=static_cast<CDRNodeInstance*>(raw);
|
||||
inst->node=new CDRNode(inst->name);
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <epicsThread.h>
|
||||
#include "noDefaultMethods.h"
|
||||
#include "lock.h"
|
||||
#include "pvType.h"
|
||||
@@ -83,11 +84,37 @@ private:
|
||||
CDRNode * const nextNode;
|
||||
};
|
||||
|
||||
#define PVDATA_REFCOUNT_MONITOR_DEFINE(NAME) static CDRNode NAME ## _node(#NAME)
|
||||
struct CDRNodeInstance
|
||||
{
|
||||
CDRNode *node;
|
||||
epicsThreadOnceId once;
|
||||
const char* const name;
|
||||
};
|
||||
|
||||
#define PVDATA_REFCOUNT_MONITOR_DESTRUCT(NAME) NAME ## _node.destruct()
|
||||
void onceNode(void* raw);
|
||||
|
||||
#define PVDATA_REFCOUNT_MONITOR_CONSTRUCT(NAME) NAME ## _node.construct()
|
||||
static inline
|
||||
CDRNode*
|
||||
getNode(CDRNodeInstance *inst)
|
||||
{
|
||||
epicsThreadOnce(&inst->once,&onceNode,
|
||||
static_cast<void*>(inst));
|
||||
return inst->node;
|
||||
}
|
||||
|
||||
#define PVDATA_REFCOUNT_MONITOR_DEFINE(NAME) \
|
||||
static CDRNodeInstance NAME ## _node={0,EPICS_THREAD_ONCE_INIT,#NAME}
|
||||
|
||||
#define PVDATA_REFCOUNT_MONITOR_DESTRUCT(NAME) \
|
||||
getNode(&NAME ## _node)->destruct()
|
||||
|
||||
#define PVDATA_REFCOUNT_MONITOR_CONSTRUCT(NAME) \
|
||||
getNode(&NAME ## _node)->construct()
|
||||
|
||||
#define PVDATA_REFCOUNT_MONITOR_INCREF(NAME) \
|
||||
getNode(&NAME ## _node)->incRef()
|
||||
#define PVDATA_REFCOUNT_MONITOR_DECREF(NAME) \
|
||||
getNode(&NAME ## _node)->decRef()
|
||||
|
||||
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user