TickCounter.cpp 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  2. // SPDX-License-Identifier: MIT
  3. #include <Jolt.h>
  4. #include <Core/TickCounter.h>
  5. #if defined(JPH_PLATFORM_WINDOWS)
  6. #pragma warning (push, 0)
  7. #pragma warning (disable : 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. #pragma warning (pop)
  11. #elif defined(JPH_PLATFORM_LINUX) || defined(JPH_PLATFORM_ANDROID)
  12. #include <fstream>
  13. #endif
  14. namespace JPH {
  15. static const uint64 sProcessorTicksPerSecond = []() {
  16. #if defined(JPH_PLATFORM_WINDOWS)
  17. // Open the key where the processor speed is stored
  18. HKEY hkey;
  19. RegOpenKeyExA(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0, 1, &hkey);
  20. // Query the speed in MHz
  21. uint mhz = 0;
  22. DWORD mhz_size = sizeof(uint);
  23. RegQueryValueExA(hkey, "~MHz", nullptr, nullptr, (LPBYTE)&mhz, &mhz_size);
  24. // Close key
  25. RegCloseKey(hkey);
  26. // Initialize amount of cycles per second
  27. return uint64(mhz) * 1000000UL;
  28. #elif defined(JPH_PLATFORM_BLUE)
  29. return JPH_PLATFORM_BLUE_GET_TICK_FREQUENCY();
  30. #elif defined(JPH_PLATFORM_LINUX) || defined(JPH_PLATFORM_ANDROID)
  31. // Open /proc/cpuinfo
  32. ifstream ifs("/proc/cpuinfo");
  33. if (ifs.is_open())
  34. {
  35. // Read all lines
  36. while (ifs.good())
  37. {
  38. // Get next line
  39. string line;
  40. getline(ifs, line);
  41. #if defined(JPH_CPU_X64)
  42. const char *cpu_str = "cpu MHz";
  43. #elif defined(JPH_CPU_ARM64)
  44. const char *cpu_str = "BogoMIPS";
  45. #else
  46. #error Unsupported CPU architecture
  47. #endif
  48. // Check if line starts with correct string
  49. const size_t num_chars = strlen(cpu_str);
  50. if (strncmp(line.c_str(), cpu_str, num_chars) == 0)
  51. {
  52. // Find ':'
  53. string::size_type pos = line.find(':', num_chars);
  54. if (pos != string::npos)
  55. {
  56. // Convert to number
  57. string freq = line.substr(pos + 1);
  58. return uint64(stod(freq) * 1000000.0);
  59. }
  60. }
  61. }
  62. }
  63. JPH_ASSERT(false);
  64. return uint64(0);
  65. #else
  66. #error Undefined
  67. #endif
  68. }();
  69. uint64 GetProcessorTicksPerSecond()
  70. {
  71. return sProcessorTicksPerSecond;
  72. }
  73. } // JPH