2
0

TickCounter.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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. #ifndef JPH_COMPILER_MINGW
  10. #include <Windows.h>
  11. #else
  12. #include <windows.h>
  13. #endif
  14. JPH_SUPPRESS_WARNING_POP
  15. #elif defined(JPH_PLATFORM_LINUX) || defined(JPH_PLATFORM_ANDROID)
  16. #include <fstream>
  17. #elif defined(JPH_PLATFORM_MACOS) || defined(JPH_PLATFORM_IOS)
  18. #include <sys/types.h>
  19. #include <sys/sysctl.h>
  20. #endif
  21. JPH_NAMESPACE_BEGIN
  22. #if defined(JPH_PLATFORM_WINDOWS_UWP) || (defined(JPH_PLATFORM_WINDOWS) && defined(JPH_CPU_ARM))
  23. uint64 GetProcessorTickCount()
  24. {
  25. LARGE_INTEGER count;
  26. QueryPerformanceCounter(&count);
  27. return uint64(count.QuadPart);
  28. }
  29. #endif // JPH_PLATFORM_WINDOWS_UWP || (JPH_PLATFORM_WINDOWS && JPH_CPU_ARM)
  30. static const uint64 sProcessorTicksPerSecond = []() {
  31. #if defined(JPH_PLATFORM_WINDOWS_UWP) || (defined(JPH_PLATFORM_WINDOWS) && defined(JPH_CPU_ARM))
  32. LARGE_INTEGER frequency { };
  33. QueryPerformanceFrequency(&frequency);
  34. return uint64(frequency.QuadPart);
  35. #elif defined(JPH_PLATFORM_WINDOWS)
  36. // Open the key where the processor speed is stored
  37. HKEY hkey;
  38. RegOpenKeyExA(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0, 1, &hkey);
  39. // Query the speed in MHz
  40. uint mhz = 0;
  41. DWORD mhz_size = sizeof(uint);
  42. RegQueryValueExA(hkey, "~MHz", nullptr, nullptr, (LPBYTE)&mhz, &mhz_size);
  43. // Close key
  44. RegCloseKey(hkey);
  45. // Initialize amount of cycles per second
  46. return uint64(mhz) * 1000000UL;
  47. #elif defined(JPH_PLATFORM_BLUE)
  48. return JPH_PLATFORM_BLUE_GET_TICK_FREQUENCY();
  49. #elif defined(JPH_PLATFORM_LINUX) || defined(JPH_PLATFORM_ANDROID)
  50. // Open /proc/cpuinfo
  51. std::ifstream ifs("/proc/cpuinfo");
  52. if (ifs.is_open())
  53. {
  54. // Read all lines
  55. while (ifs.good())
  56. {
  57. // Get next line
  58. string line;
  59. getline(ifs, line);
  60. #if defined(JPH_CPU_X86)
  61. const char *cpu_str = "cpu MHz";
  62. #elif defined(JPH_CPU_ARM)
  63. const char *cpu_str = "BogoMIPS";
  64. #else
  65. #error Unsupported CPU architecture
  66. #endif
  67. // Check if line starts with correct string
  68. const size_t num_chars = strlen(cpu_str);
  69. if (strncmp(line.c_str(), cpu_str, num_chars) == 0)
  70. {
  71. // Find ':'
  72. string::size_type pos = line.find(':', num_chars);
  73. if (pos != String::npos)
  74. {
  75. // Convert to number
  76. string freq = line.substr(pos + 1);
  77. return uint64(stod(freq) * 1000000.0);
  78. }
  79. }
  80. }
  81. }
  82. JPH_ASSERT(false);
  83. return uint64(0);
  84. #elif defined(JPH_PLATFORM_MACOS) || defined(JPH_PLATFORM_IOS)
  85. // Use sysctl to get the processor frequency
  86. int mib[2];
  87. mib[0] = CTL_HW;
  88. mib[1] = HW_CPU_FREQ;
  89. uint64 freq = 1;
  90. size_t len = sizeof(freq);
  91. sysctl(mib, 2, &freq, &len, nullptr, 0);
  92. return freq;
  93. #elif defined(JPH_PLATFORM_WASM)
  94. return 1; // Not supported
  95. #else
  96. #error Undefined
  97. #endif
  98. }();
  99. uint64 GetProcessorTicksPerSecond()
  100. {
  101. return sProcessorTicksPerSecond;
  102. }
  103. JPH_NAMESPACE_END