PageRenderTime 26ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/package/cryptopp563/hrtimer.cpp

https://gitlab.com/cdeclare/intcrypt
C++ | 142 lines | 119 code | 18 blank | 5 comment | 11 complexity | 7d9a3ccf6ab9767b287c28a7c6d3f1ba MD5 | raw file
  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. // When 'unit' is an enum 'Unit', a Clang warning is generated.
  21. assert(static_cast<unsigned int>(unit) < COUNTOF(unitsPerSecondTable));
  22. return (double)CRYPTOPP_VC6_INT64 t * unitsPerSecondTable[unit] / CRYPTOPP_VC6_INT64 TicksPerSecond();
  23. }
  24. void TimerBase::StartTimer()
  25. {
  26. m_last = m_start = GetCurrentTimerValue();
  27. m_started = true;
  28. }
  29. double TimerBase::ElapsedTimeAsDouble()
  30. {
  31. if (m_stuckAtZero)
  32. return 0;
  33. if (m_started)
  34. {
  35. TimerWord now = GetCurrentTimerValue();
  36. if (m_last < now) // protect against OS bugs where time goes backwards
  37. m_last = now;
  38. return ConvertTo(m_last - m_start, m_timerUnit);
  39. }
  40. StartTimer();
  41. return 0;
  42. }
  43. unsigned long TimerBase::ElapsedTime()
  44. {
  45. double elapsed = ElapsedTimeAsDouble();
  46. assert(elapsed <= ULONG_MAX);
  47. return (unsigned long)elapsed;
  48. }
  49. TimerWord Timer::GetCurrentTimerValue()
  50. {
  51. #if defined(CRYPTOPP_WIN32_AVAILABLE)
  52. // Use the first union member to avoid an uninitialized warning
  53. LARGE_INTEGER now = {0,0};
  54. if (!QueryPerformanceCounter(&now))
  55. throw Exception(Exception::OTHER_ERROR, "Timer: QueryPerformanceCounter failed with error " + IntToString(GetLastError()));
  56. return now.QuadPart;
  57. #elif defined(CRYPTOPP_UNIX_AVAILABLE)
  58. timeval now;
  59. gettimeofday(&now, NULL);
  60. return (TimerWord)now.tv_sec * 1000000 + now.tv_usec;
  61. #else
  62. // clock_t now;
  63. return clock();
  64. #endif
  65. }
  66. TimerWord Timer::TicksPerSecond()
  67. {
  68. #if defined(CRYPTOPP_WIN32_AVAILABLE)
  69. // Use the second union member to avoid an uninitialized warning
  70. static LARGE_INTEGER freq = {0,0};
  71. if (freq.QuadPart == 0)
  72. {
  73. if (!QueryPerformanceFrequency(&freq))
  74. throw Exception(Exception::OTHER_ERROR, "Timer: QueryPerformanceFrequency failed with error " + IntToString(GetLastError()));
  75. }
  76. return freq.QuadPart;
  77. #elif defined(CRYPTOPP_UNIX_AVAILABLE)
  78. return 1000000;
  79. #else
  80. return CLOCKS_PER_SEC;
  81. #endif
  82. }
  83. #endif // #ifndef CRYPTOPP_IMPORTS
  84. TimerWord ThreadUserTimer::GetCurrentTimerValue()
  85. {
  86. #if defined(CRYPTOPP_WIN32_AVAILABLE)
  87. static bool getCurrentThreadImplemented = true;
  88. if (getCurrentThreadImplemented)
  89. {
  90. FILETIME now, ignored;
  91. if (!GetThreadTimes(GetCurrentThread(), &ignored, &ignored, &ignored, &now))
  92. {
  93. DWORD lastError = GetLastError();
  94. if (lastError == ERROR_CALL_NOT_IMPLEMENTED)
  95. {
  96. getCurrentThreadImplemented = false;
  97. goto GetCurrentThreadNotImplemented;
  98. }
  99. throw Exception(Exception::OTHER_ERROR, "ThreadUserTimer: GetThreadTimes failed with error " + IntToString(lastError));
  100. }
  101. return now.dwLowDateTime + ((TimerWord)now.dwHighDateTime << 32);
  102. }
  103. GetCurrentThreadNotImplemented:
  104. return (TimerWord)clock() * (10*1000*1000 / CLOCKS_PER_SEC);
  105. #elif defined(CRYPTOPP_UNIX_AVAILABLE)
  106. tms now;
  107. times(&now);
  108. return now.tms_utime;
  109. #else
  110. return clock();
  111. #endif
  112. }
  113. TimerWord ThreadUserTimer::TicksPerSecond()
  114. {
  115. #if defined(CRYPTOPP_WIN32_AVAILABLE)
  116. return 10*1000*1000;
  117. #elif defined(CRYPTOPP_UNIX_AVAILABLE)
  118. static const long ticksPerSecond = sysconf(_SC_CLK_TCK);
  119. return ticksPerSecond;
  120. #else
  121. return CLOCKS_PER_SEC;
  122. #endif
  123. }
  124. NAMESPACE_END