}
}
+/* See maint.h. */
+
+scoped_time_it::scoped_time_it (const char *what)
+ : m_enabled (per_command_time),
+ m_what (what),
+ m_start_wall (m_enabled
+ ? std::chrono::steady_clock::now ()
+ : std::chrono::steady_clock::time_point ())
+{
+ if (m_enabled)
+ get_run_time (m_start_user, m_start_sys, run_time_scope::thread);
+}
+
+/* See maint.h. */
+
+scoped_time_it::~scoped_time_it ()
+{
+ if (!m_enabled)
+ return;
+
+ namespace chr = std::chrono;
+ auto end_wall = chr::steady_clock::now ();
+
+ user_cpu_time_clock::time_point end_user;
+ system_cpu_time_clock::time_point end_sys;
+ get_run_time (end_user, end_sys, run_time_scope::thread);
+
+ auto user = end_user - m_start_user;
+ auto sys = end_sys - m_start_sys;
+ auto wall = end_wall - m_start_wall;
+ auto user_ms = chr::duration_cast<chr::milliseconds> (user).count ();
+ auto sys_ms = chr::duration_cast<chr::milliseconds> (sys).count ();
+ auto wall_ms = chr::duration_cast<chr::milliseconds> (wall).count ();
+ auto user_plus_sys_ms = user_ms + sys_ms;
+
+ auto str
+ = string_printf ("Time for \"%s\": wall %.03f, user %.03f, sys %.03f, "
+ "user+sys %.03f, %.01f %% CPU\n",
+ m_what, wall_ms / 1000.0, user_ms / 1000.0,
+ sys_ms / 1000.0, user_plus_sys_ms / 1000.0,
+ user_plus_sys_ms * 100.0 / wall_ms);
+ gdb_stdlog->write_async_safe (str.data (), str.size ());
+}
+
/* Options affecting the "maintenance selftest" command. */
struct maintenance_selftest_options
int m_start_nr_blocks;
};
+/* RAII structure used to measure the time spent by the current thread in a
+ given scope. */
+
+struct scoped_time_it
+{
+ /* WHAT is the prefix to show when the summary line is printed. */
+ scoped_time_it (const char *what);
+
+ DISABLE_COPY_AND_ASSIGN (scoped_time_it);
+ ~scoped_time_it ();
+
+private:
+ bool m_enabled;
+
+ /* Summary line prefix. */
+ const char *m_what;
+
+ /* User time at the start of execution. */
+ user_cpu_time_clock::time_point m_start_user;
+
+ /* System time at the start of execution. */
+ system_cpu_time_clock::time_point m_start_sys;
+
+ /* Wall-clock time at the start of execution. */
+ std::chrono::steady_clock::time_point m_start_wall;
+};
+
extern obj_section *maint_obj_section_from_bfd_section (bfd *abfd,
asection *asection,
objfile *ofile);
using namespace std::chrono;
tv->wallclock = steady_clock::now ();
- get_run_time (tv->utime, tv->stime);
+ get_run_time (tv->utime, tv->stime, run_time_scope::process);
}
static void
void
get_run_time (user_cpu_time_clock::time_point &user,
- system_cpu_time_clock::time_point &system) noexcept
+ system_cpu_time_clock::time_point &system,
+ run_time_scope scope) noexcept
{
#ifdef HAVE_GETRUSAGE
struct rusage rusage;
+ int who;
- getrusage (RUSAGE_SELF, &rusage);
+ switch (scope)
+ {
+ case run_time_scope::thread:
+ who = RUSAGE_THREAD;
+ break;
+
+ case run_time_scope::process:
+ who = RUSAGE_SELF;
+ break;
+
+ default:
+ gdb_assert_not_reached ("invalid run_time_scope value");
+ }
+
+ getrusage (who, &rusage);
microseconds utime = timeval_to_microseconds (&rusage.ru_utime);
microseconds stime = timeval_to_microseconds (&rusage.ru_stime);
static time_point now () noexcept = delete;
};
+/* Whether to measure time run time for the whole process or just one
+ thread. */
+
+enum class run_time_scope
+{
+ process,
+ thread,
+};
+
/* Return the user/system time as separate time points, if
supported. If not supported, then the combined user+kernel time
- is returned in USER and SYSTEM is set to zero. */
+ is returned in USER and SYSTEM is set to zero.
+
+ SCOPE indicates whether to return the run time for the whole process or
+ just for the calling thread. */
void get_run_time (user_cpu_time_clock::time_point &user,
- system_cpu_time_clock::time_point &system) noexcept;
+ system_cpu_time_clock::time_point &system,
+ run_time_scope scope) noexcept;
/* Count the total amount of time spent executing in userspace+kernel
mode. */