gettime: Introduce fio_get_mono_time()
authorBart Van Assche <bvanassche@acm.org>
Sun, 20 Sep 2020 18:40:26 +0000 (11:40 -0700)
committerBart Van Assche <bvanassche@acm.org>
Sun, 20 Sep 2020 23:09:30 +0000 (16:09 -0700)
Introduce a new function for querying the monotonic clock, something that
is necessary in every context where relative time is measured and where
wall clock time jumps should have no effect. Remove fill_clock_gettime()
since the only contexts where CLOCK_MONOTONIC_RAW are used are
get_cycles_per_msec() and --clocksource=clock_gettime. I think both contexts
should use CLOCK_MONOTONIC instead of its raw variant such that the values
read from the clock are frequency adjusted (a computer clock crystal can
deviate up to 500 ppm from its nominal frequency).

This patch improves accuracy of the helper_thread code on Darwin. Darwin
supports CLOCK_MONOTONIC but not pthread_condattr_setclock(). In other
words, this patch causes the helper thread code to switch from the
real-time clock to the monotonic clock on Darwin.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
configure
engines/posixaio.c
gettime.c
gettime.h
helper_thread.c

index 2d6588ae3d61cce2a25f49e2604c29566f133615..3846881c54e54f468d2aeec9f9ec2ffebcb6f27b 100755 (executable)
--- a/configure
+++ b/configure
@@ -1104,26 +1104,6 @@ EOF
 fi
 print_config "CLOCK_MONOTONIC" "$clock_monotonic"
 
-##########################################
-# CLOCK_MONOTONIC_RAW probe
-if test "$clock_monotonic_raw" != "yes" ; then
-  clock_monotonic_raw="no"
-fi
-if test "$clock_gettime" = "yes" ; then
-  cat > $TMPC << EOF
-#include <stdio.h>
-#include <time.h>
-int main(int argc, char **argv)
-{
-  return clock_gettime(CLOCK_MONOTONIC_RAW, NULL);
-}
-EOF
-  if compile_prog "" "$LIBS" "clock monotonic"; then
-      clock_monotonic_raw="yes"
-  fi
-fi
-print_config "CLOCK_MONOTONIC_RAW" "$clock_monotonic_raw"
-
 ##########################################
 # clockid_t probe
 if test "$clockid_t" != "yes" ; then
index 82c6aa65b82fbada14192b32b6c8b29a03e03646..135d088c7a029ef1ac3e55192d724d147875bbe7 100644 (file)
@@ -17,47 +17,14 @@ struct posixaio_data {
        unsigned int queued;
 };
 
-static int fill_timespec(struct timespec *ts)
+static unsigned long long ts_utime_since_now(const struct timespec *start)
 {
-#ifdef CONFIG_CLOCK_GETTIME
-#ifdef CONFIG_CLOCK_MONOTONIC
-       clockid_t clk = CLOCK_MONOTONIC;
-#else
-       clockid_t clk = CLOCK_REALTIME;
-#endif
-       if (!clock_gettime(clk, ts))
-               return 0;
-
-       perror("clock_gettime");
-       return 1;
-#else
-       struct timeval tv;
-
-       gettimeofday(&tv, NULL);
-       ts->tv_sec = tv.tv_sec;
-       ts->tv_nsec = tv.tv_usec * 1000;
-       return 0;
-#endif
-}
-
-static unsigned long long ts_utime_since_now(struct timespec *t)
-{
-       long long sec, nsec;
        struct timespec now;
 
-       if (fill_timespec(&now))
+       if (fio_get_mono_time(&now) < 0)
                return 0;
-       
-       sec = now.tv_sec - t->tv_sec;
-       nsec = now.tv_nsec - t->tv_nsec;
-       if (sec > 0 && nsec < 0) {
-               sec--;
-               nsec += 1000000000;
-       }
 
-       sec *= 1000000;
-       nsec /= 1000;
-       return sec + nsec;
+       return utime_since(start, &now);
 }
 
 static int fio_posixaio_cancel(struct thread_data fio_unused *td,
@@ -102,7 +69,7 @@ static int fio_posixaio_getevents(struct thread_data *td, unsigned int min,
        unsigned int r;
        int i;
 
-       if (t && !fill_timespec(&start))
+       if (t && fio_get_mono_time(&start) == 0)
                have_timeout = 1;
        else
                memset(&start, 0, sizeof(start));
index c3a4966bfa71ea14f812c459dab198ee4b7d6020..6b202e8f5e29239b381d0c99391bb080f2eac948 100644 (file)
--- a/gettime.c
+++ b/gettime.c
@@ -127,18 +127,33 @@ static void fio_init gtod_init(void)
 
 #endif /* FIO_DEBUG_TIME */
 
-#ifdef CONFIG_CLOCK_GETTIME
-static int fill_clock_gettime(struct timespec *ts)
+/*
+ * Queries the value of the monotonic clock if a monotonic clock is available
+ * or the wall clock time if no monotonic clock is available. Returns 0 if
+ * querying the clock succeeded or -1 if querying the clock failed.
+ */
+int fio_get_mono_time(struct timespec *ts)
 {
-#if defined(CONFIG_CLOCK_MONOTONIC_RAW)
-       return clock_gettime(CLOCK_MONOTONIC_RAW, ts);
-#elif defined(CONFIG_CLOCK_MONOTONIC)
-       return clock_gettime(CLOCK_MONOTONIC, ts);
+       int ret;
+
+#ifdef CONFIG_CLOCK_GETTIME
+#if defined(CONFIG_CLOCK_MONOTONIC)
+       ret = clock_gettime(CLOCK_MONOTONIC, ts);
 #else
-       return clock_gettime(CLOCK_REALTIME, ts);
+       ret = clock_gettime(CLOCK_REALTIME, ts);
 #endif
-}
+#else
+       struct timeval tv;
+
+       ret = gettimeofday(&tv, NULL);
+       if (ret == 0) {
+               ts->tv_sec = tv.tv_sec;
+               ts->tv_nsec = tv.tv_usec * 1000;
+       }
 #endif
+       assert(ret <= 0);
+       return ret;
+}
 
 static void __fio_gettime(struct timespec *tp)
 {
@@ -155,8 +170,8 @@ static void __fio_gettime(struct timespec *tp)
 #endif
 #ifdef CONFIG_CLOCK_GETTIME
        case CS_CGETTIME: {
-               if (fill_clock_gettime(tp) < 0) {
-                       log_err("fio: clock_gettime fails\n");
+               if (fio_get_mono_time(tp) < 0) {
+                       log_err("fio: fio_get_mono_time() fails\n");
                        assert(0);
                }
                break;
index c55f5cba779f5269e6fbc6b96c1e85e419d40683..f1d619ad5bad5fc2b3dae6f60083b7ec2c291d61 100644 (file)
--- a/gettime.h
+++ b/gettime.h
@@ -16,6 +16,7 @@ enum fio_cs {
        CS_INVAL,
 };
 
+extern int fio_get_mono_time(struct timespec *);
 extern void fio_gettime(struct timespec *, void *);
 extern void fio_gtod_init(void);
 extern void fio_clock_init(void);
index a2fb7c29a0565884e96e9546a6967ee2de889181..c5ca23e0640197e07043697b0c3be125e6f78609 100644 (file)
@@ -169,11 +169,7 @@ static void *helper_thread_main(void *data)
        }
 #endif
 
-#ifdef CONFIG_PTHREAD_CONDATTR_SETCLOCK
-       clock_gettime(CLOCK_MONOTONIC, &ts);
-#else
-       clock_gettime(CLOCK_REALTIME, &ts);
-#endif
+       fio_get_mono_time(&ts);
        memcpy(&last_du, &ts, sizeof(ts));
        memcpy(&last_ss, &ts, sizeof(ts));
        memcpy(&last_si, &ts, sizeof(ts));
@@ -204,11 +200,7 @@ static void *helper_thread_main(void *data)
                                action = 0;
                }
 
-#ifdef CONFIG_PTHREAD_CONDATTR_SETCLOCK
-               clock_gettime(CLOCK_MONOTONIC, &ts);
-#else
-               clock_gettime(CLOCK_REALTIME, &ts);
-#endif
+               fio_get_mono_time(&ts);
 
                if (action == A_RESET) {
                        last_du = ts;