21 #define epicsExportSharedSymbols 33 typedef std::map<std::string, const size_t*> counters_t;
37 void refgbl_init(
void *)
40 refgbl =
new refgbl_t;
41 }
catch(std::exception& e) {
42 std::cerr<<
"Failed to initialize global ref. counter registry :"<<e.what()<<
"\n";
52 throw std::runtime_error(
"Failed to initialize global ref. counter registry");
62 Guard G(refgbl->lock);
63 refgbl->counters[name] = counter;
69 Guard G(refgbl->lock);
70 refgbl_t::counters_t::iterator it(refgbl->counters.find(name));
71 if(it!=refgbl->counters.end() && it->second==counter)
72 refgbl->counters.erase(it);
78 Guard G(refgbl->lock);
79 refgbl_t::counters_t::iterator it(refgbl->counters.find(name));
80 if(it==refgbl->counters.end())
85 const RefSnapshot::Count&
86 RefSnapshot::operator[](
const std::string& name)
const 88 static const Count zero;
90 cnt_map_t::const_iterator it(counts.find(name));
91 return it==counts.end() ? zero : it->second;
94 void RefSnapshot::update()
96 refgbl_t::counters_t counters;
99 Guard G(refgbl->lock);
100 counters = refgbl->counters;
105 for(refgbl_t::counters_t::const_iterator it=counters.begin(),
111 counts[it->first] = Count(cnt, 0);
115 RefSnapshot RefSnapshot::operator-(
const RefSnapshot& rhs)
const 119 RefSnapshot::cnt_map_t::const_iterator lit = counts.begin(),
121 rit = rhs.counts.begin(),
122 rend= rhs.counts.end();
124 while(lit!=lend || rit!=rend)
126 if(lit==lend || (rit!=rend && lit->first > rit->first)) {
127 ret.counts[rit->first] = RefSnapshot::Count(0, -
long(rit->second.current));
130 }
else if(rit==rend || lit->first < rit->first) {
131 ret.counts[lit->first] = RefSnapshot::Count(lit->second.current,
long(lit->second.current));
135 ret.counts[lit->first] = RefSnapshot::Count(lit->second.current,
136 long(lit->second.current) -
long(rit->second.current));
145 std::ostream&
operator<<(std::ostream& strm,
const RefSnapshot& snap)
147 for(RefSnapshot::const_iterator it = snap.begin(), end = snap.end(); it!=end; ++it)
149 if(it->second.delta==0)
continue;
150 strm<<it->first<<
":\t"<<it->second.current<<
" (delta "<<it->second.delta<<
")\n";
164 Impl(RefMonitor* owner) :owner(*owner), done(
false), period(10.0) {}
171 RefSnapshot current, P;
178 owner.show(current-P);
191 RefMonitor::RefMonitor()
192 :impl(
new Impl(
this))
194 RefMonitor::~RefMonitor()
200 void RefMonitor::start(
double period)
203 if(impl->worker.get())
return;
206 impl->period = period;
211 impl->worker->start();
214 void RefMonitor::stop()
216 epics::auto_ptr<epicsThread> W;
219 if(!impl->worker.get())
return;
220 epics::swap(W, impl->worker);
224 impl->wakeup.signal();
230 bool RefMonitor::running()
const 233 return !!impl->worker.get();
236 void RefMonitor::current()
238 RefSnapshot current, P;
246 show(current-P,
true);
249 void RefMonitor::show(
const RefSnapshot &snap,
bool complete)
252 epicsTime::getCurrent().strftime(buf,
sizeof(buf),
"%a %b %d %Y %H:%M:%S.%f");
253 buf[
sizeof(buf)-1] =
'\0';
254 std::cerr<<buf<<
" : References\n";
256 for(RefSnapshot::const_iterator it = snap.begin(), end = snap.end(); it!=end; ++it)
259 if(it->second.delta==0 && (!complete || it->second.current==0))
continue;
260 std::cerr<<it->first<<
":\t"<<it->second.current<<
" (delta "<<it->second.delta<<
")\n";
270 epics::RefSnapshot snap;
272 std::ostringstream strm;
274 const char *
str = strm.str().c_str();
275 char *ret = (
char*)malloc(strlen(str)+1);
279 }
catch(std::exception& e){
size_t readRefCounter(const char *name)
epicsGuard< epicsMutex > Guard
TODO only here because of the Lockable.
LIBCOM_API unsigned int epicsStdCall epicsThreadGetStackSize(epicsThreadStackSizeClass size)
void unregisterRefCounter(const char *name, const size_t *counter)
#define EPICS_THREAD_ONCE_INIT
epicsGuardRelease< epicsMutex > UnGuard
APIs for the epicsMutex mutual exclusion semaphore.
LIBCOM_API void epicsStdCall epicsThreadOnce(epicsThreadOnceId *id, EPICSTHREADFUNC, void *arg)
std::ostream & operator<<(std::ostream &strm, const RefSnapshot &snap)
epics::auto_ptr< epicsThread > worker
void registerRefCounter(const char *name, const size_t *counter)
char * epicsStrDup(const char *s)
APIs for the epicsEvent binary semaphore.
char * epicsRefSnapshotCurrent()
EPICS time-stamps (epicsTimeStamp), epicsTime C++ class and C functions for handling wall-clock times...
C++ and C descriptions for a thread.
#define epicsThreadPriorityMin