From: Bart Van Assche Date: Sun, 20 Sep 2020 18:40:26 +0000 (-0700) Subject: gettime: Introduce fio_get_mono_time() X-Git-Tag: fio-3.24~21^2~7 X-Git-Url: https://git.kernel.dk/?p=fio.git;a=commitdiff_plain;h=69212fc41c0420f8caf272a0cc270194edbddfe7 gettime: Introduce fio_get_mono_time() 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 --- diff --git a/configure b/configure index 2d6588ae..3846881c 100755 --- 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 -#include -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 diff --git a/engines/posixaio.c b/engines/posixaio.c index 82c6aa65..135d088c 100644 --- a/engines/posixaio.c +++ b/engines/posixaio.c @@ -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)); diff --git a/gettime.c b/gettime.c index c3a4966b..6b202e8f 100644 --- 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; diff --git a/gettime.h b/gettime.h index c55f5cba..f1d619ad 100644 --- 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); diff --git a/helper_thread.c b/helper_thread.c index a2fb7c29..c5ca23e0 100644 --- a/helper_thread.c +++ b/helper_thread.c @@ -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;