You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ovCTime.cpp 3.0KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #include "system/ovCTime.h"
  2. #include <cmath>
  3. #include <cassert>
  4. // \warning On Windows, avoid "using namespace System;" here as it may cause confusion with stuff coming from windows/boost
  5. // \note Support of C++11 steady clock:
  6. // - From GCC 4.8.1
  7. // - From Visual Studio 2015 (therefore a strategy is needed to handle Visual Studio 2013 version)
  8. // time handling strategy selection
  9. // \note With officialy supported compilers and required boost version
  10. // it should never fallback in a OV_USE_SYSTEM case
  11. #if (defined(_MSC_VER) && _MSC_VER <= 1800 && defined(TARGET_HAS_Boost_Chrono))
  12. #include <boost/chrono/config.hpp>
  13. #ifdef BOOST_CHRONO_HAS_CLOCK_STEADY
  14. #include <boost/chrono.hpp>
  15. #include <boost/thread.hpp>
  16. namespace Timelib = boost;
  17. #else
  18. #error "Please use OpenViBE recommended version of Boost"
  19. #endif // BOOST_CHRONO_HAS_CLOCK_STEADY
  20. #else // defined(_MSC_VER) && _MSC_VER <= 1800 && defined(TARGET_HAS_Boost_Chrono)
  21. #include <chrono>
  22. #include <thread>
  23. namespace Timelib = std;
  24. #endif // defined(_MSC_VER) && _MSC_VER <= 1800 && defined(TARGET_HAS_Boost_Chrono)
  25. using internal_clock = Timelib::chrono::steady_clock;
  26. // using internal_clock = chrono::high_resolution_clock;
  27. namespace System {
  28. bool Time::sleep(const size_t milliSeconds)
  29. {
  30. Timelib::this_thread::sleep_for(Timelib::chrono::milliseconds(milliSeconds));
  31. return true;
  32. }
  33. bool Time::zsleep(const uint64_t seconds)
  34. {
  35. const uint32_t s = uint32_t(seconds >> 32);
  36. // zero the seconds with 0xFFFFFFFF, multiply to get the rest as fixed point microsec, then grab them (now in the 32 msbs)
  37. const uint64_t ms = ((seconds & 0xFFFFFFFFLL) * 1000000LL) >> 32;
  38. const Timelib::chrono::microseconds duration = Timelib::chrono::seconds(s) + Timelib::chrono::microseconds(ms);
  39. Timelib::this_thread::sleep_for(duration);
  40. return true;
  41. }
  42. uint64_t Time::zgetTimeRaw(const bool sinceFirstCall)
  43. {
  44. static bool initialized = false;
  45. static internal_clock::time_point start;
  46. if (!initialized)
  47. {
  48. start = internal_clock::now();
  49. initialized = true;
  50. }
  51. const internal_clock::time_point now = internal_clock::now();
  52. const internal_clock::duration elapsed = (sinceFirstCall ? now - start : now.time_since_epoch());
  53. const Timelib::chrono::microseconds elapsedMs = Timelib::chrono::duration_cast<Timelib::chrono::microseconds>(elapsed);
  54. const uint64_t microsPerSecond = 1000ULL * 1000ULL;
  55. const uint64_t seconds = uint64_t(elapsedMs.count() / microsPerSecond);
  56. const uint64_t fraction = uint64_t(elapsedMs.count() % microsPerSecond);
  57. // below in fraction part, scale [0,microsPerSecond-1] to 32bit integer range
  58. const uint64_t res = (seconds << 32) + fraction * (0xFFFFFFFFLL / (microsPerSecond - 1));
  59. return res;
  60. }
  61. bool Time::isClockSteady() { return internal_clock::is_steady; }
  62. bool Time::checkResolution(const size_t milliSeconds)
  63. {
  64. assert(milliSeconds != 0);
  65. const auto resolution = double(internal_clock::period::num) / internal_clock::period::den;
  66. return (size_t(std::ceil(resolution * 1000)) <= milliSeconds);
  67. }
  68. } // namespace System