TickCounter.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  2. // SPDX-License-Identifier: MIT
  3. #include <Jolt/Jolt.h>
  4. #include <Jolt/Core/TickCounter.h>
  5. #if defined(JPH_PLATFORM_WINDOWS)
  6. JPH_SUPPRESS_WARNING_PUSH
  7. JPH_MSVC_SUPPRESS_WARNING(5039) // winbase.h(13179): warning C5039: 'TpSetCallbackCleanupGroup': pointer or reference to potentially throwing function passed to 'extern "C"' function under -EHc. Undefined behavior may occur if this function throws an exception.
  8. #define WIN32_LEAN_AND_MEAN
  9. #include <Windows.h>
  10. JPH_SUPPRESS_WARNING_POP
  11. #elif defined(JPH_PLATFORM_LINUX) || defined(JPH_PLATFORM_ANDROID)
  12. #include <fstream>
  13. #elif defined(JPH_PLATFORM_MACOS) || defined(JPH_PLATFORM_IOS)
  14. #include <sys/types.h>
  15. #include <sys/sysctl.h>
  16. #endif
  17. JPH_NAMESPACE_BEGIN
  18. #ifdef JPH_PLATFORM_WINDOWS_UWP
  19. uint64 GetProcessorTickCount()
  20. {
  21. LARGE_INTEGER count;
  22. QueryPerformanceCounter(&count);
  23. return uint64(count.QuadPart);
  24. }
  25. #endif // JPH_PLATFORM_WINDOWS_UWP
  26. static const uint64 sProcessorTicksPerSecond = []() {
  27. #if defined(JPH_PLATFORM_WINDOWS_UWP)
  28. LARGE_INTEGER frequency { };
  29. QueryPerformanceFrequency(&frequency);
  30. return uint64(frequency.QuadPart);
  31. #elif defined(JPH_PLATFORM_WINDOWS)
  32. // Open the key where the processor speed is stored
  33. HKEY hkey;
  34. RegOpenKeyExA(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0, 1, &hkey);
  35. // Query the speed in MHz
  36. uint mhz = 0;
  37. DWORD mhz_size = sizeof(uint);
  38. RegQueryValueExA(hkey, "~MHz", nullptr, nullptr, (LPBYTE)&mhz, &mhz_size);
  39. // Close key
  40. RegCloseKey(hkey);
  41. // Initialize amount of cycles per second
  42. return uint64(mhz) * 1000000UL;
  43. #elif defined(JPH_PLATFORM_BLUE)
  44. return JPH_PLATFORM_BLUE_GET_TICK_FREQUENCY();
  45. #elif defined(JPH_PLATFORM_LINUX) || defined(JPH_PLATFORM_ANDROID)
  46. // Open /proc/cpuinfo
  47. ifstream ifs("/proc/cpuinfo");
  48. if (ifs.is_open())
  49. {
  50. // Read all lines
  51. while (ifs.good())
  52. {
  53. // Get next line
  54. string line;
  55. getline(ifs, line);
  56. #if defined(JPH_CPU_X86)
  57. const char *cpu_str = "cpu MHz";
  58. #elif defined(JPH_CPU_ARM64)
  59. const char *cpu_str = "BogoMIPS";
  60. #else
  61. #error Unsupported CPU architecture
  62. #endif
  63. // Check if line starts with correct string
  64. const size_t num_chars = strlen(cpu_str);
  65. if (strncmp(line.c_str(), cpu_str, num_chars) == 0)
  66. {
  67. // Find ':'
  68. string::size_type pos = line.find(':', num_chars);
  69. if (pos != String::npos)
  70. {
  71. // Convert to number
  72. string freq = line.substr(pos + 1);
  73. return uint64(stod(freq) * 1000000.0);
  74. }
  75. }
  76. }
  77. }
  78. JPH_ASSERT(false);
  79. return uint64(0);
  80. #elif defined(JPH_PLATFORM_MACOS) || defined(JPH_PLATFORM_IOS)
  81. // Use sysctl to get the processor frequency
  82. int mib[2];
  83. mib[0] = CTL_HW;
  84. mib[1] = HW_CPU_FREQ;
  85. uint64 freq = 1;
  86. size_t len = sizeof(freq);
  87. sysctl(mib, 2, &freq, &len, nullptr, 0);
  88. return freq;
  89. #else
  90. #error Undefined
  91. #endif
  92. }();
  93. uint64 GetProcessorTicksPerSecond()
  94. {
  95. return sProcessorTicksPerSecond;
  96. }
  97. JPH_NAMESPACE_END