From 9a358c3cdf8eb34754cc5544e2a5e0f67c022f8d Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Thu, 17 Sep 2009 13:33:06 +0000 Subject: Improve sandglass_tsc_resolution(), and fix timespec-based grains counts. --- src/tsc.c | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) (limited to 'src/tsc.c') diff --git a/src/tsc.c b/src/tsc.c index 64fe1b1..8038c0e 100644 --- a/src/tsc.c +++ b/src/tsc.c @@ -21,19 +21,46 @@ #include "sandglass_impl.h" #include "sandglass.h" #include +#include /* Gets the number of clock ticks per second */ double sandglass_tsc_resolution() { - static long tsc = 0; - struct timespec ts = { .tv_sec = 0, .tv_nsec = 100000000 }; + static long tsc = 0, grains1, grains2; + + int monotonic; + struct timespec ts; if (tsc == 0) { + monotonic = sysconf(_SC_MONOTONIC_CLOCK) > 0; + if (monotonic) { + if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) + return 0.0/0.0; + } else { + if (clock_gettime(CLOCK_REALTIME, &ts) != 0) + return 0.0/0.0; + } tsc = sandglass_get_tsc(); - while (nanosleep(&ts, &ts) != 0); + grains1 = sandglass_timespec_grains(&ts); + grains2 = grains1; + + while (((grains2 >= grains1) ? grains2 - grains1 + : 2000000000L + (grains2 - grains1)) + < 10000000L) + { + if (monotonic) { + if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) + return 0.0/0.0; + } else { + if (clock_gettime(CLOCK_REALTIME, &ts) != 0) + return 0.0/0.0; + } + grains2 = sandglass_timespec_grains(&ts); + } + tsc = sandglass_get_tsc() - tsc; } - return tsc*10.0; + return tsc*1.0e9/(grains2 - grains1); } -- cgit v1.2.3