Counter Strike : Global Offensive Source Code
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.

139 lines
3.3 KiB

  1. // hrtimer.cpp - written and placed in the public domain by Wei Dai
  2. #include "pch.h"
  3. #include "hrtimer.h"
  4. #include "misc.h"
  5. #include <stddef.h> // for NULL
  6. #include <time.h>
  7. #if defined(CRYPTOPP_WIN32_AVAILABLE)
  8. #include <windows.h>
  9. #elif defined(CRYPTOPP_UNIX_AVAILABLE)
  10. #include <sys/time.h>
  11. #include <sys/times.h>
  12. #include <unistd.h>
  13. #endif
  14. #include <assert.h>
  15. NAMESPACE_BEGIN(CryptoPP)
  16. #ifndef CRYPTOPP_IMPORTS
  17. double TimerBase::ConvertTo(TimerWord t, Unit unit)
  18. {
  19. static unsigned long unitsPerSecondTable[] = {1, 1000, 1000*1000, 1000*1000*1000};
  20. assert(unit < sizeof(unitsPerSecondTable) / sizeof(unitsPerSecondTable[0]));
  21. return (double)CRYPTOPP_VC6_INT64 t * unitsPerSecondTable[unit] / CRYPTOPP_VC6_INT64 TicksPerSecond();
  22. }
  23. void TimerBase::StartTimer()
  24. {
  25. m_last = m_start = GetCurrentTimerValue();
  26. m_started = true;
  27. }
  28. double TimerBase::ElapsedTimeAsDouble()
  29. {
  30. if (m_stuckAtZero)
  31. return 0;
  32. if (m_started)
  33. {
  34. TimerWord now = GetCurrentTimerValue();
  35. if (m_last < now) // protect against OS bugs where time goes backwards
  36. m_last = now;
  37. return ConvertTo(m_last - m_start, m_timerUnit);
  38. }
  39. StartTimer();
  40. return 0;
  41. }
  42. unsigned long TimerBase::ElapsedTime()
  43. {
  44. double elapsed = ElapsedTimeAsDouble();
  45. assert(elapsed <= ULONG_MAX);
  46. return (unsigned long)elapsed;
  47. }
  48. TimerWord Timer::GetCurrentTimerValue()
  49. {
  50. #if defined(CRYPTOPP_WIN32_AVAILABLE)
  51. LARGE_INTEGER now;
  52. if (!QueryPerformanceCounter(&now))
  53. throw Exception(Exception::OTHER_ERROR, "Timer: QueryPerformanceCounter failed with error " + IntToString(GetLastError()));
  54. return now.QuadPart;
  55. #elif defined(CRYPTOPP_UNIX_AVAILABLE)
  56. timeval now;
  57. gettimeofday(&now, NULL);
  58. return (TimerWord)now.tv_sec * 1000000 + now.tv_usec;
  59. #else
  60. clock_t now;
  61. return clock();
  62. #endif
  63. }
  64. TimerWord Timer::TicksPerSecond()
  65. {
  66. #if defined(CRYPTOPP_WIN32_AVAILABLE)
  67. static LARGE_INTEGER freq = {0};
  68. if (freq.QuadPart == 0)
  69. {
  70. if (!QueryPerformanceFrequency(&freq))
  71. throw Exception(Exception::OTHER_ERROR, "Timer: QueryPerformanceFrequency failed with error " + IntToString(GetLastError()));
  72. }
  73. return freq.QuadPart;
  74. #elif defined(CRYPTOPP_UNIX_AVAILABLE)
  75. return 1000000;
  76. #else
  77. return CLOCKS_PER_SEC;
  78. #endif
  79. }
  80. #endif // #ifndef CRYPTOPP_IMPORTS
  81. TimerWord ThreadUserTimer::GetCurrentTimerValue()
  82. {
  83. #if defined(CRYPTOPP_WIN32_AVAILABLE)
  84. static bool getCurrentThreadImplemented = true;
  85. if (getCurrentThreadImplemented)
  86. {
  87. FILETIME now, ignored;
  88. if (!GetThreadTimes(GetCurrentThread(), &ignored, &ignored, &ignored, &now))
  89. {
  90. DWORD lastError = GetLastError();
  91. if (lastError == ERROR_CALL_NOT_IMPLEMENTED)
  92. {
  93. getCurrentThreadImplemented = false;
  94. goto GetCurrentThreadNotImplemented;
  95. }
  96. throw Exception(Exception::OTHER_ERROR, "ThreadUserTimer: GetThreadTimes failed with error " + IntToString(lastError));
  97. }
  98. return now.dwLowDateTime + ((TimerWord)now.dwHighDateTime << 32);
  99. }
  100. GetCurrentThreadNotImplemented:
  101. return (TimerWord)clock() * (10*1000*1000 / CLOCKS_PER_SEC);
  102. #elif defined(CRYPTOPP_UNIX_AVAILABLE)
  103. tms now;
  104. times(&now);
  105. return now.tms_utime;
  106. #else
  107. return clock();
  108. #endif
  109. }
  110. TimerWord ThreadUserTimer::TicksPerSecond()
  111. {
  112. #if defined(CRYPTOPP_WIN32_AVAILABLE)
  113. return 10*1000*1000;
  114. #elif defined(CRYPTOPP_UNIX_AVAILABLE)
  115. static const long ticksPerSecond = sysconf(_SC_CLK_TCK);
  116. return ticksPerSecond;
  117. #else
  118. return CLOCKS_PER_SEC;
  119. #endif
  120. }
  121. NAMESPACE_END