diff options
Diffstat (limited to 'compat/timer.cpp')
| -rw-r--r-- | compat/timer.cpp | 110 |
1 files changed, 50 insertions, 60 deletions
diff --git a/compat/timer.cpp b/compat/timer.cpp index d5052ccb..fdea185a 100644 --- a/compat/timer.cpp +++ b/compat/timer.cpp @@ -6,7 +6,12 @@ * notice appear in all copies. */ +#undef NDEBUG + #include "timer.hpp" +#include <cassert> +#include <cmath> +#include <QDebug> Timer::Timer() { @@ -15,103 +20,88 @@ Timer::Timer() void Timer::start() { - wrap_gettime(&state); + gettime(&state); } -// common - -void Timer::wrap_gettime(timespec* state) +struct timespec Timer::get_delta() const { -#if defined(_WIN32) || defined(__MACH__) - otr_clock_gettime(state); -#else - (void) clock_gettime(CLOCK_MONOTONIC, state); -#endif -} - -// nanoseconds - -long long Timer::elapsed_nsecs() const -{ - struct timespec cur = {}; - wrap_gettime(&cur); - return conv_nsecs(cur); -} - -long long Timer::conv_nsecs(const timespec& cur) const -{ - // this can and will overflow - return (cur.tv_sec - state.tv_sec) * 1000000000LL + (cur.tv_nsec - state.tv_nsec); -} - -// microseconds - -double Timer::elapsed_usecs() const -{ - struct timespec cur = {}; - wrap_gettime(&cur); - const long long nsecs = conv_nsecs(cur); - return nsecs * 1e-3; + struct timespec ts; // NOLINT + gettime(&ts); + return { ts.tv_sec - state.tv_sec, ts.tv_nsec - state.tv_nsec }; } // milliseconds double Timer::elapsed_ms() const { - return elapsed_usecs() / 1000.; + struct timespec delta = get_delta(); + return delta.tv_sec * 1000 + delta.tv_nsec * 1e-6; } double Timer::elapsed_seconds() const { - return double(elapsed_nsecs() * 1e-9L); + struct timespec delta = get_delta(); + return delta.tv_sec + delta.tv_nsec * 1e-9; } // -- // platform-specific code starts here // -- -#if defined _WIN32 -LARGE_INTEGER Timer::otr_get_clock_frequency() +#if defined (_WIN32) +# include <windows.h> + +static auto otr_get_clock_frequency() { - LARGE_INTEGER freq = {}; - (void) QueryPerformanceFrequency(&freq); - return freq; + LARGE_INTEGER freq{}; + BOOL ret = QueryPerformanceFrequency(&freq); + assert(ret && "QueryPerformanceFrequency failed"); + return freq.QuadPart; } -void Timer::otr_clock_gettime(timespec* ts) +void Timer::gettime(timespec* state) { - static LARGE_INTEGER freq = otr_get_clock_frequency(); - + static const auto freq = otr_get_clock_frequency(); LARGE_INTEGER d; + BOOL ret = QueryPerformanceCounter(&d); + assert(ret && "QueryPerformanceCounter failed"); - (void) QueryPerformanceCounter(&d); - - using ll = long long; - using ld = long double; - const long long part = ll(d.QuadPart / ld(freq.QuadPart) * 1000000000.L); - using t_s = decltype(ts->tv_sec); - using t_ns = decltype(ts->tv_nsec); - - ts->tv_sec = t_s(part / 1000000000LL); - ts->tv_nsec = t_ns(part % 1000000000LL); + constexpr int nsec = 1'000'000 * 1000; + state->tv_sec = (time_t)(d.QuadPart/freq); + state->tv_nsec = (decltype(state->tv_nsec))(d.QuadPart % freq * nsec / freq); } #elif defined __MACH__ -mach_timebase_info_data_t Timer::otr_get_mach_frequency() +# include <inttypes.h> +# include <mach/mach_time.h> + +static mach_timebase_info_data_t otr_get_mach_frequency() { mach_timebase_info_data_t timebase_info; - (void) mach_timebase_info(&timebase_info); + kern_return_t status = mach_timebase_info(&timebase_info); + assert(status == KERN_SUCCESS && "mach_timebase_info failed"); return timebase_info; } -double Timer::otr_clock_gettime(timespec* ts) +void Timer::gettime(timespec* ts) { - static mach_timebase_info_data_t timebase_info = otr_get_mach_frequency(); + static const mach_timebase_info_data_t timebase_info = otr_get_mach_frequency(); uint64_t state, nsec; state = mach_absolute_time(); nsec = state * timebase_info.numer / timebase_info.denom; - ts->tv_sec = nsec / 1000000000L; - ts->tv_nsec = nsec % 1000000000L; + ts->tv_sec = nsec / 1000000000UL; + ts->tv_nsec = nsec % 1000000000UL; +} + +#else + +void Timer::gettime(timespec* ts) +{ + int error = clock_gettime(CLOCK_MONOTONIC, ts); + assert(error == 0 && "clock_gettime failed"); } #endif + +// common + |
