TickCounter.cpp 2.6 KB

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