TickCounter.cpp 3.3 KB

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