From b159aa5da7e1aa7abeb2f77ba644aa164d25a46d Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Fri, 12 Oct 2018 06:46:09 +0200 Subject: timevar: use gethrxtime to get wall clock time clock_gettime is not portable. gethrxtime takes the best available option to get the wall clock time, including clock_gettime (monotonic clock), and gettime (non monotonic). Also, using xtime_t instead of float preserves the precision. Suggested by Bruno Haible. * lib/xtime.h (xtime_make): Handle overflows of nanoseconds. * modules/timevar (Depends-on): We need gethrxtime. We no longer use times(). (Link): Update. * lib/timevar.h (timevar_time_def): Use xtime_t. * lib/timevar.c (set_to_current_time): Use gethrxtime. (timevar_print): Instead of checking whether the timings themselves are large enough for the timevar to be printed, check the percentages. --- ChangeLog | 18 ++++++++++++++++ lib/timevar.c | 65 +++++++++++++++++++++++++-------------------------------- lib/timevar.h | 8 ++++--- lib/xtime.h | 5 ++++- modules/timevar | 6 +++++- 5 files changed, 61 insertions(+), 41 deletions(-) diff --git a/ChangeLog b/ChangeLog index cdc95adf32..c7defcff1a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2018-10-14 Akim Demaille + + timevar: use gethrxtime to get wall clock time + clock_gettime is not portable. gethrxtime takes the best available + option to get the wall clock time, including clock_gettime (monotonic + clock), and gettime (non monotonic). + Also, using xtime_t instead of float preserves the precision. + Suggested by Bruno Haible. + * lib/xtime.h (xtime_make): Handle overflows of nanoseconds. + * modules/timevar (Depends-on): We need gethrxtime. + We no longer use times(). + (Link): Update. + * lib/timevar.h (timevar_time_def): Use xtime_t. + * lib/timevar.c (set_to_current_time): Use gethrxtime. + (timevar_print): Instead of checking whether the timings themselves + are large enough for the timevar to be printed, check the percentages. + + 2018-10-14 Bruno Haible wcsnrtombs: Work around Solaris 11.4 bug. diff --git a/lib/timevar.c b/lib/timevar.c index 8b574e2777..038b4c52a5 100644 --- a/lib/timevar.c +++ b/lib/timevar.c @@ -30,6 +30,7 @@ #include #include +#include "gethrxtime.h" #include "gettext.h" #define _(msgid) gettext (msgid) #include "xalloc.h" @@ -101,13 +102,20 @@ set_to_current_time (struct timevar_time_def *now) if (!timevar_enabled) return; - struct rusage rusage; - getrusage (RUSAGE_SELF, &rusage); - now->user = rusage.ru_utime.tv_sec + rusage.ru_utime.tv_usec * 1e-6; - now->sys = rusage.ru_stime.tv_sec + rusage.ru_stime.tv_usec * 1e-6; - getrusage (RUSAGE_CHILDREN, &rusage); - now->user += rusage.ru_utime.tv_sec + rusage.ru_utime.tv_usec * 1e-6; - now->sys += rusage.ru_stime.tv_sec + rusage.ru_stime.tv_usec * 1e-6; + struct rusage self; + getrusage (RUSAGE_SELF, &self); + struct rusage chld; + getrusage (RUSAGE_CHILDREN, &chld); + + now->user = + xtime_make (self.ru_utime.tv_sec + chld.ru_utime.tv_sec, + (self.ru_utime.tv_usec + chld.ru_utime.tv_usec) * 1000); + + now->sys = + xtime_make (self.ru_stime.tv_sec + chld.ru_stime.tv_sec, + (self.ru_stime.tv_usec + chld.ru_stime.tv_usec) * 1000); + + now->wall = gethrxtime(); } /* Return the current time. */ @@ -310,49 +318,34 @@ timevar_print (FILE *fp) "", _("CPU user"), _("CPU system"), _("wall clock")); for (unsigned /* timevar_id_t */ id = 0; id < (unsigned) TIMEVAR_LAST; ++id) { - struct timevar_def *tv = &timevars[(timevar_id_t) id]; - const float tiny = 5e-3; - /* Don't print the total execution time here; that goes at the end. */ if ((timevar_id_t) id == tv_total) continue; /* Don't print timing variables that were never used. */ + struct timevar_def *tv = &timevars[(timevar_id_t) id]; if (!tv->used) continue; - /* Don't print timing variables if we're going to get a row of - zeroes. */ - if (tv->elapsed.user < tiny - && tv->elapsed.sys < tiny - && tv->elapsed.wall < tiny) + /* Percentages. */ + const int usr = total->user ? tv->elapsed.user * 100 / total->user : 0; + const int sys = total->sys ? tv->elapsed.sys * 100 / total->sys : 0; + const int wall = total->wall ? tv->elapsed.wall * 100 / total->wall : 0; + + /* Ignore insignificant lines. */ + if (!usr && !sys && !wall) continue; - /* The timing variable name. */ fprintf (fp, " %-22s", tv->name); - - /* Print user-mode time for this process. */ - fprintf (fp, "%8.3f (%2.0f%%)", - tv->elapsed.user, - (total->user == 0 ? 0 : tv->elapsed.user / total->user) * 100); - - /* Print system-mode time for this process. */ - fprintf (fp, "%8.3f (%2.0f%%)", - tv->elapsed.sys, - (total->sys == 0 ? 0 : tv->elapsed.sys / total->sys) * 100); - - /* Print wall clock time elapsed. */ - fprintf (fp, "%11.6f (%2.0f%%)", - tv->elapsed.wall, - (total->wall == 0 ? 0 : tv->elapsed.wall / total->wall) * 100); - - putc ('\n', fp); + fprintf (fp, "%8.3f (%2d%%)", tv->elapsed.user * 1e-9, usr); + fprintf (fp, "%8.3f (%2d%%)", tv->elapsed.sys * 1e-9, sys); + fprintf (fp, "%11.6f (%2d%%)\n", tv->elapsed.wall * 1e-9, wall); } /* Print total time. */ fprintf (fp, " %-22s", timevars[tv_total].name); - fprintf (fp, "%8.3f ", total->user); - fprintf (fp, "%8.3f ", total->sys); - fprintf (fp, "%11.6f\n", total->wall); + fprintf (fp, "%8.3f ", total->user * 1e-9); + fprintf (fp, "%8.3f ", total->sys * 1e-9); + fprintf (fp, "%11.6f\n", total->wall * 1e-9); } diff --git a/lib/timevar.h b/lib/timevar.h index ff443fed6b..cf9e0830d1 100644 --- a/lib/timevar.h +++ b/lib/timevar.h @@ -23,6 +23,8 @@ # include +# include "xtime.h" + # ifdef __cplusplus extern "C" { # endif @@ -58,14 +60,14 @@ extern "C" { struct timevar_time_def { /* User time in this process. */ - float user; + xtime_t user; /* System time (if applicable for this host platform) in this process. */ - float sys; + xtime_t sys; /* Wall clock time. */ - float wall; + xtime_t wall; }; /* An enumeration of timing variable identifiers. Constructed from diff --git a/lib/xtime.h b/lib/xtime.h index 7ed4b1cd4b..aabcee9e68 100644 --- a/lib/xtime.h +++ b/lib/xtime.h @@ -50,10 +50,13 @@ extern "C" { #endif /* Return an extended time value that contains S seconds and NS - nanoseconds, without any overflow checking. */ + nanoseconds. */ XTIME_INLINE xtime_t xtime_make (xtime_t s, long int ns) { + const long int giga = 1000 * 1000 * 1000; + s += ns / giga; + ns %= giga; if (XTIME_PRECISION == 1) return s; else diff --git a/modules/timevar b/modules/timevar index 354d1d211f..b2a12bb992 100644 --- a/modules/timevar +++ b/modules/timevar @@ -6,12 +6,12 @@ lib/timevar.h lib/timevar.c Depends-on: +gethrxtime getrusage gettext-h stdlib sys_time sys_times -times xalloc Makefile.am: @@ -20,6 +20,10 @@ lib_SOURCES += timevar.c timevar.def Include: "timevar.h" +Link: +$(LIB_GETHRXTIME) +$(LTLIBINTL) when linking with libtool, $(LIBINTL) otherwise + License: GPLv3+ -- cgit v1.2.1