changeset 39916:dbcdcd1db895

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.
author Akim Demaille <akim.demaille@gmail.com>
date Fri, 12 Oct 2018 06:46:09 +0200
parents 6ad3d081a5ab
children 5f0e12c5ef27
files ChangeLog lib/timevar.c lib/timevar.h lib/xtime.h modules/timevar
diffstat 5 files changed, 61 insertions(+), 41 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sun Oct 14 09:21:24 2018 +0200
+++ b/ChangeLog	Fri Oct 12 06:46:09 2018 +0200
@@ -1,3 +1,21 @@
+2018-10-14  Akim Demaille  <akim@lrde.epita.fr>
+
+	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  <bruno@clisp.org>
 
 	wcsnrtombs: Work around Solaris 11.4 bug.
--- a/lib/timevar.c	Sun Oct 14 09:21:24 2018 +0200
+++ b/lib/timevar.c	Fri Oct 12 06:46:09 2018 +0200
@@ -30,6 +30,7 @@
 #include <sys/time.h>
 #include <sys/times.h>
 
+#include "gethrxtime.h"
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
 #include "xalloc.h"
@@ -101,13 +102,20 @@
   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 @@
            "", _("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);
 }
--- a/lib/timevar.h	Sun Oct 14 09:21:24 2018 +0200
+++ b/lib/timevar.h	Fri Oct 12 06:46:09 2018 +0200
@@ -23,6 +23,8 @@
 
 # include <stdio.h>
 
+# include "xtime.h"
+
 # ifdef  __cplusplus
 extern "C" {
 # endif
@@ -58,14 +60,14 @@
 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
--- a/lib/xtime.h	Sun Oct 14 09:21:24 2018 +0200
+++ b/lib/xtime.h	Fri Oct 12 06:46:09 2018 +0200
@@ -50,10 +50,13 @@
 #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
--- a/modules/timevar	Sun Oct 14 09:21:24 2018 +0200
+++ b/modules/timevar	Fri Oct 12 06:46:09 2018 +0200
@@ -6,12 +6,12 @@
 lib/timevar.c
 
 Depends-on:
+gethrxtime
 getrusage
 gettext-h
 stdlib
 sys_time
 sys_times
-times
 xalloc
 
 Makefile.am:
@@ -20,6 +20,10 @@
 Include:
 "timevar.h"
 
+Link:
+$(LIB_GETHRXTIME)
+$(LTLIBINTL) when linking with libtool, $(LIBINTL) otherwise
+
 License:
 GPLv3+