#include "SimpleLogFile.h" #include "ThreadMonitor.h" ///////////////////////////////////////////////////////////////////// // ThreadMonitor::LongestTime::Helper ///////////////////////////////////////////////////////////////////// std::string ThreadMonitor::LongestTime::Helper::getInfoForThreadMonitor() { if (_longest.empty()) return ""; TclList result; for (std::map< std::string, Info >::const_iterator it = _longest.begin(); it != _longest.end(); it++) { TclList item; item<first // Name <second.longest <<(it->second.total / it->second.count) // Average <second.count; result< info.longest) info.longest = time; info.total += time; info.count++; } ///////////////////////////////////////////////////////////////////// // ThreadMonitor::LongestTime ///////////////////////////////////////////////////////////////////// ThreadMonitor::LongestTime::LongestTime(std::string const &name) : _name(name), _start(true) { } ThreadMonitor::LongestTime::~LongestTime() { const TimeVal stop(true); const TimeVal::Microseconds elapsed = stop.asMicroseconds() - _start.asMicroseconds(); Helper::find().report(_name, elapsed); } ///////////////////////////////////////////////////////////////////// // ThreadMonitor ///////////////////////////////////////////////////////////////////// // This and related functions lets you get the CPU usage for a thread. // http://linux.die.net/man/3/pthread_getcpuclockid That would be nice to // report. Currently we only report clock time. I had looked at CPU time in // the past, but I was only aware of the times system call, and that gives you // CPU time for the entire process. ThreadMonitor::ThreadMonitor() : _lastOutput(TimeVal(true).asMicroseconds()), _stateStart(_lastOutput), _currentState("working") { } static __thread ThreadMonitor *monitor = NULL; ThreadMonitor &ThreadMonitor::find() { if (!monitor) { monitor = new ThreadMonitor; } return *monitor; } void ThreadMonitor::setState(std::string const &state) { TimeVal::Microseconds now = TimeVal(true).asMicroseconds(); bool needToDump = ((now - _lastOutput) > 300000000LL); if (needToDump || (state != _currentState)) { _timeInState[_currentState] += (now - _stateStart); _stateStart = now; _currentState = state; } if (needToDump) { TimeVal::Microseconds totalTime = now - _lastOutput; TclList message; message<<"ThreadMonitor.C" <<_name <<"total_time" < > SS; SS sortedStates; for (std::map< std::string, TimeVal::Microseconds >::const_iterator it = _timeInState.begin(); it != _timeInState.end(); it++) sortedStates.insert(std::make_pair(it->second, it->first)); TclList states; for (SS::reverse_iterator it = sortedStates.rbegin(); it != sortedStates.rend(); it++) { states<second <<(dtoa(it->first * 100.0 / totalTime, 4) + "%"); } message<<"states" <::iterator it = _counters.begin(); it != _counters.end(); it++) { counters<first <second; } message<<"counters" <::iterator it = _extras.begin(); it != _extras.end(); it++) { std::string forLog = (*it)->getInfoForThreadMonitor(); if (!forLog.empty()) message<