diff options
Diffstat (limited to 'zen/tick_count.h')
-rw-r--r-- | zen/tick_count.h | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/zen/tick_count.h b/zen/tick_count.h index 4f1a047e..98e59ae5 100644 --- a/zen/tick_count.h +++ b/zen/tick_count.h @@ -8,8 +8,10 @@ #define ZEN_TICK_COUNT_HEADER_3807326 #include <cstdint> +#include <algorithm> #include "type_traits.h" #include "assert_static.h" +#include <cmath> #ifdef FFS_WIN #include "win.h" //includes "windows.h" @@ -21,7 +23,7 @@ namespace zen { //a portable "GetTickCount()" using "wall time equivalent" - e.g. no jumps due to ntp time corrections class TickVal; -std::int64_t operator-(const TickVal& lhs, const TickVal& rhs); +std::int64_t dist(const TickVal& lhs, const TickVal& rhs); //use absolute difference for paranoid security: even QueryPerformanceCounter "wraps-around" at *some* time std::int64_t ticksPerSec(); //return 0 on error TickVal getTicks(); //return invalid value on error: !TickVal::isValid() @@ -40,10 +42,6 @@ TickVal getTicks(); //return invalid value on error: !TickVal::isValid() - - - - //############################ implementation ############################## class TickVal { @@ -58,19 +56,31 @@ public: explicit TickVal(const NativeVal& val) : val_(val) {} inline friend - std::int64_t operator-(const TickVal& lhs, const TickVal& rhs) + std::int64_t dist(const TickVal& lhs, const TickVal& rhs) { #ifdef FFS_WIN assert_static(IsSignedInt<decltype(lhs.val_.QuadPart)>::value); - return lhs.val_.QuadPart - rhs.val_.QuadPart; + return std::abs(lhs.val_.QuadPart - rhs.val_.QuadPart); #elif defined FFS_LINUX assert_static(IsSignedInt<decltype(lhs.val_.tv_sec)>::value); assert_static(IsSignedInt<decltype(lhs.val_.tv_nsec)>::value); - return static_cast<std::int64_t>(lhs.val_.tv_sec - rhs.val_.tv_sec) * 1000000000.0 + lhs.val_.tv_nsec - rhs.val_.tv_nsec; + return std::abs(static_cast<std::int64_t>(lhs.val_.tv_sec - rhs.val_.tv_sec) * 1000000000.0 + (lhs.val_.tv_nsec - rhs.val_.tv_nsec)); +#endif + } + + inline friend + bool operator<(const TickVal& lhs, const TickVal& rhs) //evaluate directly rather than reuse operator- + { +#ifdef FFS_WIN + return lhs.val_.QuadPart < rhs.val_.QuadPart; +#elif defined FFS_LINUX + if (lhs.val_.tv_sec != rhs.val_.tv_sec) + return lhs.val_.tv_sec < rhs.val_.tv_sec; + return lhs.val_.tv_nsec < rhs.val_.tv_nsec; #endif } - bool isValid() const { return *this - TickVal() != 0; } + bool isValid() const { return dist(*this, TickVal()) != 0; } private: NativeVal val_; @@ -82,7 +92,7 @@ std::int64_t ticksPerSec() //return 0 on error { #ifdef FFS_WIN LARGE_INTEGER frequency = {}; - if (!::QueryPerformanceFrequency(&frequency)) + if (!::QueryPerformanceFrequency(&frequency)) //MSDN promises: "The frequency cannot change while the system is running." return 0; assert_static(sizeof(std::int64_t) >= sizeof(frequency.QuadPart)); return frequency.QuadPart; |