2020-11-03 11:26:42 +03:00
|
|
|
#include "mold.h"
|
|
|
|
|
2020-12-10 16:32:47 +03:00
|
|
|
#include <iomanip>
|
|
|
|
#include <ios>
|
2020-12-11 10:51:20 +03:00
|
|
|
#include <sys/resource.h>
|
|
|
|
#include <sys/time.h>
|
2020-12-10 16:32:47 +03:00
|
|
|
|
2020-11-03 11:26:42 +03:00
|
|
|
void Counter::print() {
|
|
|
|
if (!enabled)
|
|
|
|
return;
|
|
|
|
|
|
|
|
std::vector<Counter *> vec = instances;
|
2020-12-21 12:42:14 +03:00
|
|
|
sort(vec, [](Counter *a, Counter *b) { return a->value > b->value; });
|
2020-11-03 11:26:42 +03:00
|
|
|
|
|
|
|
for (Counter *c : vec)
|
2020-12-10 16:32:47 +03:00
|
|
|
std::cout << std::setw(20) << std::right << c->name << "=" << c->value << "\n";
|
2020-11-03 11:26:42 +03:00
|
|
|
}
|
2020-12-11 10:51:20 +03:00
|
|
|
|
2021-01-24 07:26:03 +03:00
|
|
|
static i64 now_nsec() {
|
2020-12-11 10:51:20 +03:00
|
|
|
struct timespec t;
|
|
|
|
clock_gettime(CLOCK_MONOTONIC, &t);
|
2021-01-24 07:26:03 +03:00
|
|
|
return (i64)t.tv_sec * 1000000000 + t.tv_nsec;
|
2020-12-11 10:51:20 +03:00
|
|
|
}
|
|
|
|
|
2021-01-24 07:26:03 +03:00
|
|
|
static i64 to_nsec(struct timeval t) {
|
|
|
|
return (i64)t.tv_sec * 1000000000 + t.tv_usec * 1000;
|
2020-12-11 10:51:20 +03:00
|
|
|
}
|
|
|
|
|
2021-01-09 12:15:09 +03:00
|
|
|
TimerRecord::TimerRecord(std::string name) : name(name) {
|
2020-12-11 10:51:20 +03:00
|
|
|
struct rusage usage;
|
|
|
|
getrusage(RUSAGE_SELF, &usage);
|
|
|
|
|
|
|
|
start = now_nsec();
|
2020-12-11 10:52:19 +03:00
|
|
|
user = to_nsec(usage.ru_utime);
|
|
|
|
sys = to_nsec(usage.ru_stime);
|
2020-12-11 10:51:20 +03:00
|
|
|
}
|
|
|
|
|
2021-01-09 12:15:09 +03:00
|
|
|
void TimerRecord::stop() {
|
2020-12-11 10:51:20 +03:00
|
|
|
if (stopped)
|
|
|
|
return;
|
|
|
|
stopped = true;
|
|
|
|
|
|
|
|
struct rusage usage;
|
|
|
|
getrusage(RUSAGE_SELF, &usage);
|
|
|
|
|
|
|
|
end = now_nsec();
|
2020-12-11 10:52:19 +03:00
|
|
|
user = to_nsec(usage.ru_utime) - user;
|
|
|
|
sys = to_nsec(usage.ru_stime) - sys;
|
2020-12-11 10:51:20 +03:00
|
|
|
}
|
|
|
|
|
2021-01-09 12:15:09 +03:00
|
|
|
Timer::Timer(std::string name) {
|
|
|
|
record = new TimerRecord(name);
|
|
|
|
records.push_back(record);
|
|
|
|
}
|
|
|
|
|
|
|
|
Timer::~Timer() {
|
|
|
|
record->stop();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Timer::stop() {
|
|
|
|
record->stop();
|
|
|
|
}
|
|
|
|
|
2020-12-11 10:51:20 +03:00
|
|
|
void Timer::print() {
|
2021-01-24 06:01:43 +03:00
|
|
|
for (i64 i = records.size() - 1; i >= 0; i--)
|
2021-01-09 12:15:09 +03:00
|
|
|
records[i]->stop();
|
2020-12-11 10:51:20 +03:00
|
|
|
|
2021-01-24 06:01:43 +03:00
|
|
|
std::vector<i64> depth(records.size());
|
2020-12-11 10:51:20 +03:00
|
|
|
|
2021-01-24 06:01:43 +03:00
|
|
|
for (i64 i = 0; i < records.size(); i++)
|
|
|
|
for (i64 j = 0; j < i; j++)
|
2021-01-09 12:15:09 +03:00
|
|
|
if (records[i]->end < records[j]->end)
|
2020-12-11 11:04:19 +03:00
|
|
|
depth[i]++;
|
2020-12-11 10:51:20 +03:00
|
|
|
|
|
|
|
std::cout << " User System Real Name\n";
|
|
|
|
|
2021-01-24 06:01:43 +03:00
|
|
|
for (i64 i = 0; i < records.size(); i++) {
|
2021-01-09 12:15:09 +03:00
|
|
|
TimerRecord &rec = *records[i];
|
2020-12-11 10:51:20 +03:00
|
|
|
printf(" % 8.3f % 8.3f % 8.3f %s%s\n",
|
2021-01-09 12:15:09 +03:00
|
|
|
((double)rec.user / 1000000000),
|
|
|
|
((double)rec.sys / 1000000000),
|
|
|
|
(((double)rec.end - rec.start) / 1000000000),
|
2020-12-12 07:11:55 +03:00
|
|
|
std::string(depth[i] * 2, ' ').c_str(),
|
2021-01-09 12:15:09 +03:00
|
|
|
rec.name.c_str());
|
2020-12-11 10:51:20 +03:00
|
|
|
}
|
2020-12-11 10:52:19 +03:00
|
|
|
|
2020-12-11 10:51:20 +03:00
|
|
|
std::cout << std::flush;
|
|
|
|
}
|