datetime.cpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. #include "datetime.h"
  2. #include "yassert.h"
  3. #include "platform.h"
  4. #include "cpu_id.h"
  5. #include <util/datetime/systime.h>
  6. #include <ctime>
  7. #include <cerrno>
  8. #ifdef _darwin_
  9. #include <AvailabilityMacros.h>
  10. #if defined(MAC_OS_X_VERSION_10_12) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12
  11. #define Y_HAS_CLOCK_GETTIME
  12. #endif
  13. #elif defined(_linux_) || defined(_freebsd_) || defined(_cygwin_)
  14. #define Y_HAS_CLOCK_GETTIME
  15. #endif
  16. static ui64 ToMicroSeconds(const struct timeval& tv) {
  17. return (ui64)tv.tv_sec * 1000000 + (ui64)tv.tv_usec;
  18. }
  19. #if defined(_win_)
  20. static ui64 ToMicroSeconds(const FILETIME& ft) {
  21. return (((ui64)ft.dwHighDateTime << 32) + (ui64)ft.dwLowDateTime) / (ui64)10;
  22. }
  23. #elif defined(Y_HAS_CLOCK_GETTIME)
  24. static ui64 ToMicroSeconds(const struct timespec& ts) {
  25. return (ui64)ts.tv_sec * 1000000 + (ui64)ts.tv_nsec / 1000;
  26. }
  27. #endif
  28. ui64 MicroSeconds() noexcept {
  29. struct timeval tv;
  30. gettimeofday(&tv, nullptr);
  31. return ToMicroSeconds(tv);
  32. }
  33. ui64 ThreadCPUUserTime() noexcept {
  34. #if defined(_win_)
  35. FILETIME creationTime, exitTime, kernelTime, userTime;
  36. GetThreadTimes(GetCurrentThread(), &creationTime, &exitTime, &kernelTime, &userTime);
  37. return ToMicroSeconds(userTime);
  38. #else
  39. return 0;
  40. #endif
  41. }
  42. ui64 ThreadCPUSystemTime() noexcept {
  43. #if defined(_win_)
  44. FILETIME creationTime, exitTime, kernelTime, userTime;
  45. GetThreadTimes(GetCurrentThread(), &creationTime, &exitTime, &kernelTime, &userTime);
  46. return ToMicroSeconds(kernelTime);
  47. #else
  48. return 0;
  49. #endif
  50. }
  51. ui64 ThreadCPUTime() noexcept {
  52. #if defined(_win_)
  53. FILETIME creationTime, exitTime, kernelTime, userTime;
  54. GetThreadTimes(GetCurrentThread(), &creationTime, &exitTime, &kernelTime, &userTime);
  55. return ToMicroSeconds(userTime) + ToMicroSeconds(kernelTime);
  56. #elif defined(Y_HAS_CLOCK_GETTIME)
  57. struct timespec ts;
  58. clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
  59. return ToMicroSeconds(ts);
  60. #else
  61. return 0;
  62. #endif
  63. }
  64. ui32 Seconds() noexcept {
  65. struct timeval tv;
  66. gettimeofday(&tv, nullptr);
  67. return tv.tv_sec;
  68. }
  69. void NanoSleep(ui64 ns) noexcept {
  70. #if defined(_win_)
  71. Sleep(ns / 1000000);
  72. #else
  73. const ui64 NS = 1000 * 1000 * 1000;
  74. struct timespec req;
  75. req.tv_sec = ns / NS;
  76. req.tv_nsec = ns % NS;
  77. struct timespec left;
  78. while (nanosleep(&req, &left) < 0) {
  79. Y_ASSERT(errno == EINTR);
  80. req = left;
  81. }
  82. #endif
  83. }
  84. #if defined(_x86_)
  85. namespace NPrivate {
  86. bool HaveRdtscpImpl() {
  87. return NX86::HaveRDTSCP();
  88. }
  89. } // namespace NPrivate
  90. #endif
  91. #ifdef Y_HAS_CLOCK_GETTIME
  92. #undef Y_HAS_CLOCK_GETTIME
  93. #endif