HighRezTimerPosix.cpp 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. // Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <AnKi/Util/HighRezTimer.h>
  6. #include <AnKi/Util/Assert.h>
  7. #include <sys/time.h>
  8. #include <unistd.h>
  9. #include <errno.h>
  10. #include <time.h>
  11. namespace anki
  12. {
  13. namespace
  14. {
  15. /// A dummy struct that inits the timer
  16. class StartTime
  17. {
  18. public:
  19. /// The first ticks value of the application
  20. timespec m_time;
  21. StartTime()
  22. {
  23. clock_gettime(CLOCK_MONOTONIC, &m_time);
  24. }
  25. };
  26. StartTime startTime;
  27. } // namespace
  28. static U64 getNs()
  29. {
  30. U64 ticks;
  31. timespec now;
  32. clock_gettime(CLOCK_MONOTONIC, &now);
  33. ticks =
  34. static_cast<U64>(now.tv_sec - startTime.m_time.tv_sec) * 1000000000 + (now.tv_nsec - startTime.m_time.tv_nsec);
  35. return ticks;
  36. }
  37. void HighRezTimer::sleep(Second sec)
  38. {
  39. ANKI_ASSERT(sec >= 0.0);
  40. int wasError;
  41. U64 ns = static_cast<U64>(sec * 1e+9);
  42. struct timespec elapsed, tv;
  43. elapsed.tv_sec = ns / 1000000000;
  44. elapsed.tv_nsec = (ns % 1000000000);
  45. do
  46. {
  47. errno = 0;
  48. tv.tv_sec = elapsed.tv_sec;
  49. tv.tv_nsec = elapsed.tv_nsec;
  50. wasError = nanosleep(&tv, &elapsed);
  51. } while(wasError && (errno == EINTR));
  52. }
  53. Second HighRezTimer::getCurrentTime()
  54. {
  55. // Second(ticks) / 1000.0
  56. return static_cast<Second>(getNs()) * 1e-9;
  57. }
  58. } // end namespace anki