gdb: Use C++11 std::chrono
This patch fixes a few problems with GDB's time handling. #1 - It avoids problems with gnulib's C++ namespace support On MinGW, the struct timeval that should be passed to gnulib's gettimeofday replacement is incompatible with libiberty's timeval_sub/timeval_add. That's because gnulib also replaces "struct timeval" with its own definition, while libiberty expects the system's. E.g., in code like this: gettimeofday (&prompt_ended, NULL); timeval_sub (&prompt_delta, &prompt_ended, &prompt_started); timeval_add (&prompt_for_continue_wait_time, &prompt_for_continue_wait_time, &prompt_delta); That's currently handled in gdb by not using gnulib's gettimeofday at all (see common/gdb_sys_time.h), but that #undef hack won't work with if/when we enable gnulib's C++ namespace support, because that mode adds compile time warnings for uses of ::gettimeofday, which are hard errors with -Werror. #2 - But there's an elephant in the room: gettimeofday is not monotonic... We're using it to: a) check how long functions take, for performance analysis b) compute when in the future to fire events in the event-loop c) print debug timestamps But that's exactly what gettimeofday is NOT meant for. Straight from the man page: ~~~ The time returned by gettimeofday() is affected by discontinuous jumps in the system time (e.g., if the system administrator manually changes the system time). If you need a monotonically increasing clock, see clock_gettime(2). ~~~ std::chrono (part of the C++11 standard library) has a monotonic clock exactly for such purposes (std::chrono::steady_clock). This commit switches to use that instead of gettimeofday, fixing all the issues mentioned above. gdb/ChangeLog: 2016-11-23 Pedro Alves <palves@redhat.com> * Makefile.in (SFILES): Add common/run-time-clock.c. (HFILES_NO_SRCDIR): Add common/run-time-clock.h. (COMMON_OBS): Add run-time-clock.o. * common/run-time-clock.c, common/run-time-clock.h: New files. * defs.h (struct timeval, print_transfer_performance): Delete declarations. * event-loop.c (struct gdb_timer) <when>: Now a std::chrono::steady_clock::time_point. (create_timer): use std::chrono::steady_clock instead of gettimeofday. Use new instead of malloc. (delete_timer): Use delete instead of xfree. (duration_cast_timeval): New. (update_wait_timeout): Use std::chrono::steady_clock instead of gettimeofday. * maint.c: Include <chrono> instead of "gdb_sys_time.h", <time.h> and "timeval-utils.h". (scoped_command_stats::~scoped_command_stats) (scoped_command_stats::scoped_command_stats): Use std::chrono::steady_clock instead of gettimeofday. Use user_cpu_time_clock instead of get_run_time. * maint.h: Include "run-time-clock.h" and <chrono>. (scoped_command_stats): <m_start_cpu_time>: Now a user_cpu_time_clock::time_point. <m_start_wall_time>: Now a std::chrono::steady_clock::time_point. * mi/mi-main.c: Include "run-time-clock.h" and <chrono> instead of "gdb_sys_time.h" and <sys/resource.h>. (rusage): Delete. (mi_execute_command): Use new instead of XNEW. (mi_load_progress): Use std::chrono::steady_clock instead of gettimeofday. (timestamp): Rewrite in terms of std::chrono::steady_clock, user_cpu_time_clock and system_cpu_time_clock. (timeval_diff): Delete. (print_diff): Adjust to use std::chrono::steady_clock, user_cpu_time_clock and system_cpu_time_clock. * mi/mi-parse.h: Include "run-time-clock.h" and <chrono> instead of "gdb_sys_time.h". (struct mi_timestamp): Change fields types to std::chrono::steady_clock::time_point, user_cpu_time_clock::time and system_cpu_time_clock::time_point, instead of struct timeval. * symfile.c: Include <chrono> instead of <time.h> and "gdb_sys_time.h". (struct time_range): New. (generic_load): Use std::chrono::steady_clock instead of gettimeofday. (print_transfer_performance): Replace timeval parameters with a std::chrono::steady_clock::duration parameter. Adjust. * utils.c: Include <chrono> instead of "timeval-utils.h", "gdb_sys_time.h", and <time.h>. (prompt_for_continue_wait_time): Now a std::chrono::steady_clock::duration. (defaulted_query, prompt_for_continue): Use std::chrono::steady_clock instead of gettimeofday/timeval_sub/timeval_add. (reset_prompt_for_continue_wait_time): Use std::chrono::steady_clock::duration instead of struct timeval. (get_prompt_for_continue_wait_time): Return a std::chrono::steady_clock::duration instead of struct timeval. (vfprintf_unfiltered): Use std::chrono::steady_clock instead of gettimeofday. Use std::string. Use '.' instead of ':'. * utils.h: Include <chrono>. (get_prompt_for_continue_wait_time): Return a std::chrono::steady_clock::duration instead of struct timeval. gdb/gdbserver/ChangeLog: 2016-11-23 Pedro Alves <palves@redhat.com> * debug.c: Include <chrono> instead of "gdb_sys_time.h". (debug_vprintf): Use std::chrono::steady_clock instead of gettimeofday. Use '.' instead of ':'. * tracepoint.c: Include <chrono> instead of "gdb_sys_time.h". (get_timestamp): Use std::chrono::steady_clock instead of gettimeofday.
This commit is contained in:
parent
7836e407c6
commit
dcb07cfa15
@ -1,3 +1,69 @@
|
||||
2016-11-23 Pedro Alves <palves@redhat.com>
|
||||
|
||||
* Makefile.in (SFILES): Add common/run-time-clock.c.
|
||||
(HFILES_NO_SRCDIR): Add common/run-time-clock.h.
|
||||
(COMMON_OBS): Add run-time-clock.o.
|
||||
* common/run-time-clock.c, common/run-time-clock.h: New files.
|
||||
* defs.h (struct timeval, print_transfer_performance): Delete
|
||||
declarations.
|
||||
* event-loop.c (struct gdb_timer) <when>: Now a
|
||||
std::chrono::steady_clock::time_point.
|
||||
(create_timer): use std::chrono::steady_clock instead of
|
||||
gettimeofday. Use new instead of malloc.
|
||||
(delete_timer): Use delete instead of xfree.
|
||||
(duration_cast_timeval): New.
|
||||
(update_wait_timeout): Use std::chrono::steady_clock instead of
|
||||
gettimeofday.
|
||||
* maint.c: Include <chrono> instead of "gdb_sys_time.h", <time.h>
|
||||
and "timeval-utils.h".
|
||||
(scoped_command_stats::~scoped_command_stats)
|
||||
(scoped_command_stats::scoped_command_stats): Use
|
||||
std::chrono::steady_clock instead of gettimeofday. Use
|
||||
user_cpu_time_clock instead of get_run_time.
|
||||
* maint.h: Include "run-time-clock.h" and <chrono>.
|
||||
(scoped_command_stats): <m_start_cpu_time>: Now a
|
||||
user_cpu_time_clock::time_point.
|
||||
<m_start_wall_time>: Now a std::chrono::steady_clock::time_point.
|
||||
* mi/mi-main.c: Include "run-time-clock.h" and <chrono> instead of
|
||||
"gdb_sys_time.h" and <sys/resource.h>.
|
||||
(rusage): Delete.
|
||||
(mi_execute_command): Use new instead of XNEW.
|
||||
(mi_load_progress): Use std::chrono::steady_clock instead of
|
||||
gettimeofday.
|
||||
(timestamp): Rewrite in terms of std::chrono::steady_clock,
|
||||
user_cpu_time_clock and system_cpu_time_clock.
|
||||
(timeval_diff): Delete.
|
||||
(print_diff): Adjust to use std::chrono::steady_clock,
|
||||
user_cpu_time_clock and system_cpu_time_clock.
|
||||
* mi/mi-parse.h: Include "run-time-clock.h" and <chrono> instead
|
||||
of "gdb_sys_time.h".
|
||||
(struct mi_timestamp): Change fields types to
|
||||
std::chrono::steady_clock::time_point, user_cpu_time_clock::time
|
||||
and system_cpu_time_clock::time_point, instead of struct timeval.
|
||||
* symfile.c: Include <chrono> instead of <time.h> and
|
||||
"gdb_sys_time.h".
|
||||
(struct time_range): New.
|
||||
(generic_load): Use std::chrono::steady_clock instead of
|
||||
gettimeofday.
|
||||
(print_transfer_performance): Replace timeval parameters with a
|
||||
std::chrono::steady_clock::duration parameter. Adjust.
|
||||
* utils.c: Include <chrono> instead of "timeval-utils.h",
|
||||
"gdb_sys_time.h", and <time.h>.
|
||||
(prompt_for_continue_wait_time): Now a
|
||||
std::chrono::steady_clock::duration.
|
||||
(defaulted_query, prompt_for_continue): Use
|
||||
std::chrono::steady_clock instead of
|
||||
gettimeofday/timeval_sub/timeval_add.
|
||||
(reset_prompt_for_continue_wait_time): Use
|
||||
std::chrono::steady_clock::duration instead of struct timeval.
|
||||
(get_prompt_for_continue_wait_time): Return a
|
||||
std::chrono::steady_clock::duration instead of struct timeval.
|
||||
(vfprintf_unfiltered): Use std::chrono::steady_clock instead of
|
||||
gettimeofday. Use std::string. Use '.' instead of ':'.
|
||||
* utils.h: Include <chrono>.
|
||||
(get_prompt_for_continue_wait_time): Return a
|
||||
std::chrono::steady_clock::duration instead of struct timeval.
|
||||
|
||||
2016-11-22 Simon Marchi <simon.marchi@polymtl.ca>
|
||||
|
||||
* Makefile.in: Fix whitespace formatting.
|
||||
|
@ -1201,6 +1201,7 @@ SFILES = \
|
||||
common/print-utils.c \
|
||||
common/ptid.c \
|
||||
common/rsp-low.c \
|
||||
common/run-time-clock.c \
|
||||
common/signals.c \
|
||||
common/signals-state-save-restore.c \
|
||||
common/vec.c \
|
||||
@ -1485,6 +1486,7 @@ HFILES_NO_SRCDIR = \
|
||||
common/ptid.h \
|
||||
common/queue.h \
|
||||
common/rsp-low.h \
|
||||
common/run-time-clock.h \
|
||||
common/signals-state-save-restore.h \
|
||||
common/symbol.h \
|
||||
common/vec.h \
|
||||
@ -1739,6 +1741,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \
|
||||
registry.o \
|
||||
reverse.o \
|
||||
rsp-low.o \
|
||||
run-time-clock.o \
|
||||
rust-lang.o \
|
||||
selftest.o \
|
||||
sentinel-frame.o \
|
||||
|
58
gdb/common/run-time-clock.c
Normal file
58
gdb/common/run-time-clock.c
Normal file
@ -0,0 +1,58 @@
|
||||
/* User/system CPU time clocks that follow the std::chrono interface.
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "common-defs.h"
|
||||
#include "run-time-clock.h"
|
||||
#if defined HAVE_SYS_RESOURCE_H
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
using namespace std::chrono;
|
||||
|
||||
run_time_clock::time_point
|
||||
run_time_clock::now () noexcept
|
||||
{
|
||||
return time_point (microseconds (get_run_time ()));
|
||||
}
|
||||
|
||||
#ifdef HAVE_GETRUSAGE
|
||||
static std::chrono::microseconds
|
||||
timeval_to_microseconds (struct timeval *tv)
|
||||
{
|
||||
return (seconds (tv->tv_sec) + microseconds (tv->tv_usec));
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
run_time_clock::now (user_cpu_time_clock::time_point &user,
|
||||
system_cpu_time_clock::time_point &system) noexcept
|
||||
{
|
||||
#ifdef HAVE_GETRUSAGE
|
||||
struct rusage rusage;
|
||||
|
||||
getrusage (RUSAGE_SELF, &rusage);
|
||||
|
||||
microseconds utime = timeval_to_microseconds (&rusage.ru_utime);
|
||||
microseconds stime = timeval_to_microseconds (&rusage.ru_stime);
|
||||
user = user_cpu_time_clock::time_point (utime);
|
||||
system = system_cpu_time_clock::time_point (stime);
|
||||
#else
|
||||
user = user_cpu_time_clock::time_point (microseconds (get_run_time ()));
|
||||
system = system_cpu_time_clock::time_point (microseconds::zero ());
|
||||
#endif
|
||||
}
|
75
gdb/common/run-time-clock.h
Normal file
75
gdb/common/run-time-clock.h
Normal file
@ -0,0 +1,75 @@
|
||||
/* User/system CPU time clocks that follow the std::chrono interface.
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef RUN_TIME_CLOCK_H
|
||||
#define RUN_TIME_CLOCK_H
|
||||
|
||||
#include <chrono>
|
||||
|
||||
/* Count the total amount of time spent executing in user mode. */
|
||||
|
||||
struct user_cpu_time_clock
|
||||
{
|
||||
using duration = std::chrono::microseconds;
|
||||
using rep = duration::rep;
|
||||
using period = duration::period;
|
||||
using time_point = std::chrono::time_point<user_cpu_time_clock>;
|
||||
|
||||
static constexpr bool is_steady = true;
|
||||
|
||||
/* Use run_time_clock::now instead. */
|
||||
static time_point now () noexcept = delete;
|
||||
};
|
||||
|
||||
/* Count the total amount of time spent executing in kernel mode. */
|
||||
|
||||
struct system_cpu_time_clock
|
||||
{
|
||||
using duration = std::chrono::microseconds;
|
||||
using rep = duration::rep;
|
||||
using period = duration::period;
|
||||
using time_point = std::chrono::time_point<system_cpu_time_clock>;
|
||||
|
||||
static constexpr bool is_steady = true;
|
||||
|
||||
/* Use run_time_clock::now instead. */
|
||||
static time_point now () noexcept = delete;
|
||||
};
|
||||
|
||||
/* Count the total amount of time spent executing in userspace+kernel
|
||||
mode. */
|
||||
|
||||
struct run_time_clock
|
||||
{
|
||||
using duration = std::chrono::microseconds;
|
||||
using rep = duration::rep;
|
||||
using period = duration::period;
|
||||
using time_point = std::chrono::time_point<run_time_clock>;
|
||||
|
||||
static constexpr bool is_steady = true;
|
||||
|
||||
static time_point now () noexcept;
|
||||
|
||||
/* 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. */
|
||||
static void now (user_cpu_time_clock::time_point &user,
|
||||
system_cpu_time_clock::time_point &system) noexcept;
|
||||
};
|
||||
|
||||
#endif
|
14
gdb/defs.h
14
gdb/defs.h
@ -303,20 +303,6 @@ extern void symbol_file_command (char *, int);
|
||||
/* * Remote targets may wish to use this as their load function. */
|
||||
extern void generic_load (const char *name, int from_tty);
|
||||
|
||||
/* * Report on STREAM the performance of memory transfer operation,
|
||||
such as 'load'.
|
||||
@param DATA_COUNT is the number of bytes transferred.
|
||||
@param WRITE_COUNT is the number of separate write operations, or 0,
|
||||
if that information is not available.
|
||||
@param START_TIME is the time at which an operation was started.
|
||||
@param END_TIME is the time at which an operation ended. */
|
||||
struct timeval;
|
||||
extern void print_transfer_performance (struct ui_file *stream,
|
||||
unsigned long data_count,
|
||||
unsigned long write_count,
|
||||
const struct timeval *start_time,
|
||||
const struct timeval *end_time);
|
||||
|
||||
/* From top.c */
|
||||
|
||||
typedef void initialize_file_ftype (void);
|
||||
|
@ -212,7 +212,7 @@ gdb_notifier;
|
||||
first occasion after WHEN. */
|
||||
struct gdb_timer
|
||||
{
|
||||
struct timeval when;
|
||||
std::chrono::steady_clock::time_point when;
|
||||
int timer_id;
|
||||
struct gdb_timer *next;
|
||||
timer_handler_func *proc; /* Function to call to do the work. */
|
||||
@ -1097,33 +1097,22 @@ delete_async_event_handler (async_event_handler **async_handler_ptr)
|
||||
*async_handler_ptr = NULL;
|
||||
}
|
||||
|
||||
/* Create a timer that will expire in MILLISECONDS from now. When the
|
||||
timer is ready, PROC will be executed. At creation, the timer is
|
||||
aded to the timers queue. This queue is kept sorted in order of
|
||||
increasing timers. Return a handle to the timer struct. */
|
||||
/* Create a timer that will expire in MS milliseconds from now. When
|
||||
the timer is ready, PROC will be executed. At creation, the timer
|
||||
is added to the timers queue. This queue is kept sorted in order
|
||||
of increasing timers. Return a handle to the timer struct. */
|
||||
|
||||
int
|
||||
create_timer (int milliseconds, timer_handler_func * proc,
|
||||
create_timer (int ms, timer_handler_func *proc,
|
||||
gdb_client_data client_data)
|
||||
{
|
||||
using namespace std::chrono;
|
||||
struct gdb_timer *timer_ptr, *timer_index, *prev_timer;
|
||||
struct timeval time_now, delta;
|
||||
|
||||
/* Compute seconds. */
|
||||
delta.tv_sec = milliseconds / 1000;
|
||||
/* Compute microseconds. */
|
||||
delta.tv_usec = (milliseconds % 1000) * 1000;
|
||||
steady_clock::time_point time_now = steady_clock::now ();
|
||||
|
||||
gettimeofday (&time_now, NULL);
|
||||
|
||||
timer_ptr = XNEW (struct gdb_timer);
|
||||
timer_ptr->when.tv_sec = time_now.tv_sec + delta.tv_sec;
|
||||
timer_ptr->when.tv_usec = time_now.tv_usec + delta.tv_usec;
|
||||
/* Carry? */
|
||||
if (timer_ptr->when.tv_usec >= 1000000)
|
||||
{
|
||||
timer_ptr->when.tv_sec += 1;
|
||||
timer_ptr->when.tv_usec -= 1000000;
|
||||
}
|
||||
timer_ptr = new gdb_timer ();
|
||||
timer_ptr->when = time_now + milliseconds (ms);
|
||||
timer_ptr->proc = proc;
|
||||
timer_ptr->client_data = client_data;
|
||||
timer_list.num_timers++;
|
||||
@ -1136,11 +1125,7 @@ create_timer (int milliseconds, timer_handler_func * proc,
|
||||
timer_index != NULL;
|
||||
timer_index = timer_index->next)
|
||||
{
|
||||
/* If the seconds field is greater or if it is the same, but the
|
||||
microsecond field is greater. */
|
||||
if ((timer_index->when.tv_sec > timer_ptr->when.tv_sec)
|
||||
|| ((timer_index->when.tv_sec == timer_ptr->when.tv_sec)
|
||||
&& (timer_index->when.tv_usec > timer_ptr->when.tv_usec)))
|
||||
if (timer_index->when > timer_ptr->when)
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1194,47 +1179,56 @@ delete_timer (int id)
|
||||
;
|
||||
prev_timer->next = timer_ptr->next;
|
||||
}
|
||||
xfree (timer_ptr);
|
||||
delete timer_ptr;
|
||||
|
||||
gdb_notifier.timeout_valid = 0;
|
||||
}
|
||||
|
||||
/* Convert a std::chrono duration to a struct timeval. */
|
||||
|
||||
template<typename Duration>
|
||||
static struct timeval
|
||||
duration_cast_timeval (const Duration &d)
|
||||
{
|
||||
using namespace std::chrono;
|
||||
seconds sec = duration_cast<seconds> (d);
|
||||
microseconds msec = duration_cast<microseconds> (d - sec);
|
||||
|
||||
struct timeval tv;
|
||||
tv.tv_sec = sec.count ();
|
||||
tv.tv_usec = msec.count ();
|
||||
return tv;
|
||||
}
|
||||
|
||||
/* Update the timeout for the select() or poll(). Returns true if the
|
||||
timer has already expired, false otherwise. */
|
||||
|
||||
static int
|
||||
update_wait_timeout (void)
|
||||
{
|
||||
struct timeval time_now, delta;
|
||||
|
||||
if (timer_list.first_timer != NULL)
|
||||
{
|
||||
gettimeofday (&time_now, NULL);
|
||||
delta.tv_sec = timer_list.first_timer->when.tv_sec - time_now.tv_sec;
|
||||
delta.tv_usec = timer_list.first_timer->when.tv_usec - time_now.tv_usec;
|
||||
/* Borrow? */
|
||||
if (delta.tv_usec < 0)
|
||||
{
|
||||
delta.tv_sec -= 1;
|
||||
delta.tv_usec += 1000000;
|
||||
}
|
||||
using namespace std::chrono;
|
||||
steady_clock::time_point time_now = steady_clock::now ();
|
||||
struct timeval timeout;
|
||||
|
||||
/* Cannot simply test if delta.tv_sec is negative because time_t
|
||||
might be unsigned. */
|
||||
if (timer_list.first_timer->when.tv_sec < time_now.tv_sec
|
||||
|| (timer_list.first_timer->when.tv_sec == time_now.tv_sec
|
||||
&& timer_list.first_timer->when.tv_usec < time_now.tv_usec))
|
||||
if (timer_list.first_timer->when < time_now)
|
||||
{
|
||||
/* It expired already. */
|
||||
delta.tv_sec = 0;
|
||||
delta.tv_usec = 0;
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
steady_clock::duration d = timer_list.first_timer->when - time_now;
|
||||
timeout = duration_cast_timeval (d);
|
||||
}
|
||||
|
||||
/* Update the timeout for select/ poll. */
|
||||
if (use_poll)
|
||||
{
|
||||
#ifdef HAVE_POLL
|
||||
gdb_notifier.poll_timeout = delta.tv_sec * 1000;
|
||||
gdb_notifier.poll_timeout = timeout.tv_sec * 1000;
|
||||
#else
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("use_poll without HAVE_POLL"));
|
||||
@ -1242,12 +1236,12 @@ update_wait_timeout (void)
|
||||
}
|
||||
else
|
||||
{
|
||||
gdb_notifier.select_timeout.tv_sec = delta.tv_sec;
|
||||
gdb_notifier.select_timeout.tv_usec = delta.tv_usec;
|
||||
gdb_notifier.select_timeout.tv_sec = timeout.tv_sec;
|
||||
gdb_notifier.select_timeout.tv_usec = timeout.tv_usec;
|
||||
}
|
||||
gdb_notifier.timeout_valid = 1;
|
||||
|
||||
if (delta.tv_sec == 0 && delta.tv_usec == 0)
|
||||
if (timer_list.first_timer->when < time_now)
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
|
@ -1,3 +1,12 @@
|
||||
2016-11-23 Pedro Alves <palves@redhat.com>
|
||||
|
||||
* debug.c: Include <chrono> instead of "gdb_sys_time.h".
|
||||
(debug_vprintf): Use std::chrono::steady_clock instead of
|
||||
gettimeofday. Use '.' instead of ':'.
|
||||
* tracepoint.c: Include <chrono> instead of "gdb_sys_time.h".
|
||||
(get_timestamp): Use std::chrono::steady_clock instead of
|
||||
gettimeofday.
|
||||
|
||||
2016-11-22 Simon Marchi <simon.marchi@polymtl.ca>
|
||||
|
||||
* Makefile.in: Fix whitespace formatting.
|
||||
|
@ -17,7 +17,7 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "server.h"
|
||||
#include "gdb_sys_time.h"
|
||||
#include <chrono>
|
||||
|
||||
/* Enable miscellaneous debugging output. The name is historical - it
|
||||
was originally used to debug LinuxThreads support. */
|
||||
@ -27,8 +27,7 @@ int debug_threads;
|
||||
int debug_timestamp;
|
||||
|
||||
/* Print a debugging message.
|
||||
If the text begins a new line it is preceded by a timestamp, if the
|
||||
system has gettimeofday.
|
||||
If the text begins a new line it is preceded by a timestamp.
|
||||
We don't get fancy with newline checking, we just check whether the
|
||||
previous call ended with "\n". */
|
||||
|
||||
@ -41,14 +40,13 @@ debug_vprintf (const char *format, va_list ap)
|
||||
|
||||
if (debug_timestamp && new_line)
|
||||
{
|
||||
struct timeval tm;
|
||||
using namespace std::chrono;
|
||||
|
||||
gettimeofday (&tm, NULL);
|
||||
steady_clock::time_point now = steady_clock::now ();
|
||||
seconds s = duration_cast<seconds> (now.time_since_epoch ());
|
||||
microseconds us = duration_cast<microseconds> (now.time_since_epoch ()) - s;
|
||||
|
||||
/* If gettimeofday doesn't exist, and as a portability solution it has
|
||||
been replaced with, e.g., time, then it doesn't make sense to print
|
||||
the microseconds field. Is there a way to check for that? */
|
||||
fprintf (stderr, "%ld:%06ld ", (long) tm.tv_sec, (long) tm.tv_usec);
|
||||
fprintf (stderr, "%ld.%06ld ", (long) s.count (), (long) us.count ());
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include "gdb_sys_time.h"
|
||||
#include <chrono>
|
||||
#include <inttypes.h>
|
||||
#include "ax.h"
|
||||
#include "tdesc.h"
|
||||
@ -7410,12 +7410,10 @@ getauxval (unsigned long type)
|
||||
static LONGEST
|
||||
get_timestamp (void)
|
||||
{
|
||||
struct timeval tv;
|
||||
using namespace std::chrono;
|
||||
|
||||
if (gettimeofday (&tv, 0) != 0)
|
||||
return -1;
|
||||
else
|
||||
return (LONGEST) tv.tv_sec * 1000000 + tv.tv_usec;
|
||||
steady_clock::time_point now = steady_clock::now ();
|
||||
return duration_cast<microseconds> (now.time_since_epoch ()).count ();
|
||||
}
|
||||
|
||||
void
|
||||
|
31
gdb/maint.c
31
gdb/maint.c
@ -24,8 +24,6 @@
|
||||
#include "arch-utils.h"
|
||||
#include <ctype.h>
|
||||
#include <signal.h>
|
||||
#include "gdb_sys_time.h"
|
||||
#include <time.h>
|
||||
#include "command.h"
|
||||
#include "gdbcmd.h"
|
||||
#include "symtab.h"
|
||||
@ -39,7 +37,6 @@
|
||||
#include "objfiles.h"
|
||||
#include "value.h"
|
||||
#include "top.h"
|
||||
#include "timeval-utils.h"
|
||||
#include "maint.h"
|
||||
#include "selftest.h"
|
||||
|
||||
@ -822,23 +819,21 @@ scoped_command_stats::~scoped_command_stats ()
|
||||
|
||||
if (m_time_enabled && per_command_time)
|
||||
{
|
||||
long cmd_time = get_run_time () - m_start_cpu_time;
|
||||
struct timeval now_wall_time, delta_wall_time, wait_time;
|
||||
using namespace std::chrono;
|
||||
|
||||
gettimeofday (&now_wall_time, NULL);
|
||||
timeval_sub (&delta_wall_time,
|
||||
&now_wall_time, &m_start_wall_time);
|
||||
run_time_clock::duration cmd_time
|
||||
= run_time_clock::now () - m_start_cpu_time;
|
||||
|
||||
steady_clock::duration wall_time
|
||||
= steady_clock::now () - m_start_wall_time;
|
||||
/* Subtract time spend in prompt_for_continue from walltime. */
|
||||
wait_time = get_prompt_for_continue_wait_time ();
|
||||
timeval_sub (&delta_wall_time, &delta_wall_time, &wait_time);
|
||||
wall_time -= get_prompt_for_continue_wait_time ();
|
||||
|
||||
printf_unfiltered (!m_msg_type
|
||||
? _("Startup time: %ld.%06ld (cpu), %ld.%06ld (wall)\n")
|
||||
: _("Command execution time: %ld.%06ld (cpu), %ld.%06ld (wall)\n"),
|
||||
cmd_time / 1000000, cmd_time % 1000000,
|
||||
(long) delta_wall_time.tv_sec,
|
||||
(long) delta_wall_time.tv_usec);
|
||||
? _("Startup time: %.6f (cpu), %.6f (wall)\n")
|
||||
: _("Command execution time: %.6f (cpu), %.6f (wall)\n"),
|
||||
duration<double> (cmd_time).count (),
|
||||
duration<double> (wall_time).count ());
|
||||
}
|
||||
|
||||
if (m_space_enabled && per_command_space)
|
||||
@ -892,8 +887,10 @@ scoped_command_stats::scoped_command_stats (bool msg_type)
|
||||
|
||||
if (msg_type == 0 || per_command_time)
|
||||
{
|
||||
m_start_cpu_time = get_run_time ();
|
||||
gettimeofday (&m_start_wall_time, NULL);
|
||||
using namespace std::chrono;
|
||||
|
||||
m_start_cpu_time = run_time_clock::now ();
|
||||
m_start_wall_time = steady_clock::now ();
|
||||
m_time_enabled = 1;
|
||||
}
|
||||
else
|
||||
|
@ -19,6 +19,9 @@
|
||||
#ifndef MAINT_H
|
||||
#define MAINT_H
|
||||
|
||||
#include "run-time-clock.h"
|
||||
#include <chrono>
|
||||
|
||||
extern void set_per_command_time (int);
|
||||
|
||||
extern void set_per_command_space (int);
|
||||
@ -48,8 +51,8 @@ class scoped_command_stats
|
||||
int m_time_enabled : 1;
|
||||
int m_space_enabled : 1;
|
||||
int m_symtab_enabled : 1;
|
||||
long m_start_cpu_time;
|
||||
struct timeval m_start_wall_time;
|
||||
run_time_clock::time_point m_start_cpu_time;
|
||||
std::chrono::steady_clock::time_point m_start_wall_time;
|
||||
long m_start_space;
|
||||
/* Total number of symtabs (over all objfiles). */
|
||||
int m_start_nr_symtabs;
|
||||
|
@ -56,15 +56,8 @@
|
||||
#include "observer.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include "gdb_sys_time.h"
|
||||
|
||||
#if defined HAVE_SYS_RESOURCE_H
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETRUSAGE
|
||||
struct rusage rusage;
|
||||
#endif
|
||||
#include "run-time-clock.h"
|
||||
#include <chrono>
|
||||
|
||||
enum
|
||||
{
|
||||
@ -2169,7 +2162,7 @@ mi_execute_command (const char *cmd, int from_tty)
|
||||
|
||||
if (do_timings)
|
||||
{
|
||||
command->cmd_start = XNEW (struct mi_timestamp);
|
||||
command->cmd_start = new mi_timestamp ();
|
||||
timestamp (command->cmd_start);
|
||||
}
|
||||
|
||||
@ -2390,8 +2383,8 @@ mi_load_progress (const char *section_name,
|
||||
unsigned long total_sent,
|
||||
unsigned long grand_total)
|
||||
{
|
||||
struct timeval time_now, delta, update_threshold;
|
||||
static struct timeval last_update;
|
||||
using namespace std::chrono;
|
||||
static steady_clock::time_point last_update;
|
||||
static char *previous_sect_name = NULL;
|
||||
int new_section;
|
||||
struct ui_out *saved_uiout;
|
||||
@ -2416,19 +2409,6 @@ mi_load_progress (const char *section_name,
|
||||
|
||||
uiout = current_uiout;
|
||||
|
||||
update_threshold.tv_sec = 0;
|
||||
update_threshold.tv_usec = 500000;
|
||||
gettimeofday (&time_now, NULL);
|
||||
|
||||
delta.tv_usec = time_now.tv_usec - last_update.tv_usec;
|
||||
delta.tv_sec = time_now.tv_sec - last_update.tv_sec;
|
||||
|
||||
if (delta.tv_usec < 0)
|
||||
{
|
||||
delta.tv_sec -= 1;
|
||||
delta.tv_usec += 1000000L;
|
||||
}
|
||||
|
||||
new_section = (previous_sect_name ?
|
||||
strcmp (previous_sect_name, section_name) : 1);
|
||||
if (new_section)
|
||||
@ -2451,13 +2431,12 @@ mi_load_progress (const char *section_name,
|
||||
gdb_flush (mi->raw_stdout);
|
||||
}
|
||||
|
||||
if (delta.tv_sec >= update_threshold.tv_sec &&
|
||||
delta.tv_usec >= update_threshold.tv_usec)
|
||||
steady_clock::time_point time_now = steady_clock::now ();
|
||||
if (time_now - last_update > milliseconds (500))
|
||||
{
|
||||
struct cleanup *cleanup_tuple;
|
||||
|
||||
last_update.tv_sec = time_now.tv_sec;
|
||||
last_update.tv_usec = time_now.tv_usec;
|
||||
last_update = time_now;
|
||||
if (current_token)
|
||||
fputs_unfiltered (current_token, mi->raw_stdout);
|
||||
fputs_unfiltered ("+download", mi->raw_stdout);
|
||||
@ -2480,23 +2459,10 @@ mi_load_progress (const char *section_name,
|
||||
static void
|
||||
timestamp (struct mi_timestamp *tv)
|
||||
{
|
||||
gettimeofday (&tv->wallclock, NULL);
|
||||
#ifdef HAVE_GETRUSAGE
|
||||
getrusage (RUSAGE_SELF, &rusage);
|
||||
tv->utime.tv_sec = rusage.ru_utime.tv_sec;
|
||||
tv->utime.tv_usec = rusage.ru_utime.tv_usec;
|
||||
tv->stime.tv_sec = rusage.ru_stime.tv_sec;
|
||||
tv->stime.tv_usec = rusage.ru_stime.tv_usec;
|
||||
#else
|
||||
{
|
||||
long usec = get_run_time ();
|
||||
using namespace std::chrono;
|
||||
|
||||
tv->utime.tv_sec = usec/1000000L;
|
||||
tv->utime.tv_usec = usec - 1000000L*tv->utime.tv_sec;
|
||||
tv->stime.tv_sec = 0;
|
||||
tv->stime.tv_usec = 0;
|
||||
}
|
||||
#endif
|
||||
tv->wallclock = steady_clock::now ();
|
||||
run_time_clock::now (tv->utime, tv->stime);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2517,23 +2483,20 @@ mi_print_timing_maybe (struct ui_file *file)
|
||||
print_diff_now (file, current_command_ts);
|
||||
}
|
||||
|
||||
static long
|
||||
timeval_diff (struct timeval start, struct timeval end)
|
||||
{
|
||||
return ((end.tv_sec - start.tv_sec) * 1000000L)
|
||||
+ (end.tv_usec - start.tv_usec);
|
||||
}
|
||||
|
||||
static void
|
||||
print_diff (struct ui_file *file, struct mi_timestamp *start,
|
||||
struct mi_timestamp *end)
|
||||
{
|
||||
using namespace std::chrono;
|
||||
|
||||
duration<double> wallclock = end->wallclock - start->wallclock;
|
||||
duration<double> utime = end->utime - start->utime;
|
||||
duration<double> stime = end->stime - start->stime;
|
||||
|
||||
fprintf_unfiltered
|
||||
(file,
|
||||
",time={wallclock=\"%0.5f\",user=\"%0.5f\",system=\"%0.5f\"}",
|
||||
timeval_diff (start->wallclock, end->wallclock) / 1000000.0,
|
||||
timeval_diff (start->utime, end->utime) / 1000000.0,
|
||||
timeval_diff (start->stime, end->stime) / 1000000.0);
|
||||
wallclock.count (), utime.count (), stime.count ());
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -20,15 +20,17 @@
|
||||
#ifndef MI_PARSE_H
|
||||
#define MI_PARSE_H
|
||||
|
||||
#include "gdb_sys_time.h"
|
||||
#include "run-time-clock.h"
|
||||
#include <chrono>
|
||||
|
||||
/* MI parser */
|
||||
|
||||
/* Timestamps for current command and last asynchronous command. */
|
||||
struct mi_timestamp {
|
||||
struct timeval wallclock;
|
||||
struct timeval utime;
|
||||
struct timeval stime;
|
||||
struct mi_timestamp
|
||||
{
|
||||
std::chrono::steady_clock::time_point wallclock;
|
||||
user_cpu_time_clock::time_point utime;
|
||||
system_cpu_time_clock::time_point stime;
|
||||
};
|
||||
|
||||
enum mi_command_type
|
||||
|
@ -61,8 +61,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
#include "gdb_sys_time.h"
|
||||
#include <chrono>
|
||||
|
||||
#include "psymtab.h"
|
||||
|
||||
@ -2066,11 +2065,15 @@ clear_memory_write_data (void *arg)
|
||||
VEC_free (memory_write_request_s, vec);
|
||||
}
|
||||
|
||||
static void print_transfer_performance (struct ui_file *stream,
|
||||
unsigned long data_count,
|
||||
unsigned long write_count,
|
||||
std::chrono::steady_clock::duration d);
|
||||
|
||||
void
|
||||
generic_load (const char *args, int from_tty)
|
||||
{
|
||||
bfd *loadfile_bfd;
|
||||
struct timeval start_time, end_time;
|
||||
char *filename;
|
||||
struct cleanup *old_cleanups = make_cleanup (null_cleanup, 0);
|
||||
struct load_section_data cbdata;
|
||||
@ -2131,13 +2134,15 @@ generic_load (const char *args, int from_tty)
|
||||
|
||||
bfd_map_over_sections (loadfile_bfd, load_section_callback, &cbdata);
|
||||
|
||||
gettimeofday (&start_time, NULL);
|
||||
using namespace std::chrono;
|
||||
|
||||
steady_clock::time_point start_time = steady_clock::now ();
|
||||
|
||||
if (target_write_memory_blocks (cbdata.requests, flash_discard,
|
||||
load_progress) != 0)
|
||||
error (_("Load failed"));
|
||||
|
||||
gettimeofday (&end_time, NULL);
|
||||
steady_clock::time_point end_time = steady_clock::now ();
|
||||
|
||||
entry = bfd_get_start_address (loadfile_bfd);
|
||||
entry = gdbarch_addr_bits_remove (target_gdbarch (), entry);
|
||||
@ -2160,32 +2165,32 @@ generic_load (const char *args, int from_tty)
|
||||
|
||||
print_transfer_performance (gdb_stdout, total_progress.data_count,
|
||||
total_progress.write_count,
|
||||
&start_time, &end_time);
|
||||
end_time - start_time);
|
||||
|
||||
do_cleanups (old_cleanups);
|
||||
}
|
||||
|
||||
/* Report how fast the transfer went. */
|
||||
/* Report on STREAM the performance of a memory transfer operation,
|
||||
such as 'load'. DATA_COUNT is the number of bytes transferred.
|
||||
WRITE_COUNT is the number of separate write operations, or 0, if
|
||||
that information is not available. TIME is how long the operation
|
||||
lasted. */
|
||||
|
||||
void
|
||||
static void
|
||||
print_transfer_performance (struct ui_file *stream,
|
||||
unsigned long data_count,
|
||||
unsigned long write_count,
|
||||
const struct timeval *start_time,
|
||||
const struct timeval *end_time)
|
||||
std::chrono::steady_clock::duration time)
|
||||
{
|
||||
ULONGEST time_count;
|
||||
using namespace std::chrono;
|
||||
struct ui_out *uiout = current_uiout;
|
||||
|
||||
/* Compute the elapsed time in milliseconds, as a tradeoff between
|
||||
accuracy and overflow. */
|
||||
time_count = (end_time->tv_sec - start_time->tv_sec) * 1000;
|
||||
time_count += (end_time->tv_usec - start_time->tv_usec) / 1000;
|
||||
milliseconds ms = duration_cast<milliseconds> (time);
|
||||
|
||||
ui_out_text (uiout, "Transfer rate: ");
|
||||
if (time_count > 0)
|
||||
if (ms.count () > 0)
|
||||
{
|
||||
unsigned long rate = ((ULONGEST) data_count * 1000) / time_count;
|
||||
unsigned long rate = ((ULONGEST) data_count * 1000) / ms.count ();
|
||||
|
||||
if (ui_out_is_mi_like_p (uiout))
|
||||
{
|
||||
|
58
gdb/utils.c
58
gdb/utils.c
@ -37,7 +37,6 @@
|
||||
#endif
|
||||
|
||||
#include <signal.h>
|
||||
#include "timeval-utils.h"
|
||||
#include "gdbcmd.h"
|
||||
#include "serial.h"
|
||||
#include "bfd.h"
|
||||
@ -61,8 +60,7 @@
|
||||
|
||||
#include "readline/readline.h"
|
||||
|
||||
#include "gdb_sys_time.h"
|
||||
#include <time.h>
|
||||
#include <chrono>
|
||||
|
||||
#include "gdb_usleep.h"
|
||||
#include "interps.h"
|
||||
@ -98,7 +96,7 @@ static void set_width (void);
|
||||
Modified in prompt_for_continue and defaulted_query.
|
||||
Used in report_command_stats. */
|
||||
|
||||
static struct timeval prompt_for_continue_wait_time;
|
||||
static std::chrono::steady_clock::duration prompt_for_continue_wait_time;
|
||||
|
||||
/* A flag indicating whether to timestamp debugging messages. */
|
||||
|
||||
@ -1184,9 +1182,6 @@ defaulted_query (const char *ctlstr, const char defchar, va_list args)
|
||||
int def_value;
|
||||
char def_answer, not_def_answer;
|
||||
char *y_string, *n_string, *question, *prompt;
|
||||
/* Used to add duration we waited for user to respond to
|
||||
prompt_for_continue_wait_time. */
|
||||
struct timeval prompt_started, prompt_ended, prompt_delta;
|
||||
struct cleanup *old_chain;
|
||||
|
||||
/* Set up according to which answer is the default. */
|
||||
@ -1261,8 +1256,10 @@ defaulted_query (const char *ctlstr, const char defchar, va_list args)
|
||||
annotation_level > 1 ? "\n\032\032query\n" : "");
|
||||
make_cleanup (xfree, prompt);
|
||||
|
||||
/* Used for calculating time spend waiting for user. */
|
||||
gettimeofday (&prompt_started, NULL);
|
||||
/* Used to add duration we waited for user to respond to
|
||||
prompt_for_continue_wait_time. */
|
||||
using namespace std::chrono;
|
||||
steady_clock::time_point prompt_started = steady_clock::now ();
|
||||
|
||||
prepare_to_handle_input ();
|
||||
|
||||
@ -1307,10 +1304,7 @@ defaulted_query (const char *ctlstr, const char defchar, va_list args)
|
||||
}
|
||||
|
||||
/* Add time spend in this routine to prompt_for_continue_wait_time. */
|
||||
gettimeofday (&prompt_ended, NULL);
|
||||
timeval_sub (&prompt_delta, &prompt_ended, &prompt_started);
|
||||
timeval_add (&prompt_for_continue_wait_time,
|
||||
&prompt_for_continue_wait_time, &prompt_delta);
|
||||
prompt_for_continue_wait_time += steady_clock::now () - prompt_started;
|
||||
|
||||
if (annotation_level > 1)
|
||||
printf_filtered (("\n\032\032post-query\n"));
|
||||
@ -1816,12 +1810,11 @@ prompt_for_continue (void)
|
||||
{
|
||||
char *ignore;
|
||||
char cont_prompt[120];
|
||||
struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
|
||||
/* Used to add duration we waited for user to respond to
|
||||
prompt_for_continue_wait_time. */
|
||||
struct timeval prompt_started, prompt_ended, prompt_delta;
|
||||
struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
|
||||
|
||||
gettimeofday (&prompt_started, NULL);
|
||||
using namespace std::chrono;
|
||||
steady_clock::time_point prompt_started = steady_clock::now ();
|
||||
|
||||
if (annotation_level > 1)
|
||||
printf_unfiltered (("\n\032\032pre-prompt-for-continue\n"));
|
||||
@ -1844,10 +1837,7 @@ prompt_for_continue (void)
|
||||
make_cleanup (xfree, ignore);
|
||||
|
||||
/* Add time spend in this routine to prompt_for_continue_wait_time. */
|
||||
gettimeofday (&prompt_ended, NULL);
|
||||
timeval_sub (&prompt_delta, &prompt_ended, &prompt_started);
|
||||
timeval_add (&prompt_for_continue_wait_time,
|
||||
&prompt_for_continue_wait_time, &prompt_delta);
|
||||
prompt_for_continue_wait_time += steady_clock::now () - prompt_started;
|
||||
|
||||
if (annotation_level > 1)
|
||||
printf_unfiltered (("\n\032\032post-prompt-for-continue\n"));
|
||||
@ -1877,15 +1867,15 @@ prompt_for_continue (void)
|
||||
void
|
||||
reset_prompt_for_continue_wait_time (void)
|
||||
{
|
||||
static const struct timeval zero_timeval = { 0 };
|
||||
using namespace std::chrono;
|
||||
|
||||
prompt_for_continue_wait_time = zero_timeval;
|
||||
prompt_for_continue_wait_time = steady_clock::duration::zero ();
|
||||
}
|
||||
|
||||
/* Fetch the cumulative time spent in prompt_for_continue. */
|
||||
|
||||
struct timeval
|
||||
get_prompt_for_continue_wait_time (void)
|
||||
std::chrono::steady_clock::duration
|
||||
get_prompt_for_continue_wait_time ()
|
||||
{
|
||||
return prompt_for_continue_wait_time;
|
||||
}
|
||||
@ -2308,21 +2298,21 @@ vfprintf_unfiltered (struct ui_file *stream, const char *format, va_list args)
|
||||
old_cleanups = make_cleanup (xfree, linebuffer);
|
||||
if (debug_timestamp && stream == gdb_stdlog)
|
||||
{
|
||||
struct timeval tm;
|
||||
char *timestamp;
|
||||
using namespace std::chrono;
|
||||
int len, need_nl;
|
||||
|
||||
gettimeofday (&tm, NULL);
|
||||
steady_clock::time_point now = steady_clock::now ();
|
||||
seconds s = duration_cast<seconds> (now.time_since_epoch ());
|
||||
microseconds us = duration_cast<microseconds> (now.time_since_epoch () - s);
|
||||
|
||||
len = strlen (linebuffer);
|
||||
need_nl = (len > 0 && linebuffer[len - 1] != '\n');
|
||||
|
||||
timestamp = xstrprintf ("%ld:%ld %s%s",
|
||||
(long) tm.tv_sec, (long) tm.tv_usec,
|
||||
linebuffer,
|
||||
need_nl ? "\n": "");
|
||||
make_cleanup (xfree, timestamp);
|
||||
fputs_unfiltered (timestamp, stream);
|
||||
std::string timestamp = string_printf ("%ld.%06ld %s%s",
|
||||
(long) s.count (),
|
||||
(long) us.count (),
|
||||
linebuffer, need_nl ? "\n": "");
|
||||
fputs_unfiltered (timestamp.c_str (), stream);
|
||||
}
|
||||
else
|
||||
fputs_unfiltered (linebuffer, stream);
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include "exceptions.h"
|
||||
#include "common/scoped_restore.h"
|
||||
#include <chrono>
|
||||
|
||||
extern void initialize_utils (void);
|
||||
|
||||
@ -51,7 +52,7 @@ extern const char *gdb_bfd_errmsg (bfd_error_type error_tag, char **matching);
|
||||
/* Reset the prompt_for_continue clock. */
|
||||
void reset_prompt_for_continue_wait_time (void);
|
||||
/* Return the time spent in prompt_for_continue. */
|
||||
struct timeval get_prompt_for_continue_wait_time (void);
|
||||
std::chrono::steady_clock::duration get_prompt_for_continue_wait_time ();
|
||||
|
||||
/* Parsing utilites. */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user