From 35f2540805c69edfbfcb7d00351d7a8293a5ff28 Mon Sep 17 00:00:00 2001
From: Paolo Capriotti <p.capriotti@gmail.com>
Date: Tue, 20 Mar 2012 11:57:28 +0000
Subject: [PATCH] Use monotonic clock in Select.c (#5865)

---
 rts/posix/Clock.h   |   32 ++++++++++++++++++++++++++++++++
 rts/posix/GetTime.c |   21 +++++++++------------
 rts/posix/Itimer.c  |   11 ++---------
 rts/posix/Select.c  |   14 +++++---------
 4 files changed, 48 insertions(+), 30 deletions(-)
 create mode 100644 rts/posix/Clock.h

diff --git a/rts/posix/Clock.h b/rts/posix/Clock.h
new file mode 100644
index 0000000..5062023
--- /dev/null
+++ b/rts/posix/Clock.h
@@ -0,0 +1,32 @@
+/* -----------------------------------------------------------------------------
+ *
+ * (c) The GHC Team, 2012
+ *
+ * Posix monotonic clock
+ *
+ * ---------------------------------------------------------------------------*/
+
+#ifndef POSIX_CLOCK_H
+#define POSIX_CLOCK_H
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#ifdef HAVE_TIME_H
+# include <time.h>
+#endif
+
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+
+#ifdef HAVE_CLOCK_GETTIME
+# ifdef _POSIX_MONOTONIC_CLOCK
+#  define CLOCK_ID CLOCK_MONOTONIC
+# else
+#  define CLOCK_ID CLOCK_REALTIME
+# endif
+#endif
+
+#endif /* POSIX_CLOCK_H */
diff --git a/rts/posix/GetTime.c b/rts/posix/GetTime.c
index 16511ce..4abc82f 100644
--- a/rts/posix/GetTime.c
+++ b/rts/posix/GetTime.c
@@ -11,23 +11,12 @@
 
 #include "Rts.h"
 #include "GetTime.h"
-
-#ifdef HAVE_TIME_H
-# include <time.h>
-#endif
-
-#ifdef HAVE_SYS_TIME_H
-# include <sys/time.h>
-#endif
+#include "Clock.h"
 
 #if HAVE_SYS_RESOURCE_H
 # include <sys/resource.h>
 #endif
 
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
 #ifdef HAVE_SYS_TIMES_H
 # include <sys/times.h>
 #endif
@@ -77,9 +66,17 @@ Time getProcessCPUTime(void)
 
 Time getProcessElapsedTime(void)
 {
+#ifdef HAVE_CLOCK_GETTIME
+    struct timespec ts;
+
+    clock_gettime(CLOCK_ID, &ts);
+    return SecondsToTime(ts.tv_sec) + NSToTime(ts.tv_nsec);
+#else
     struct timeval tv;
+
     gettimeofday(&tv, (struct timezone *) NULL);
     return SecondsToTime(tv.tv_sec) + USToTime(tv.tv_usec);
+#endif
 }
 
 void getProcessTimes(Time *user, Time *elapsed)
diff --git a/rts/posix/Itimer.c b/rts/posix/Itimer.c
index 13ba345..8c9b1f8 100644
--- a/rts/posix/Itimer.c
+++ b/rts/posix/Itimer.c
@@ -24,7 +24,7 @@
 #include "Itimer.h"
 #include "Proftimer.h"
 #include "Schedule.h"
-#include "Select.h"
+#include "Clock.h"
 
 /* As recommended in the autoconf manual */
 # ifdef TIME_WITH_SYS_TIME
@@ -123,7 +123,6 @@ initTicker (Time interval, TickProc handle_tick)
 #if defined(USE_TIMER_CREATE)
     {
         struct sigevent ev;
-        clockid_t clock;
 
         // Keep programs like valgrind happy
         memset(&ev, 0, sizeof(ev));
@@ -131,13 +130,7 @@ initTicker (Time interval, TickProc handle_tick)
         ev.sigev_notify = SIGEV_SIGNAL;
         ev.sigev_signo  = ITIMER_SIGNAL;
 
-#if defined(CLOCK_MONOTONIC)
-        clock = CLOCK_MONOTONIC;
-#else
-        clock = CLOCK_REALTIME;
-#endif
-
-        if (timer_create(clock, &ev, &timer) != 0) {
+        if (timer_create(CLOCK_ID, &ev, &timer) != 0) {
             sysErrorBelch("timer_create");
             stg_exit(EXIT_FAILURE);
         }
diff --git a/rts/posix/Select.c b/rts/posix/Select.c
index 013b374..cec721d 100644
--- a/rts/posix/Select.c
+++ b/rts/posix/Select.c
@@ -17,6 +17,7 @@
 #include "Select.h"
 #include "AwaitEvent.h"
 #include "Stats.h"
+#include "GetTime.h"
 
 # ifdef HAVE_SYS_SELECT_H
 #  include <sys/select.h>
@@ -26,16 +27,10 @@
 #  include <sys/types.h>
 # endif
 
-# ifdef HAVE_SYS_TIME_H
-#  include <sys/time.h>
-# endif
-
 #include <errno.h>
 #include <string.h>
 
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
+#include "Clock.h"
 
 #if !defined(THREADED_RTS)
 
@@ -53,7 +48,7 @@
  */
 LowResTime getourtimeofday(void)
 {
-  return TimeToUS(stat_getElapsedTime()) / 10000;
+  return TimeToUS(getProcessElapsedTime()) / 10000;
 }
 
 /* There's a clever trick here to avoid problems when the time wraps
@@ -246,8 +241,9 @@ awaitEvent(rtsBool wait)
 	  
 	  /* check for threads that need waking up 
 	   */
+
           wakeUpSleepingThreads(getourtimeofday());
-	  
+
 	  /* If new runnable threads have arrived, stop waiting for
 	   * I/O and run them.
 	   */
-- 
1.7.5.4

