diff options
Diffstat (limited to 'zen/tick_count.h')
-rw-r--r-- | zen/tick_count.h | 41 |
1 files changed, 17 insertions, 24 deletions
diff --git a/zen/tick_count.h b/zen/tick_count.h index 893d8e80..cb15fe20 100644 --- a/zen/tick_count.h +++ b/zen/tick_count.h @@ -10,6 +10,7 @@ #include <cstdint> #include "type_traits.h" #include "basic_math.h" + #ifdef ZEN_WIN #include "win.h" //includes "windows.h" @@ -19,31 +20,20 @@ #elif defined ZEN_MAC #include <mach/mach_time.h> #endif -//#include <algorithm> -//#include "assert_static.h" -//#include <cmath> //template <class T> inline //T dist(T a, T b) //{ // return a > b ? a - b : b - a; //} - - namespace zen { //a portable "GetTickCount()" using "wall time equivalent" - e.g. no jumps due to ntp time corrections class TickVal; -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() - - - - - +int64_t dist(const TickVal& lhs, const TickVal& rhs); //use absolute difference for paranoid security: even QueryPerformanceCounter "wraps-around" at *some* time +int64_t ticksPerSec(); //return 0 on error +TickVal getTicks(); //return invalid value on error: !TickVal::isValid() @@ -69,17 +59,17 @@ public: explicit TickVal(const NativeVal& val) : val_(val) {} inline friend - std::int64_t dist(const TickVal& lhs, const TickVal& rhs) + int64_t dist(const TickVal& lhs, const TickVal& rhs) { #ifdef ZEN_WIN return numeric::dist(lhs.val_.QuadPart, rhs.val_.QuadPart); //std::abs(a - b) can lead to overflow! #elif defined ZEN_LINUX - const auto distSec = numeric::dist(lhs.val_.tv_sec, rhs.val_.tv_sec); - const auto distNsec = numeric::dist(lhs.val_.tv_nsec, rhs.val_.tv_nsec); - - if (distSec > (std::numeric_limits<std::int64_t>::max() - distNsec) / 1000000000) //truncate instead of overflow! - return std::numeric_limits<std::int64_t>::max(); - return distSec * 1000000000 + distNsec; +//structure timespec documented with members: +// time_t tv_sec seconds +// long tv_nsec nanoseconds + const int64_t deltaSec = lhs.val_.tv_sec - rhs.val_.tv_sec; + const int64_t deltaNsec = lhs.val_.tv_nsec - rhs.val_.tv_nsec; + return numeric::abs(deltaSec * 1000000000 + deltaNsec); #elif defined ZEN_MAC return numeric::dist(lhs.val_, rhs.val_); #endif @@ -107,13 +97,13 @@ private: inline -std::int64_t ticksPerSec() //return 0 on error +int64_t ticksPerSec() //return 0 on error { #ifdef ZEN_WIN LARGE_INTEGER frequency = {}; if (!::QueryPerformanceFrequency(&frequency)) //MSDN promises: "The frequency cannot change while the system is running." return 0; - static_assert(sizeof(std::int64_t) >= sizeof(frequency.QuadPart), ""); + static_assert(sizeof(int64_t) >= sizeof(frequency.QuadPart), ""); return frequency.QuadPart; #elif defined ZEN_LINUX @@ -123,7 +113,10 @@ std::int64_t ticksPerSec() //return 0 on error mach_timebase_info_data_t tbi = {}; if (::mach_timebase_info(&tbi) != KERN_SUCCESS) return 0; - return 1000000000 * tbi.denom / tbi.numer; +//structure mach_timebase_info_data_t documented with members: +// uint32_t numer; +// uint32_t denom; + return static_cast<int64_t>(1000000000) * tbi.denom / tbi.numer; #endif } |