X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=gettime.c;h=35d685e1576149974d5e77f18db2b1fb180f3a9e;hp=08d2d2b3b1205a56543ec6aef00e52b37711d622;hb=8425687edef1b2961a17bd58341686f7b598cf28;hpb=4780fa263c038646ab803b63f23f486b2b7b1140 diff --git a/gettime.c b/gettime.c index 08d2d2b3..35d685e1 100644 --- a/gettime.c +++ b/gettime.c @@ -5,22 +5,21 @@ #include #include #include +#include #include "fio.h" #include "smalloc.h" #include "hash.h" +#ifdef ARCH_HAVE_CPU_CLOCK static unsigned long cycles_per_usec; -static struct timeval last_tv; static unsigned long last_cycles; +#endif +static struct timeval last_tv; static int last_tv_valid; -static struct timeval *fio_tv; -int fio_gtod_offload = 0; -int fio_gtod_cpu = -1; - -enum fio_cs fio_clock_source = CS_GTOD; +enum fio_cs fio_clock_source = FIO_PREFERRED_CLOCK_SOURCE; #ifdef FIO_DEBUG_TIME @@ -137,7 +136,11 @@ void fio_gettime(struct timeval *tp, void fio_unused *caller) case CS_CGETTIME: { struct timespec ts; +#ifdef FIO_HAVE_CLOCK_MONOTONIC + if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0) { +#else if (clock_gettime(CLOCK_REALTIME, &ts) < 0) { +#endif log_err("fio: clock_gettime fails\n"); assert(0); } @@ -183,6 +186,7 @@ void fio_gettime(struct timeval *tp, void fio_unused *caller) memcpy(&last_tv, tp, sizeof(*tp)); } +#ifdef ARCH_HAVE_CPU_CLOCK static unsigned long get_cycles_per_usec(void) { struct timeval s, e; @@ -204,14 +208,12 @@ static unsigned long get_cycles_per_usec(void) return c_e - c_s; } -void fio_clock_init(void) +static void calibrate_cpu_clock(void) { double delta, mean, S; unsigned long avg, cycles[10]; int i, samples; - last_tv_valid = 0; - cycles[0] = get_cycles_per_usec(); S = delta = mean = 0.0; for (i = 0; i < 10; i++) { @@ -229,7 +231,7 @@ void fio_clock_init(void) for (i = 0; i < 10; i++) { double this = cycles[i]; - if ((max(this, mean) - min(this, mean)) > S) + if ((fmax(this, mean) - fmin(this, mean)) > S) continue; samples++; avg += this; @@ -246,15 +248,82 @@ void fio_clock_init(void) dprint(FD_TIME, "mean=%f, S=%f\n", mean, S); cycles_per_usec = avg; + +} +#else +static void calibrate_cpu_clock(void) +{ } +#endif -void fio_gtod_init(void) +void fio_clock_init(void) { - fio_tv = smalloc(sizeof(struct timeval)); - assert(fio_tv); + last_tv_valid = 0; + calibrate_cpu_clock(); +} + +unsigned long long utime_since(struct timeval *s, struct timeval *e) +{ + long sec, usec; + unsigned long long ret; + + sec = e->tv_sec - s->tv_sec; + usec = e->tv_usec - s->tv_usec; + if (sec > 0 && usec < 0) { + sec--; + usec += 1000000; + } + + /* + * time warp bug on some kernels? + */ + if (sec < 0 || (sec == 0 && usec < 0)) + return 0; + + ret = sec * 1000000ULL + usec; + + return ret; +} + +unsigned long long utime_since_now(struct timeval *s) +{ + struct timeval t; + + fio_gettime(&t, NULL); + return utime_since(s, &t); +} + +unsigned long mtime_since(struct timeval *s, struct timeval *e) +{ + long sec, usec, ret; + + sec = e->tv_sec - s->tv_sec; + usec = e->tv_usec - s->tv_usec; + if (sec > 0 && usec < 0) { + sec--; + usec += 1000000; + } + + if (sec < 0 || (sec == 0 && usec < 0)) + return 0; + + sec *= 1000UL; + usec /= 1000UL; + ret = sec + usec; + + return ret; +} + +unsigned long mtime_since_now(struct timeval *s) +{ + struct timeval t; + void *p = __builtin_return_address(0); + + fio_gettime(&t, p); + return mtime_since(s, &t); } -void fio_gtod_update(void) +unsigned long time_since_now(struct timeval *s) { - gettimeofday(fio_tv, NULL); + return mtime_since_now(s) / 1000; }