From 967be9e750221ab2ab783f95df79bb26d290a45e Mon Sep 17 00:00:00 2001 From: Martial Simon Date: Mon, 15 Sep 2025 01:07:58 +0200 Subject: add: added projects --- tiger-compiler/lib/misc/timer.cc | 208 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100644 tiger-compiler/lib/misc/timer.cc (limited to 'tiger-compiler/lib/misc/timer.cc') diff --git a/tiger-compiler/lib/misc/timer.cc b/tiger-compiler/lib/misc/timer.cc new file mode 100644 index 0000000..703930f --- /dev/null +++ b/tiger-compiler/lib/misc/timer.cc @@ -0,0 +1,208 @@ +/** + ** \file misc/timer.cc + ** \brief Implementation for misc/timer.hh. + */ + +#include +#include +#include + +#include +#include + +namespace misc +{ + /*-----------------. + | timer::time_var. | + `-----------------*/ + + timer::time_var::time_var() + : initial(true) + {} + + void timer::time_var::start() + { + struct tms tms; + + begin.wall = times(&tms); + begin.user = tms.tms_utime; + begin.sys = tms.tms_stime; + + if (initial) + { + initial = false; + first = begin; + } + } + + void timer::time_var::stop() + { + struct tms tms; + + last.wall = times(&tms); + last.user = tms.tms_utime; + last.sys = tms.tms_stime; + elapsed.wall += last.wall - begin.wall; + elapsed.user += last.user - begin.user; + elapsed.sys += last.sys - begin.sys; + } + + bool timer::time_var::is_zero() + { + return elapsed.wall == 0 && elapsed.user == 0 && elapsed.sys == 0; + } + + /*--------. + | timer. | + `--------*/ + + timer::timer() + : dump_stream(nullptr) + {} + + // Duplicate a timer. No tasks should be running. + timer::timer(const timer& rhs) + : intmap(rhs.intmap) + , total(rhs.total) + , dump_stream(rhs.dump_stream) + { + precondition(rhs.tasks.empty()); + + for (const task_map_type::value_type& p : rhs.tasksmap) + if (tasksmap.find(p.first) == tasksmap.end()) + tasksmap[p.first] = new time_var(*p.second); + } + + timer::~timer() + { + // Print information if automatic dumping has been enabled. + if (dump_stream) + { + // Consider that if the tasks were not properly closed, then + // stop was not invoked either. + if (!tasks.empty()) + { + do + pop(); + while (!tasks.empty()); + stop(); + } + dump(*dump_stream); + } + + // Deallocate all our time_var's. + for (task_map_type::value_type& p : tasksmap) + delete p.second; + } + + void timer::name(int i, const std::string& task_name) + { + intmap[i] = task_name; + } + + void timer::timeinfo(long time, long total_time, std::ostream& out) + { + out << std::setiosflags(std::ios::left) << std::setw(6) + << std::setprecision(6) << float(time) / clocks_per_sec + << std::resetiosflags(std::ios::left) << " (" << std::setw(5) + << std::setprecision(3) + << (total_time ? float(time) * 100 / total_time : float(time)) << "%) "; + } + + void timer::dump(std::ostream& out) + { + out << "Execution times (seconds)\n"; + for (const task_map_type::value_type& p : tasksmap) + { + if (!p.second->is_zero()) + { + out << " " << p.first << std::setw(26 - p.first.length()) << ": "; + timeinfo(p.second->elapsed.user, total.elapsed.user, out); + out << " "; + timeinfo(p.second->elapsed.sys, total.elapsed.sys, out); + out << " "; + timeinfo(p.second->elapsed.wall, total.elapsed.wall, out); + out << '\n'; + } + } + out << '\n'; + + out << "Cumulated times (seconds)\n"; + for (const task_map_type::value_type& p : tasksmap) + { + if (p.second->last.wall != p.second->first.wall) + { + out << " " << p.first << std::setw(26 - p.first.length()) << ": "; + timeinfo(p.second->last.user - p.second->first.user, + total.elapsed.user, out); + out << " "; + timeinfo(p.second->last.sys - p.second->first.sys, + total.elapsed.sys, out); + out << " "; + timeinfo(p.second->last.wall - p.second->first.wall, + total.elapsed.wall, out); + out << '\n'; + } + } + out << '\n'; + + out << " TOTAL (seconds)" << std::setw(11) << ": " + + << std::setiosflags(std::ios::left) << std::setw(7) + << float(total.elapsed.user) / clocks_per_sec << std::setw(11) + << "user," + + << std::setw(7) << float(total.elapsed.sys) / clocks_per_sec + << std::setw(11) << "system," + + << std::setw(7) << float(total.elapsed.wall) / clocks_per_sec << "wall" + + << std::resetiosflags(std::ios::left) << std::endl; + } + + void timer::push(const std::string& task_name) + { + time_var* current; + + // If the stack is not empty, set the elapsed time for the current + // task. + if (!tasks.empty()) + tasks.top()->stop(); + + if (tasksmap.find(task_name) == tasksmap.end()) + tasksmap[task_name] = new time_var; + + current = tasksmap[task_name]; + tasks.push(current); + current->start(); + } + + void timer::pop() + { + precondition(!tasks.empty()); + + // Set the elapsed time for the current task before popping it. + tasks.top()->stop(); + tasks.pop(); + + // Set the start time of the previous task to the current time. + if (!tasks.empty()) + tasks.top()->start(); + } + + timer& timer::operator<<(const timer& rhs) + { + // No task should be running when merging timers. + precondition(rhs.tasks.empty()); + + for (const task_map_type::value_type& p : rhs.tasksmap) + if (tasksmap.find(p.first) == tasksmap.end()) + tasksmap[p.first] = new time_var(*p.second); + + intmap.insert(rhs.intmap.begin(), rhs.intmap.end()); + return *this; + } + + const long timer::clocks_per_sec = sysconf(_SC_CLK_TCK); + +} // namespace misc -- cgit v1.2.3