24 #include <utils/time/tracker.h> 25 #include <core/exceptions/software.h> 26 #include <core/exceptions/system.h> 63 const unsigned int TimeTracker::DEFAULT_CLASS = 0;
68 TimeTracker::TimeTracker(
bool add_default_class)
73 if ( add_default_class ) {
74 __class_times.push_back(vector<struct timeval *>());
75 __class_names.push_back(
"Default");
84 TimeTracker::TimeTracker(
const char *filename,
bool add_default_class)
88 if ( add_default_class ) {
89 __class_times.push_back(vector<struct timeval *>());
90 __class_names.push_back(
"Default");
92 __timelog = fopen(filename,
"w");
100 TimeTracker::~TimeTracker()
106 __class_times.clear();
107 __class_names.clear();
116 TimeTracker::reset(std::string comment)
118 __tracker_comment = comment;
119 for (vector<vector<struct timeval *> >::iterator i = __class_times.begin(); i != __class_times.end(); ++i) {
120 for (vector<struct timeval *>::iterator j = i->begin(); j != i->end(); ++j) {
127 gettimeofday(&start_time, NULL);
128 gettimeofday(&last_time, NULL);
138 TimeTracker::ping(std::string comment)
140 timeval *t = (timeval *)malloc(
sizeof(timeval));
141 gettimeofday(t, NULL);
142 __times.push_back(t);
143 if (!comment.empty()) {
144 __comments[ __times.size() - 1 ] = comment;
156 TimeTracker::add_class(std::string name)
159 throw Exception(
"TimeTracker::add_class(): Class name may not be empty");
161 __class_times.push_back(vector<struct timeval *>());
162 __class_names.push_back(name);
163 return __class_times.size() - 1;
174 TimeTracker::remove_class(
unsigned int cls)
176 if ( cls < __class_names.size() ) {
177 __class_names[cls] =
"";
179 if ( __class_times.size() == 0 ) {
180 throw Exception(
"No classes have been added, cannot delete class %u", cls);
194 TimeTracker::ping(
unsigned int cls)
196 timeval *t = (timeval *)malloc(
sizeof(timeval));
197 gettimeofday(t, NULL);
199 long sec = t->tv_sec - last_time.tv_sec;
200 long usec = t->tv_usec - last_time.tv_usec;
205 last_time.tv_sec = t->tv_sec;
206 last_time.tv_usec = t->tv_usec;
211 if (cls < __class_times.size()) {
212 __class_times[cls].push_back(t);
214 if ( __class_times.size() == 0 ) {
215 throw Exception(
"No classes have been added, cannot track times");
228 TimeTracker::ping_start(
unsigned int cls)
230 if (cls >= __class_times.size())
return;
232 timeval *t = (timeval *)malloc(
sizeof(timeval));
233 gettimeofday(t, NULL);
235 if (cls < __class_times.size()) {
236 __class_times[cls].push_back(t);
238 if ( __class_times.size() == 0 ) {
239 throw Exception(
"No classes have been added, cannot track times");
254 TimeTracker::ping_end(
unsigned int cls)
256 if (cls >= __class_times.size())
return;
259 gettimeofday(&t2, NULL);
261 timeval *t1 = __class_times[cls].back();
263 long sec = t2.tv_sec - t1->tv_sec;
264 long usec = t2.tv_usec - t1->tv_usec;
282 TimeTracker::ping_abort(
unsigned int cls)
284 if (cls >= __class_times.size())
return;
286 free(__class_times[cls].back());
287 __class_times[cls].pop_back();
292 TimeTracker::average_and_deviation(vector<struct timeval *> &values,
293 double &average_sec,
double &average_ms,
294 double &deviation_sec,
double &deviation_ms)
296 vector<struct timeval * >::iterator tit;
298 average_sec = average_ms = deviation_sec = deviation_ms = 0.f;
300 for (tit = values.begin(); tit != values.end(); ++tit) {
301 average_sec += float((*tit)->tv_sec);
302 average_sec += (*tit)->tv_usec / 1000000.f;
304 average_sec /= values.size();
306 for (tit = values.begin(); tit != values.end(); ++tit) {
307 deviation_sec += fabs((*tit)->tv_sec + ((*tit)->tv_usec / 1000000.f) - average_sec);
309 deviation_sec /= values.size();
311 average_ms = average_sec * 1000.f;
312 deviation_ms = deviation_sec * 1000.f;
317 TimeTracker::print_to_stdout()
320 if ( ! __times.empty()) {
323 long diff_sec_start = 0;
324 long diff_usec_start = 0;
325 long diff_sec_last = 0;
326 long diff_usec_last = 0;
327 float diff_msec_start = 0.0;
328 float diff_msec_last = 0.0;
329 time_t last_sec = start_time.tv_sec;
330 suseconds_t last_usec = start_time.tv_usec;
331 char time_string[26];
333 ctime_r(&(start_time.tv_sec), time_string);
334 for (j = 26; j > 0; --j) {
335 if (time_string[j] ==
'\n') {
341 cout << endl <<
"TimeTracker stats - individual times";
342 if (__tracker_comment.empty()) {
343 cout <<
" (" << __tracker_comment <<
")";
346 <<
"==================================================================" << endl
347 <<
"Initialized: " << time_string <<
" (" << start_time.tv_sec <<
")" << endl << endl;
349 for (__time_it = __times.begin(); __time_it != __times.end(); ++__time_it) {
351 sprintf(tmp,
"%3u.", i + 1);
353 if (__comments.count(i) > 0) {
354 cout <<
" (" << __comments[i] <<
")";
358 diff_sec_start = (*__time_it)->tv_sec - start_time.tv_sec;
359 diff_usec_start = (*__time_it)->tv_usec - start_time.tv_usec;
360 if (diff_usec_start < 0) {
362 diff_usec_start = 1000000 + diff_usec_start;
364 diff_msec_start = diff_usec_start / 1000.f;
366 diff_sec_last = (*__time_it)->tv_sec - last_sec;
367 diff_usec_last = (*__time_it)->tv_usec - last_usec;
368 if (diff_usec_last < 0) {
370 diff_usec_last = 1000000 + diff_usec_last;
372 diff_msec_last = diff_usec_last / 1000.f;
374 last_sec = (*__time_it)->tv_sec;
375 last_usec = (*__time_it)->tv_usec;
377 ctime_r(&(*__time_it)->tv_sec, time_string);
378 for (j = 26; j > 0; --j) {
379 if (time_string[j] ==
'\n') {
384 cout << time_string <<
" (" << (*__time_it)->tv_sec <<
")" << endl;
385 cout <<
"Diff to start: " << diff_sec_start <<
" sec and " << diff_usec_start
386 <<
" usec (which are " 387 << diff_msec_start <<
" msec)" << endl;
388 cout <<
"Diff to last: " << diff_sec_last <<
" sec and " << diff_usec_last
389 <<
" usec (which are " 390 << diff_msec_last <<
" msec)" << endl << endl;
396 cout << endl <<
"TimeTracker stats - class times";
397 if (!__tracker_comment.empty()) {
398 cout <<
" (" << __tracker_comment <<
")";
401 <<
"==================================================================" << endl;
403 vector<vector<struct timeval *> >::iterator it = __class_times.begin();
404 vector<string>::iterator sit = __class_names.begin();
406 double deviation = 0.f;
407 double average = 0.f;
408 double average_ms = 0.f;
409 double deviation_ms = 0.f;
411 for (; (it != __class_times.end()) && (sit != __class_names.end()); ++it, ++sit) {
412 if (sit->empty())
continue;
414 if (it->size() > 0) {
416 average_and_deviation(*it, average, average_ms, deviation, deviation_ms);
418 cout <<
"Class '" << *sit <<
"'" << endl
419 <<
" avg=" << average <<
" (" << average_ms <<
" ms)" << endl
420 <<
" dev=" << deviation <<
" (" << deviation_ms <<
" ms)" << endl
421 <<
" res=" << it->size() <<
" results" 424 cout <<
"Class '" << *sit <<
"' has no results." << endl;
442 TimeTracker::print_to_file()
444 if ( ! __timelog)
throw Exception(
"Time log not opened, use other ctor");
446 vector<vector<struct timeval *> >::iterator it = __class_times.begin();
447 vector<string>::iterator sit = __class_names.begin();
449 double deviation = 0.f;
450 double average = 0.f;
451 double average_ms = 0.f;
452 double deviation_ms = 0.f;
455 fprintf(__timelog,
"%u ", ++__write_cycle);
456 for (; (it != __class_times.end()) && (sit != __class_names.end()); ++it, ++sit) {
457 if (sit->empty())
continue;
459 average_and_deviation(*it, average, average_ms, deviation, deviation_ms);
462 fprintf(__timelog,
"%lf %lf %lf %lf %lf ",
463 average, average_ms, avgsum, deviation, deviation_ms);
465 fprintf(__timelog,
"\n");
479 ScopedClassItemTracker::ScopedClassItemTracker(
TimeTracker &tt,
unsigned int cls)
File could not be opened.
void ping_start(unsigned int cls)
Start of given class task.
Fawkes library namespace.
Base class for exceptions in Fawkes.
void ping_end(unsigned int cls)
End of given class task.
~ScopedClassItemTracker()
Destructor.