#include "system/ovCTime.h" #include #include // \warning On Windows, avoid "using namespace System;" here as it may cause confusion with stuff coming from windows/boost // \note Support of C++11 steady clock: // - From GCC 4.8.1 // - From Visual Studio 2015 (therefore a strategy is needed to handle Visual Studio 2013 version) // time handling strategy selection // \note With officialy supported compilers and required boost version // it should never fallback in a OV_USE_SYSTEM case #if (defined(_MSC_VER) && _MSC_VER <= 1800 && defined(TARGET_HAS_Boost_Chrono)) #include #ifdef BOOST_CHRONO_HAS_CLOCK_STEADY #include #include namespace Timelib = boost; #else #error "Please use OpenViBE recommended version of Boost" #endif // BOOST_CHRONO_HAS_CLOCK_STEADY #else // defined(_MSC_VER) && _MSC_VER <= 1800 && defined(TARGET_HAS_Boost_Chrono) #include #include namespace Timelib = std; #endif // defined(_MSC_VER) && _MSC_VER <= 1800 && defined(TARGET_HAS_Boost_Chrono) using internal_clock = Timelib::chrono::steady_clock; // using internal_clock = chrono::high_resolution_clock; namespace System { bool Time::sleep(const size_t milliSeconds) { Timelib::this_thread::sleep_for(Timelib::chrono::milliseconds(milliSeconds)); return true; } bool Time::zsleep(const uint64_t seconds) { const uint32_t s = uint32_t(seconds >> 32); // zero the seconds with 0xFFFFFFFF, multiply to get the rest as fixed point microsec, then grab them (now in the 32 msbs) const uint64_t ms = ((seconds & 0xFFFFFFFFLL) * 1000000LL) >> 32; const Timelib::chrono::microseconds duration = Timelib::chrono::seconds(s) + Timelib::chrono::microseconds(ms); Timelib::this_thread::sleep_for(duration); return true; } uint64_t Time::zgetTimeRaw(const bool sinceFirstCall) { static bool initialized = false; static internal_clock::time_point start; if (!initialized) { start = internal_clock::now(); initialized = true; } const internal_clock::time_point now = internal_clock::now(); const internal_clock::duration elapsed = (sinceFirstCall ? now - start : now.time_since_epoch()); const Timelib::chrono::microseconds elapsedMs = Timelib::chrono::duration_cast(elapsed); const uint64_t microsPerSecond = 1000ULL * 1000ULL; const uint64_t seconds = uint64_t(elapsedMs.count() / microsPerSecond); const uint64_t fraction = uint64_t(elapsedMs.count() % microsPerSecond); // below in fraction part, scale [0,microsPerSecond-1] to 32bit integer range const uint64_t res = (seconds << 32) + fraction * (0xFFFFFFFFLL / (microsPerSecond - 1)); return res; } bool Time::isClockSteady() { return internal_clock::is_steady; } bool Time::checkResolution(const size_t milliSeconds) { assert(milliSeconds != 0); const auto resolution = double(internal_clock::period::num) / internal_clock::period::den; return (size_t(std::ceil(resolution * 1000)) <= milliSeconds); } } // namespace System