ioc: add instance counter tools to IOC shell

This commit is contained in:
Michael Davidsaver
2023-05-09 22:24:19 -07:00
parent aef69c9f25
commit 044b0db7af
+80
View File
@@ -128,6 +128,79 @@ void pvxsi() {
}
}
namespace {
void pvxrefshow() {
auto refs(instanceSnapshot());
for(auto& pair : refs) {
if(pair.second>0u)
printf("%s\t= %zu\n", pair.first.c_str(), pair.second);
}
}
struct RefTrack {
epicsMutex lock;
std::map<std::string, size_t> refs;
} *refTrack;
epicsThreadOnceId refSavedOnce = EPICS_THREAD_ONCE_INIT;
void refSavedInit(void *) {
refTrack = new RefTrack();
}
void pvxrefsave() {
epicsThreadOnce(&refSavedOnce, &refSavedInit, nullptr);
epicsGuard<epicsMutex> G(refTrack->lock);
refTrack->refs = instanceSnapshot();
}
void pvxrefdiff() {
auto cur(instanceSnapshot());
std::map<std::string, int64_t> diff;
epicsThreadOnce(&refSavedOnce, &refSavedInit, nullptr);
{
epicsGuard<epicsMutex> G(refTrack->lock);
auto& prev(refTrack->refs);
// Both std::map will iterate in the same order. So co-iterate.
// Some keys may appear in one but not the other.
auto itC = cur.begin();
auto itP = prev.begin();
while(true) {
bool haveC = itC!=cur.end();
bool haveP = itP!=prev.end();
int ord = haveC && haveP ? itC->first.compare(itP->first) : 0;
if(haveC && haveP && ord==0) {
diff[itC->first] = int64_t(itC->second) - int64_t(itP->second);
++itC;
++itP;
} else if(haveP && (!haveC || ord > 0)) { // !cur || cur > prev
diff[itP->first] = -int64_t(itP->second);
++itP;
} else if(haveC && (!haveP || ord < 0)) { // !prev || cur < prev
diff[itC->first] = int64_t(itC->second);
++itC;
} else {
break;
}
}
}
for(auto& pair : diff) {
if(pair.second!=0u)
printf("%s\t= %lld\n", pair.first.c_str(), (long long)pair.second);
}
}
} // namespace
/**
* Initialise and control state of pvxs ioc server instance in response to iocInitHook events.
* Installed on the initHookState hook this function will respond to the following events:
@@ -219,6 +292,13 @@ void pvxsBaseRegistrar() {
.implementation<&pvxsr>();
IOCShCommand<>("pvxsi", "Show detailed server information\n").implementation<&pvxsi>();
IOCShCommand<>("pvxrefshow",
"Show instance counts for various internal data structures.\n").implementation<&pvxrefshow>();
IOCShCommand<>("pvxrefsave",
"Save the current set of instance counters for reference by later pvxrefdiff.\n").implementation<&pvxrefsave>();
IOCShCommand<>("pvxrefdiff",
"Show different of current instance counts with those when pvxrefsave was called.\n").implementation<&pvxrefdiff>();
// Initialise the PVXS Server
initialisePvxsServer();