/** * Copyright - See the COPYRIGHT that is included with this distribution. * pvxs is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. */ #include #include #include #include #include #include #include #include #define PVXS_ENABLE_EXPERT_API #include #include #include #if EPICS_VERSION_INT < VERSION_INT(7,0,1,0) #define epicsMonotonicGet epicsTime::getCurrent #endif using namespace pvxs; DEFINE_LOGGER(app, "eatspam"); namespace { template bool parse_as(T& out, const char *s) { std::istringstream strm(s); return (strm>>out).fail() || !strm.eof(); } struct Counter { std::string name; std::vector scratch; std::shared_ptr sub; uint32_t prev; size_t nwake = 0; size_t nupdate = 0; size_t nskip = 0; bool first = true; }; } // namespace int main(int argc, char* argv[]) { logger_level_set(app.name, Level::Warn); logger_config_env(); size_t queueSize = 0; int pipeline = 0; // tri-bool int opt; { while((opt = getopt(argc, argv, "hpPQ:")) != -1) { switch (opt) { case 'h': std::cerr<<"Usage: "<] pvname..."<(queueSize, optarg)) { std::cerr<<"Invalid queueSize: "<>()); if(!aval.empty()) { sval = aval[0]; gotit = true; } else { continue; } } else if(val.type().code <= TypeCode::Float64 && !val.type().isarray()) { sval = val.as(); gotit = true; } if(gotit) { if(!ctr.first) { auto diff = sval-ctr.prev; if(diff != 1) { log_info_printf(app, "%s skip %u -> %u, %u\n", ctr.name.c_str(), ctr.prev, sval, diff); ctr.nskip++; } } else { ctr.first = false; log_info_printf(app, "%s initial %u\n", ctr.name.c_str(), sval); } ctr.nupdate++; ctr.prev = sval; } else { std::cerr<cancel(); } } ctr.scratch.clear(); } // cancel subscriptions for(auto& ctr : ctrs) { ctr.sub->cancel(); } // final stats and cleanup for(auto& ctr : ctrs) { client::SubscriptionStat stats; ctr.sub->stats(stats); std::cout<<' '<