redo INST_COUNTER
Allow for use by pvxsIoc
This commit is contained in:
@@ -27,6 +27,11 @@ typedef epicsGuardRelease<epicsMutex> UnGuard;
|
||||
namespace pvxs {
|
||||
namespace client {
|
||||
|
||||
DEFINE_INST_COUNTER(Connection);
|
||||
DEFINE_INST_COUNTER(Channel);
|
||||
DEFINE_INST_COUNTER2(ContextImpl, ClientContextImpl);
|
||||
DEFINE_INST_COUNTER2(Context::Pvt, ClientPvt);
|
||||
|
||||
namespace {
|
||||
/* "normal" tick interval for the search bucket ring, and "fast" interval
|
||||
* used for one revolution after a successful poke().
|
||||
|
||||
@@ -383,6 +383,7 @@ struct GPROp : public OperationBase
|
||||
}
|
||||
}
|
||||
};
|
||||
DEFINE_INST_COUNTER(GPROp);
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
@@ -108,6 +108,7 @@ struct InfoOp : public OperationBase
|
||||
}
|
||||
}
|
||||
};
|
||||
DEFINE_INST_COUNTER(InfoOp);
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
@@ -463,6 +463,7 @@ struct SubscriptionImpl final : public OperationBase, public Subscription
|
||||
}
|
||||
}
|
||||
};
|
||||
DEFINE_INST_COUNTER(SubscriptionImpl);
|
||||
|
||||
void Connection::handle_MONITOR()
|
||||
{
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
|
||||
namespace pvxs {
|
||||
|
||||
DEFINE_INST_COUNTER(StructTop);
|
||||
|
||||
NoField::NoField()
|
||||
:std::runtime_error ("No such field")
|
||||
{}
|
||||
|
||||
+11
-1
@@ -107,6 +107,13 @@ struct ThreadEvent
|
||||
inline epicsEvent* operator->() { return get(); }
|
||||
};
|
||||
|
||||
namespace {
|
||||
struct evbaseRunning {
|
||||
INST_COUNTER(evbaseRunning);
|
||||
};
|
||||
DEFINE_INST_COUNTER(evbaseRunning);
|
||||
}
|
||||
|
||||
struct evbase::Pvt final : public epicsThreadRunable
|
||||
{
|
||||
SockAttach attach;
|
||||
@@ -165,7 +172,7 @@ struct evbase::Pvt final : public epicsThreadRunable
|
||||
|
||||
virtual void run() override final
|
||||
{
|
||||
INST_COUNTER(evbaseRunning);
|
||||
evbaseRunning track;
|
||||
try {
|
||||
evconfig conf(__FILE__, __LINE__, event_config_new());
|
||||
#ifdef __rtems__
|
||||
@@ -253,6 +260,7 @@ struct evbase::Pvt final : public epicsThreadRunable
|
||||
}
|
||||
|
||||
};
|
||||
DEFINE_INST_COUNTER2(evbase::Pvt, evbase);
|
||||
|
||||
evbase::evbase(const std::string &name, unsigned prio)
|
||||
{
|
||||
@@ -1024,6 +1032,8 @@ void to_evbuf(evbuffer *buf, const Header& H, bool be)
|
||||
|
||||
} // namespace impl
|
||||
|
||||
std::atomic<size_t> Timer::Pvt::cnt_Timer {0u};
|
||||
|
||||
Timer::~Timer() {}
|
||||
|
||||
bool Timer::cancel()
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
/* Names of internal object instance counters.
|
||||
* Included in three places in utilpvt.h and util.cpp
|
||||
*/
|
||||
#ifndef CASE
|
||||
// for IDEs
|
||||
# define CASE(NAME)
|
||||
# error Must define CASE
|
||||
#endif
|
||||
CASE(StructTop);
|
||||
|
||||
CASE(UDPListener);
|
||||
CASE(evbase);
|
||||
CASE(evbaseRunning);
|
||||
CASE(Timer);
|
||||
|
||||
CASE(GPROp);
|
||||
CASE(Connection);
|
||||
CASE(Channel);
|
||||
CASE(ClientPvt);
|
||||
CASE(ClientContextImpl);
|
||||
CASE(InfoOp);
|
||||
CASE(SubScriptionImpl);
|
||||
|
||||
CASE(ServerChannelControl);
|
||||
CASE(ServerChan);
|
||||
CASE(ServerConn);
|
||||
CASE(ServerSource);
|
||||
CASE(ServerPvt);
|
||||
CASE(ServerIntrospect);
|
||||
CASE(ServerIntrospectControl);
|
||||
CASE(ServerGPR);
|
||||
CASE(ServerGPRConnect);
|
||||
CASE(ServerGPRExec);
|
||||
CASE(MonitorOp);
|
||||
CASE(ServerMonitorControl);
|
||||
CASE(ServerMonitorSetup);
|
||||
CASE(SharedPVImpl);
|
||||
CASE(SubscriptionImpl);
|
||||
@@ -20,7 +20,16 @@
|
||||
static constexpr size_t tcp_tx_limit_mult = 2u;
|
||||
|
||||
namespace pvxs {
|
||||
namespace impl {
|
||||
DEFINE_INST_COUNTER(ServerChannelControl);
|
||||
DEFINE_INST_COUNTER(ServerChan);
|
||||
DEFINE_INST_COUNTER(ServerConn);
|
||||
DEFINE_INST_COUNTER(ServerSource);
|
||||
}
|
||||
namespace server {
|
||||
|
||||
DEFINE_INST_COUNTER2(Server::Pvt, ServerPvt);
|
||||
|
||||
std::set<std::string> ClientCredentials::roles() const
|
||||
{
|
||||
std::set<std::string> ret;
|
||||
|
||||
@@ -152,6 +152,7 @@ struct ServerGPR : public ServerOp
|
||||
|
||||
INST_COUNTER(ServerGPR);
|
||||
};
|
||||
DEFINE_INST_COUNTER(ServerGPR);
|
||||
|
||||
|
||||
struct ServerGPRConnect : public server::ConnectOp
|
||||
@@ -246,6 +247,7 @@ struct ServerGPRConnect : public server::ConnectOp
|
||||
|
||||
INST_COUNTER(ServerGPRConnect);
|
||||
};
|
||||
DEFINE_INST_COUNTER(ServerGPRConnect);
|
||||
|
||||
struct ServerGPRExec : public server::ExecOp
|
||||
{
|
||||
@@ -317,6 +319,7 @@ struct ServerGPRExec : public server::ExecOp
|
||||
|
||||
INST_COUNTER(ServerGPRExec);
|
||||
};
|
||||
DEFINE_INST_COUNTER(ServerGPRExec);
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@ struct ServerIntrospect : public ServerOp
|
||||
|
||||
INST_COUNTER(ServerIntrospect);
|
||||
};
|
||||
DEFINE_INST_COUNTER(ServerIntrospect);
|
||||
|
||||
struct ServerIntrospectControl : public server::ConnectOp
|
||||
{
|
||||
@@ -117,6 +118,7 @@ struct ServerIntrospectControl : public server::ConnectOp
|
||||
|
||||
INST_COUNTER(ServerIntrospectControl);
|
||||
};
|
||||
DEFINE_INST_COUNTER(ServerIntrospectControl);
|
||||
} // namespace
|
||||
|
||||
void ServerConn::handle_GET_FIELD()
|
||||
|
||||
@@ -200,6 +200,7 @@ struct MonitorOp : public ServerOp,
|
||||
strm<<"MONITOR\n";
|
||||
}
|
||||
};
|
||||
DEFINE_INST_COUNTER(MonitorOp);
|
||||
|
||||
struct ServerMonitorSetup;
|
||||
|
||||
@@ -326,6 +327,7 @@ struct ServerMonitorControl : public server::MonitorControlOp
|
||||
|
||||
INST_COUNTER(ServerMonitorControl);
|
||||
};
|
||||
DEFINE_INST_COUNTER(ServerMonitorControl);
|
||||
|
||||
struct ServerMonitorSetup : public server::MonitorSetupOp
|
||||
{
|
||||
@@ -401,6 +403,7 @@ struct ServerMonitorSetup : public server::MonitorSetupOp
|
||||
|
||||
INST_COUNTER(ServerMonitorSetup);
|
||||
};
|
||||
DEFINE_INST_COUNTER(ServerMonitorSetup);
|
||||
|
||||
|
||||
ServerMonitorControl::ServerMonitorControl(ServerMonitorSetup* setup,
|
||||
|
||||
@@ -101,6 +101,7 @@ struct SharedPV::Impl : public std::enable_shared_from_this<Impl>
|
||||
}
|
||||
}
|
||||
};
|
||||
DEFINE_INST_COUNTER2(SharedPV::Impl, SharedPVImpl);
|
||||
|
||||
SharedPV SharedPV::buildMailbox()
|
||||
{
|
||||
|
||||
@@ -31,6 +31,8 @@ namespace pvxs {namespace impl {
|
||||
DEFINE_LOGGER(logio, "pvxs.udp.io");
|
||||
DEFINE_LOGGER(logsetup, "pvxs.udp.setup");
|
||||
|
||||
DEFINE_INST_COUNTER(UDPListener);
|
||||
|
||||
struct UDPCollector final : public UDPManager::Search,
|
||||
public std::enable_shared_from_this<UDPCollector>
|
||||
{
|
||||
|
||||
+36
-6
@@ -78,18 +78,48 @@ unsigned long version_abi_int()
|
||||
return PVXS_ABI_VERSION;
|
||||
}
|
||||
|
||||
namespace {
|
||||
epicsThreadOnceId ICountOnce = EPICS_THREAD_ONCE_INIT;
|
||||
struct ICountGbl_t {
|
||||
RWLock lock;
|
||||
std::map<std::string, std::atomic<size_t>*> counters;
|
||||
} *ICountGbl;
|
||||
|
||||
#define CASE(KLASS) std::atomic<size_t> cnt_ ## KLASS{}
|
||||
#include "instcounters.h"
|
||||
#undef CASE
|
||||
void ICountInit(void*)
|
||||
{
|
||||
ICountGbl = new ICountGbl_t;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void registerICount(const char *name, std::atomic<size_t>& Cnt)
|
||||
{
|
||||
epicsThreadOnce(&ICountOnce, &ICountInit, nullptr);
|
||||
auto& gbl = *ICountGbl;
|
||||
try {
|
||||
auto L(gbl.lock.lockWriter());
|
||||
if(!gbl.counters.emplace(name, &Cnt).second) { // duplicate name
|
||||
return;
|
||||
}
|
||||
} catch(std::exception& e) { // bad_alloc
|
||||
return;
|
||||
}
|
||||
Cnt++; // bias by +1 to indicate initialization
|
||||
}
|
||||
|
||||
std::map<std::string, size_t> instanceSnapshot()
|
||||
{
|
||||
std::map<std::string, size_t> ret;
|
||||
|
||||
#define CASE(KLASS) ret[#KLASS] = cnt_ ## KLASS .load(std::memory_order_relaxed)
|
||||
#include "instcounters.h"
|
||||
#undef CASE
|
||||
{
|
||||
epicsThreadOnce(&ICountOnce, &ICountInit, nullptr);
|
||||
auto& gbl = *ICountGbl;
|
||||
auto L(gbl.lock.lockReader());
|
||||
for(auto& pair : gbl.counters) {
|
||||
// remove -1 bias for initialized counter
|
||||
ret.emplace(pair.first, pair.second->load(std::memory_order_relaxed)-1u);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
+19
-10
@@ -267,18 +267,27 @@ struct Restore {
|
||||
}
|
||||
};
|
||||
|
||||
template<std::atomic<size_t>* Cnt>
|
||||
struct InstCounter
|
||||
{
|
||||
InstCounter() {(*Cnt).fetch_add(1, std::memory_order_relaxed);}
|
||||
~InstCounter() {(*Cnt).fetch_sub(1, std::memory_order_relaxed);}
|
||||
PVXS_API
|
||||
void registerICount(const char* name, std::atomic<size_t>& Cnt);
|
||||
|
||||
// Name and Cnt must have global lifetime
|
||||
template<std::atomic<size_t>& Cnt>
|
||||
struct InstCounter {
|
||||
explicit InstCounter(const char* Name) {
|
||||
if(0u==Cnt.fetch_add(1u, std::memory_order_relaxed)) { // first
|
||||
registerICount(Name, Cnt);
|
||||
}
|
||||
}
|
||||
~InstCounter() {
|
||||
Cnt.fetch_sub(1u, std::memory_order_relaxed);
|
||||
}
|
||||
};
|
||||
|
||||
#define INST_COUNTER(KLASS) InstCounter<&cnt_ ## KLASS> instances
|
||||
|
||||
#define CASE(KLASS) PVXS_API extern std::atomic<size_t> cnt_ ## KLASS
|
||||
#include "instcounters.h"
|
||||
#undef CASE
|
||||
#define INST_COUNTER(KLASS) \
|
||||
static std::atomic<size_t> cnt_ ## KLASS; \
|
||||
InstCounter<cnt_ ## KLASS> instances{#KLASS}
|
||||
#define DEFINE_INST_COUNTER2(KLASS, NAME) std::atomic<size_t> KLASS::cnt_ ## NAME {0u}
|
||||
#define DEFINE_INST_COUNTER(KLASS) DEFINE_INST_COUNTER2(KLASS, KLASS)
|
||||
|
||||
} // namespace pvxs
|
||||
|
||||
|
||||
Reference in New Issue
Block a user