Backlog/lib/zphysics/libs/Jolt/Core/TickCounter.cpp

121 lines
3.3 KiB
C++

// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
// SPDX-License-Identifier: MIT
#include <Jolt/Jolt.h>
#include <Jolt/Core/TickCounter.h>
#if defined(JPH_PLATFORM_WINDOWS)
JPH_SUPPRESS_WARNING_PUSH
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.
#define WIN32_LEAN_AND_MEAN
#ifndef JPH_COMPILER_MINGW
#include <Windows.h>
#else
#include <windows.h>
#endif
JPH_SUPPRESS_WARNING_POP
#elif defined(JPH_PLATFORM_LINUX) || defined(JPH_PLATFORM_ANDROID)
#include <fstream>
#elif defined(JPH_PLATFORM_MACOS) || defined(JPH_PLATFORM_IOS)
#include <sys/types.h>
#include <sys/sysctl.h>
#endif
JPH_NAMESPACE_BEGIN
#if defined(JPH_PLATFORM_WINDOWS_UWP) || (defined(JPH_PLATFORM_WINDOWS) && defined(JPH_CPU_ARM))
uint64 GetProcessorTickCount()
{
LARGE_INTEGER count;
QueryPerformanceCounter(&count);
return uint64(count.QuadPart);
}
#endif // JPH_PLATFORM_WINDOWS_UWP || (JPH_PLATFORM_WINDOWS && JPH_CPU_ARM)
static const uint64 sProcessorTicksPerSecond = []() {
#if defined(JPH_PLATFORM_WINDOWS_UWP) || (defined(JPH_PLATFORM_WINDOWS) && defined(JPH_CPU_ARM))
LARGE_INTEGER frequency { };
QueryPerformanceFrequency(&frequency);
return uint64(frequency.QuadPart);
#elif defined(JPH_PLATFORM_WINDOWS)
// Open the key where the processor speed is stored
HKEY hkey;
RegOpenKeyExA(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0, 1, &hkey);
// Query the speed in MHz
uint mhz = 0;
DWORD mhz_size = sizeof(uint);
RegQueryValueExA(hkey, "~MHz", nullptr, nullptr, (LPBYTE)&mhz, &mhz_size);
// Close key
RegCloseKey(hkey);
// Initialize amount of cycles per second
return uint64(mhz) * 1000000UL;
#elif defined(JPH_PLATFORM_BLUE)
return JPH_PLATFORM_BLUE_GET_TICK_FREQUENCY();
#elif defined(JPH_PLATFORM_LINUX) || defined(JPH_PLATFORM_ANDROID)
// Open /proc/cpuinfo
std::ifstream ifs("/proc/cpuinfo");
if (ifs.is_open())
{
// Read all lines
while (ifs.good())
{
// Get next line
string line;
getline(ifs, line);
#if defined(JPH_CPU_X86)
const char *cpu_str = "cpu MHz";
#elif defined(JPH_CPU_ARM)
const char *cpu_str = "BogoMIPS";
#else
#error Unsupported CPU architecture
#endif
// Check if line starts with correct string
const size_t num_chars = strlen(cpu_str);
if (strncmp(line.c_str(), cpu_str, num_chars) == 0)
{
// Find ':'
string::size_type pos = line.find(':', num_chars);
if (pos != String::npos)
{
// Convert to number
string freq = line.substr(pos + 1);
return uint64(stod(freq) * 1000000.0);
}
}
}
}
JPH_ASSERT(false);
return uint64(0);
#elif defined(JPH_PLATFORM_MACOS) || defined(JPH_PLATFORM_IOS)
// Use sysctl to get the processor frequency
int mib[2];
mib[0] = CTL_HW;
mib[1] = HW_CPU_FREQ;
uint64 freq = 1;
size_t len = sizeof(freq);
sysctl(mib, 2, &freq, &len, nullptr, 0);
return freq;
#elif defined(JPH_PLATFORM_WASM)
return 1; // Not supported
#else
#error Undefined
#endif
}();
uint64 GetProcessorTicksPerSecond()
{
return sProcessorTicksPerSecond;
}
JPH_NAMESPACE_END