Re: time: Should real time usage account discontinous jumps?

Petr Pisar <[email protected]> Wed, 11 Jan 2017 15:12:00 +0100
Newsgroups gmane.comp.gnu.utils.bugs
Message-ID <[email protected]>
On Fri, Dec 02, 2016 at 03:38:19PM +0100, Petr Pisar wrote:
> On Thu, Dec 01, 2016 at 08:51:55AM -0600, Eric Blake wrote:
> > On 12/01/2016 12:17 AM, Petr Pisar wrote:
> > 
> > > Please excuse resurrecting this old story. I forgot it and now I found it.
> > > Two patches are attached that should implement the idea discuessed in this
> > > thread.
> > > 
> > > The first patch corrects configure.in because the old syntax does not work
> > > with my autotools anymore.
> > 
> > If you're going to modernize configure.in, start by renaming it to
> > configure.ac.
> > 
> I worried it would be too brave for so old code. But nevertheless here is the
> rename.
> 
I found the the patched code cannot detect clock_gettime(2) on systems with
glibc-2.12. That's because the syscall wrapper is provided by "rt" library
there. Attached is a new patch set that fixes even this flaw.
0001-Modernize-configure.in.patch (text/plain, 3.7 KB)
From 73e60377a708ea6d9e45c981b9b131df4d93e511 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <[email protected]>
Date: Wed, 30 Nov 2016 17:38:37 +0100
Subject: [PATCH 1/2] Modernize configure.in
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

After editting configure.in and running autoreconf with autoconf-2.69
and automake-1.15, make command failed because configure.in did not
hook Automake. This patch allows to regenerate the scripts with
contemporary autotools.

Signed-off-by: Petr Písař <[email protected]>
---
 INSTALL      |  4 ++--
 configure.ac | 39 +++++++++++++++++++++++++++++++++++++++
 configure.in | 42 ------------------------------------------
 3 files changed, 41 insertions(+), 44 deletions(-)
 create mode 100644 configure.ac
 delete mode 100644 configure.in

diff --git a/INSTALL b/INSTALL
index a2c8722..0cbcb35 100644
--- a/INSTALL
+++ b/INSTALL
@@ -19,8 +19,8 @@ diffs or instructions to the address given in the `README' so they can
 be considered for the next release.  If at some point `config.cache'
 contains results you don't want to keep, you may remove or edit it.
 
-   The file `configure.in' is used to create `configure' by a program
-called `autoconf'.  You only need `configure.in' if you want to change
+   The file `configure.ac' is used to create `configure' by a program
+called `autoconf'.  You only need `configure.ac' if you want to change
 it or regenerate `configure' using a newer version of `autoconf'.
 
 The simplest way to compile this package is:
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..2380b76
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,39 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT([time], [1.7])
+AM_INIT_AUTOMAKE()
+
+AC_ARG_PROGRAM
+
+dnl Checks for programs.
+AC_PROG_CC
+AC_PROG_CPP
+AC_PROG_INSTALL
+
+dnl Checks for header files.
+AC_HEADER_STDC
+AC_HEADER_SYS_WAIT
+AC_CHECK_HEADERS(unistd.h string.h sys/rusage.h)
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_TYPE_PID_T
+AC_TYPE_SIZE_T
+AC_TYPE_SIGNAL
+
+AC_MSG_CHECKING(for struct timeval in sys/time.h)
+AC_EGREP_HEADER(tv_usec, sys/time.h, have_tv=yes, have_tv=no)
+AC_MSG_RESULT($have_tv)
+test $have_tv = yes && AC_DEFINE(HAVE_TIMEVAL)
+
+dnl Checks for library functions.
+AC_FUNC_VPRINTF
+AC_FUNC_WAIT3
+AC_CHECK_FUNCS(strerror)
+
+AC_MSG_CHECKING(for getpagesize)
+AC_TRY_LINK([#include <sys/param.h>],
+[getpagesize();], have_gp=yes, have_gp=no)
+AC_MSG_RESULT($have_gp)
+test $have_gp = yes && AC_DEFINE(HAVE_GETPAGESIZE)
+
+AC_OUTPUT(Makefile)
diff --git a/configure.in b/configure.in
deleted file mode 100644
index 1531bad..0000000
--- a/configure.in
+++ /dev/null
@@ -1,42 +0,0 @@
-dnl Process this file with autoconf to produce a configure script.
-AC_INIT(time.c)
-VERSION=1.7
-AC_SUBST(VERSION)
-PACKAGE=time
-AC_SUBST(PACKAGE)
-
-AC_ARG_PROGRAM
-
-dnl Checks for programs.
-AC_PROG_CC
-AC_PROG_CPP
-AC_PROG_INSTALL
-
-dnl Checks for header files.
-AC_HEADER_STDC
-AC_HEADER_SYS_WAIT
-AC_CHECK_HEADERS(unistd.h string.h sys/rusage.h)
-
-dnl Checks for typedefs, structures, and compiler characteristics.
-AC_C_CONST
-AC_TYPE_PID_T
-AC_TYPE_SIZE_T
-AC_TYPE_SIGNAL
-
-AC_MSG_CHECKING(for struct timeval in sys/time.h)
-AC_EGREP_HEADER(tv_usec, sys/time.h, have_tv=yes, have_tv=no)
-AC_MSG_RESULT($have_tv)
-test $have_tv = yes && AC_DEFINE(HAVE_TIMEVAL)
-
-dnl Checks for library functions.
-AC_FUNC_VPRINTF
-AC_FUNC_WAIT3
-AC_CHECK_FUNCS(strerror)
-
-AC_MSG_CHECKING(for getpagesize)
-AC_TRY_LINK([#include <sys/param.h>],
-[getpagesize();], have_gp=yes, have_gp=no)
-AC_MSG_RESULT($have_gp)
-test $have_gp = yes && AC_DEFINE(HAVE_GETPAGESIZE)
-
-AC_OUTPUT(Makefile)
-- 
2.7.4
0002-Prefer-clock_gettime-CLOCK_MONOTONIC.patch (text/plain, 2.8 KB)
From 0d9b55f773b13dc1d44651163888b6a5037a2c7d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <[email protected]>
Date: Wed, 30 Nov 2016 17:13:16 +0100
Subject: [PATCH 2/2] Prefer clock_gettime(CLOCK_MONOTONIC)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

gettimeofday() reports wrong elapsed real time if a time step was
inserted while running a program. This can happen on initial time
adjustment from NTP server or by manual adjustement by date command.

This patch uses clock_gettime(CLOCK_MONOTONIC) instead (if available)
that does not suffer from the issue.

<http://lists.gnu.org/archive/html/bug-gnu-utils/2013-09/msg00008.html>

Signed-off-by: Petr Písař <[email protected]>
---
 configure.ac |  2 ++
 resuse.c     | 27 +++++++++++++++++++++++++--
 2 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/configure.ac b/configure.ac
index 2380b76..558d112 100644
--- a/configure.ac
+++ b/configure.ac
@@ -29,6 +29,8 @@ dnl Checks for library functions.
 AC_FUNC_VPRINTF
 AC_FUNC_WAIT3
 AC_CHECK_FUNCS(strerror)
+AC_SEARCH_LIBS(clock_gettime, [rt])
+test "$ac_cv_search_clock_gettime" != "no" && AC_DEFINE(HAVE_CLOCK_GETTIME)
 
 AC_MSG_CHECKING(for getpagesize)
 AC_TRY_LINK([#include <sys/param.h>],
diff --git a/resuse.c b/resuse.c
index 4133941..da0da64 100644
--- a/resuse.c
+++ b/resuse.c
@@ -23,7 +23,14 @@
 #include "wait.h"
 #include "port.h"
 
-#if !HAVE_WAIT3
+#if HAVE_WAIT3
+# if HAVE_CLOCK_GETTIME
+#  ifndef _POSIX_C_SOURCE
+#   define _POSIX_C_SOURCE 199309L
+#  endif
+#  include <time.h>
+# endif
+#else
 # include <sys/times.h>
 # ifndef HZ
 #  include <sys/param.h>
@@ -48,7 +55,14 @@ resuse_start (resp)
      RESUSE *resp;
 {
 #if HAVE_WAIT3
+#if HAVE_CLOCK_GETTIME
+  struct timespec res;
+  clock_gettime(CLOCK_MONOTONIC, &res);
+  resp->start.tv_sec = res.tv_sec;
+  resp->start.tv_usec = res.tv_nsec / 1000;
+#else
   gettimeofday (&resp->start, (struct timezone *) 0);
+#endif /* !HAVE_CLOCK_GETTIME */
 #else
   long value;
   struct tms tms;
@@ -56,7 +70,7 @@ resuse_start (resp)
   value = times (&tms);
   resp->start.tv_sec = value / HZ;
   resp->start.tv_usec = value % HZ * (1000000 / HZ);
-#endif
+#endif /* !HAVE_WAIT3 */
 }
 
 /* Wait for and fill in data on child process PID.
@@ -76,6 +90,9 @@ resuse_end (pid, resp)
   int status;
 
 #if HAVE_WAIT3
+#if HAVE_CLOCK_GETTIME
+  struct timespec res;
+#endif
   pid_t caught;
 
   /* Ignore signals, but don't ignore the children.  When wait3
@@ -86,7 +103,13 @@ resuse_end (pid, resp)
 	return 0;
     }
 
+#if HAVE_CLOCK_GETTIME
+  clock_gettime(CLOCK_MONOTONIC, &res);
+  resp->elapsed.tv_sec = res.tv_sec;
+  resp->elapsed.tv_usec = res.tv_nsec / 1000;
+#else
   gettimeofday (&resp->elapsed, (struct timezone *) 0);
+#endif
 #else  /* !HAVE_WAIT3 */
   long value;
   struct tms tms;
-- 
2.7.4
signature.asc (application/pgp-signature, 213 B)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2

iF4EABEIAAYFAlh2PSUACgkQEsnFx2fG+qJG5wD8DpWiQg9uxCwHhLdlGQIeW12t
9l/7cm4S5g4oZ0PfwdcBAJI6myeihO39EJIchxYdBQIkdUE9FwIaIu/G5avV/82h
=5CoQ
-----END PGP SIGNATURE-----