crt/stats.cpp
#include "stats.hpp"
#ifdef STATS
INIT_EARLY std::set<Timer*> Timer::registry;
Timer::Timer(const char* desc, bool reg) {
strncpy(name, desc, sizeof(name));
name[sizeof(name)-1] = '\0';
memset(&sum, 0, sizeof(sum));
if (reg) registry.insert(this);
}
Timer::~Timer() {
registry.erase(this);
}
void Timer::reset() {
memset(&sum, 0, sizeof(sum));
}
uint64_t Timer::get() const {
return (sum.tv_sec * 1000000000ll) + sum.tv_nsec;
}
void Timer::start() {
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &curr);
}
void Timer::end() {
struct timespec end;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end);
if (end.tv_nsec >= curr.tv_nsec) {
sum.tv_sec += end.tv_sec - curr.tv_sec;
sum.tv_nsec += end.tv_nsec - curr.tv_nsec;
if (sum.tv_nsec >= 1000000000l) {
sum.tv_sec++;
sum.tv_nsec -= 1000000000l;
assert(sum.tv_nsec < 1000000000l);
}
} else {
sum.tv_nsec += end.tv_nsec + (1000000000l - curr.tv_nsec);
if (end.tv_sec > curr.tv_sec + 1) {
sum.tv_sec += end.tv_sec - curr.tv_sec - 1;
}
if (sum.tv_nsec >= 2000000000l) {
sum.tv_sec += 2;
sum.tv_nsec -= 2000000000l;
assert(sum.tv_nsec < 1000000000l);
} else if (sum.tv_nsec >= 1000000000l) {
sum.tv_sec++;
sum.tv_nsec -= 1000000000l;
assert(sum.tv_nsec < 1000000000l);
}
}
}
void Timer::print() const {
LOG("%s: %ld.%09ld", name, sum.tv_sec, sum.tv_nsec);
}
void Timer::print_all() {
for (std::set<Timer*>::const_iterator it = registry.begin(); it != registry.end(); ++it) {
(*it)->print();
}
}
void Timer::reset_all() {
for (std::set<Timer*>::const_iterator it = registry.begin(); it != registry.end(); ++it) {
(*it)->reset();
}
}
INIT_EARLY std::set<Counter*> Counter::registry;
Counter::Counter(const char* desc, bool reg) {
strncpy(name, desc, sizeof(name));
name[sizeof(name)-1] = '\0';
num = 0;
sum = 0;
if (reg) registry.insert(this);
}
Counter::~Counter() {
registry.erase(this);
}
void Counter::reset() {
num = 0;
sum = 0;
}
void Counter::inc() {
++num;
}
void Counter::inc(unsigned i) {
++num;
sum += i;
}
void Counter::print() const {
LOG("%s: %llu/%llu (%f)", name, sum, num, num? (float)sum/(float)num: 0);
}
void Counter::print_all() {
for (std::set<Counter*>::const_iterator it = registry.begin(); it != registry.end(); ++it) {
(*it)->print();
}
}
void Counter::reset_all() {
for (std::set<Counter*>::const_iterator it = registry.begin(); it != registry.end(); ++it) {
(*it)->reset();
}
}
#endif