8cdaa02
From a3c400a8553b598bc2fd01eb0f63c5748b2147e1 Mon Sep 17 00:00:00 2001
87b2267
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
8cdaa02
Date: Wed, 8 Nov 2017 17:02:42 +0100
8cdaa02
Subject: [PATCH] Prefer clock_gettime(CLOCK_MONOTONIC)
87b2267
MIME-Version: 1.0
87b2267
Content-Type: text/plain; charset=UTF-8
87b2267
Content-Transfer-Encoding: 8bit
87b2267
87b2267
gettimeofday() reports wrong elapsed real time if a time step was
87b2267
inserted while running a program. This can happen on initial time
87b2267
adjustment from NTP server or by manual adjustement by date command.
87b2267
87b2267
This patch uses clock_gettime(CLOCK_MONOTONIC) instead (if available)
87b2267
that does not suffer from the issue.
87b2267
87b2267
<http://lists.gnu.org/archive/html/bug-gnu-utils/2013-09/msg00008.html>
87b2267
87b2267
Signed-off-by: Petr Písař <ppisar@redhat.com>
87b2267
---
8cdaa02
 configure.ac |  3 +++
8cdaa02
 src/resuse.c | 27 +++++++++++++++++++++++++--
8cdaa02
 2 files changed, 28 insertions(+), 2 deletions(-)
87b2267
87b2267
diff --git a/configure.ac b/configure.ac
8cdaa02
index ede8fd5..d2950bd 100644
87b2267
--- a/configure.ac
87b2267
+++ b/configure.ac
8cdaa02
@@ -72,6 +72,9 @@ dnl Checks for library functions.
87b2267
 AC_FUNC_VPRINTF
87b2267
 AC_FUNC_WAIT3
87b2267
 AC_CHECK_FUNCS(strerror)
17c7c00
+AC_SEARCH_LIBS(clock_gettime, [rt])
8cdaa02
+test "$ac_cv_search_clock_gettime" != "no" && \
8cdaa02
+    AC_DEFINE([HAVE_CLOCK_GETTIME], [1], [System provides clock_gettime() call])
87b2267
 
8cdaa02
 
8cdaa02
 # What memory units are reported by getrusage(2) ?
8cdaa02
diff --git a/src/resuse.c b/src/resuse.c
8cdaa02
index d2ab870..ec54863 100644
8cdaa02
--- a/src/resuse.c
8cdaa02
+++ b/src/resuse.c
8cdaa02
@@ -26,7 +26,14 @@
8cdaa02
 #include <sys/wait.h>
8cdaa02
 #include <sys/resource.h>
87b2267
 
87b2267
-#if !HAVE_WAIT3
87b2267
+#if HAVE_WAIT3
87b2267
+# if HAVE_CLOCK_GETTIME
87b2267
+#  ifndef _POSIX_C_SOURCE
87b2267
+#   define _POSIX_C_SOURCE 199309L
87b2267
+#  endif
87b2267
+#  include <time.h>
87b2267
+# endif
87b2267
+#else
87b2267
 # include <sys/times.h>
87b2267
 # ifndef HZ
87b2267
 #  include <sys/param.h>
8cdaa02
@@ -51,7 +58,14 @@ resuse_start (resp)
87b2267
      RESUSE *resp;
87b2267
 {
87b2267
 #if HAVE_WAIT3
87b2267
+#if HAVE_CLOCK_GETTIME
87b2267
+  struct timespec res;
87b2267
+  clock_gettime(CLOCK_MONOTONIC, &res;;
87b2267
+  resp->start.tv_sec = res.tv_sec;
87b2267
+  resp->start.tv_usec = res.tv_nsec / 1000;
87b2267
+#else
87b2267
   gettimeofday (&resp->start, (struct timezone *) 0);
87b2267
+#endif /* !HAVE_CLOCK_GETTIME */
87b2267
 #else
87b2267
   long value;
87b2267
   struct tms tms;
8cdaa02
@@ -59,7 +73,7 @@ resuse_start (resp)
87b2267
   value = times (&tms);
87b2267
   resp->start.tv_sec = value / HZ;
87b2267
   resp->start.tv_usec = value % HZ * (1000000 / HZ);
87b2267
-#endif
87b2267
+#endif /* !HAVE_WAIT3 */
87b2267
 }
87b2267
 
87b2267
 /* Wait for and fill in data on child process PID.
8cdaa02
@@ -79,6 +93,9 @@ resuse_end (pid, resp)
87b2267
   int status;
87b2267
 
87b2267
 #if HAVE_WAIT3
87b2267
+#if HAVE_CLOCK_GETTIME
87b2267
+  struct timespec res;
87b2267
+#endif
87b2267
   pid_t caught;
87b2267
 
87b2267
   /* Ignore signals, but don't ignore the children.  When wait3
8cdaa02
@@ -89,7 +106,13 @@ resuse_end (pid, resp)
87b2267
 	return 0;
87b2267
     }
87b2267
 
87b2267
+#if HAVE_CLOCK_GETTIME
87b2267
+  clock_gettime(CLOCK_MONOTONIC, &res;;
87b2267
+  resp->elapsed.tv_sec = res.tv_sec;
87b2267
+  resp->elapsed.tv_usec = res.tv_nsec / 1000;
87b2267
+#else
87b2267
   gettimeofday (&resp->elapsed, (struct timezone *) 0);
87b2267
+#endif
87b2267
 #else  /* !HAVE_WAIT3 */
87b2267
   long value;
87b2267
   struct tms tms;
87b2267
-- 
8cdaa02
2.13.6
87b2267