HighRezTimerPosix.cpp 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  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. namespace {
  13. /// A dummy struct that inits the timer
  14. class StartTime
  15. {
  16. public:
  17. /// The first ticks value of the application
  18. timespec m_time;
  19. StartTime()
  20. {
  21. clock_gettime(CLOCK_MONOTONIC, &m_time);
  22. }
  23. };
  24. StartTime startTime;
  25. } // namespace
  26. static U64 getNs()
  27. {
  28. U64 ticks;
  29. timespec now;
  30. clock_gettime(CLOCK_MONOTONIC, &now);
  31. ticks =
  32. static_cast<U64>(now.tv_sec - startTime.m_time.tv_sec) * 1000000000 + (now.tv_nsec - startTime.m_time.tv_nsec);
  33. return ticks;
  34. }
  35. void HighRezTimer::sleep(Second sec)
  36. {
  37. ANKI_ASSERT(sec >= 0.0);
  38. int wasError;
  39. U64 ns = static_cast<U64>(sec * 1e+9);
  40. struct timespec elapsed, tv;
  41. elapsed.tv_sec = ns / 1000000000;
  42. elapsed.tv_nsec = (ns % 1000000000);
  43. do
  44. {
  45. errno = 0;
  46. tv.tv_sec = elapsed.tv_sec;
  47. tv.tv_nsec = elapsed.tv_nsec;
  48. wasError = nanosleep(&tv, &elapsed);
  49. } while(wasError && (errno == EINTR));
  50. }
  51. Second HighRezTimer::getCurrentTime()
  52. {
  53. // Second(ticks) / 1000.0
  54. return static_cast<Second>(getNs()) * 1e-9;
  55. }
  56. } // end namespace anki