diff options
-rw-r--r-- | compat/timer.cpp | 76 | ||||
-rw-r--r-- | compat/timer.hpp | 13 |
2 files changed, 38 insertions, 51 deletions
diff --git a/compat/timer.cpp b/compat/timer.cpp index b46ebe4a..a555018c 100644 --- a/compat/timer.cpp +++ b/compat/timer.cpp @@ -12,6 +12,8 @@ #include <cassert> #include <cmath> +#include <QDebug> + using time_type = Timer::time_type; Timer::Timer() @@ -24,40 +26,35 @@ void Timer::start() gettime(&state); } -// nanoseconds - -time_type Timer::elapsed_nsecs() const +struct timespec Timer::gettime_() const { - timespec cur{}; - gettime(&cur); - return conv_nsecs(cur); + struct timespec ts{}; + gettime(&ts); + ts.tv_sec -= state.tv_sec; + ts.tv_nsec -= state.tv_nsec; + return ts; } -time_type Timer::conv_nsecs(const struct timespec& cur) const -{ - return (cur.tv_sec - state.tv_sec) * 1000000000LL + (cur.tv_nsec - state.tv_nsec); -} - -// microseconds +// nanoseconds -double Timer::elapsed_usecs() const +time_type Timer::elapsed_nsecs() const { - timespec cur{}; - gettime(&cur); - const long long nsecs = conv_nsecs(cur); - return nsecs * 1e-3; + struct timespec delta = gettime_(); + return (time_type)delta.tv_sec * 1000000000 + (time_type)delta.tv_nsec; } // milliseconds double Timer::elapsed_ms() const { - return elapsed_usecs() / 1000.; + struct timespec delta = gettime_(); + return delta.tv_sec * 1000 + delta.tv_nsec * 1e-6; } double Timer::elapsed_seconds() const { - return double(elapsed_nsecs() * 1e-9); + struct timespec delta = gettime_(); + return delta.tv_sec + delta.tv_nsec * 1e-9; } // -- @@ -67,27 +64,28 @@ double Timer::elapsed_seconds() const #if defined (_WIN32) # include <windows.h> -static LARGE_INTEGER otr_get_clock_frequency() +static auto otr_get_clock_frequency() { LARGE_INTEGER freq{}; - const BOOL ret = QueryPerformanceFrequency(&freq); + BOOL ret = QueryPerformanceFrequency(&freq); assert(ret && "QueryPerformanceFrequency failed"); - return freq; + return freq.QuadPart; } -static void otr_clock_gettime(timespec* ts) +void Timer::gettime(timespec* ts) { - static const LARGE_INTEGER freq = otr_get_clock_frequency(); + static const unsigned long long freq = otr_get_clock_frequency(); LARGE_INTEGER d; - (void) QueryPerformanceCounter(&d); + BOOL ret = QueryPerformanceCounter(&d); + assert(ret && "QueryPerformanceCounter failed"); using ll = long long; - const auto part = ll(std::roundl((d.QuadPart * 1000000000.L) / ll(freq.QuadPart))); + auto part = ll(std::roundl((d.QuadPart * 1000000000.L) / freq)); using t_s = decltype(ts->tv_sec); using t_ns = decltype(ts->tv_nsec); - ts->tv_sec = t_s(part / 1000000000LL); + ts->tv_sec = t_s((long double)d.QuadPart/freq); ts->tv_nsec = t_ns(part % 1000000000LL); } @@ -98,11 +96,11 @@ static void otr_clock_gettime(timespec* ts) static mach_timebase_info_data_t otr_get_mach_frequency() { mach_timebase_info_data_t timebase_info; - (void) mach_timebase_info(&timebase_info); + (void)mach_timebase_info(&timebase_info); return timebase_info; } -static void otr_clock_gettime(timespec* ts) +void Timer::gettime(timespec* ts) { static const mach_timebase_info_data_t timebase_info = otr_get_mach_frequency(); uint64_t state, nsec; @@ -112,19 +110,15 @@ static void otr_clock_gettime(timespec* ts) ts->tv_nsec = nsec % 1000000000UL; } +#else + +void Timer::gettime(timespec* ts) +{ + [[maybe_unused]] int error = clock_gettime(CLOCK_MONOTONIC, ts); + assert(error == 0 && "clock_gettime failed"); +}; + #endif // common -void Timer::gettime(timespec* state) -{ -#if defined(_WIN32) || defined(__MACH__) - otr_clock_gettime(state); -#elif defined CLOCK_MONOTONIC - const int res = clock_gettime(CLOCK_MONOTONIC, state); - (void)res; - assert(res == 0 && "must support CLOCK_MONOTONIC"); -#else -# error "timer query method not known" -#endif -} diff --git a/compat/timer.hpp b/compat/timer.hpp index d162a949..c107d28d 100644 --- a/compat/timer.hpp +++ b/compat/timer.hpp @@ -12,30 +12,23 @@ #include "time.hpp" #include <ctime> +#include <cstdint> #include <type_traits> struct OTR_COMPAT_EXPORT Timer final { - using time_type = time_t; + using time_type = std::int64_t; Timer(); void start(); - template<typename t> - constexpr auto elapsed() const - { - using ns = time_units::ns; - return t{ns{elapsed_nsecs()}}; - } - time_type elapsed_nsecs() const; - double elapsed_usecs() const; double elapsed_ms() const; double elapsed_seconds() const; private: struct timespec state {}; static void gettime(struct timespec* state); - time_type conv_nsecs(const struct timespec& cur) const; + struct timespec gettime_() const; using ns = time_units::ns; }; |