mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-19 00:41:43 +00:00
[hal] Fix Java sim timing on Windows (#6910)
Also set power throttling options correctly.
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#pragma comment(lib, "Winmm.lib")
|
||||
#pragma comment(lib, "ntdll.lib")
|
||||
extern "C" NTSYSAPI NTSTATUS NTAPI NtSetTimerResolution(
|
||||
ULONG DesiredResolution, BOOLEAN SetResolution, PULONG CurrentResolution);
|
||||
@@ -371,6 +372,19 @@ HAL_Bool HAL_Initialize(int32_t timeout, int32_t mode) {
|
||||
|
||||
// Set Timer Precision to 0.5ms on Windows
|
||||
#ifdef _WIN32
|
||||
// Use timeGetDevCaps as well to prevent Java from interfering
|
||||
TIMECAPS tc;
|
||||
if (timeGetDevCaps(&tc, sizeof(tc)) == TIMERR_NOERROR) {
|
||||
UINT target = (std::max)(static_cast<UINT>(1), tc.wPeriodMin);
|
||||
timeBeginPeriod(target);
|
||||
std::atexit([]() {
|
||||
TIMECAPS tc;
|
||||
if (timeGetDevCaps(&tc, sizeof(tc)) == TIMERR_NOERROR) {
|
||||
UINT target = (std::max)(static_cast<UINT>(1), tc.wPeriodMin);
|
||||
timeEndPeriod(target);
|
||||
}
|
||||
});
|
||||
}
|
||||
// https://stackoverflow.com/questions/3141556/how-to-setup-timer-resolution-to-0-5-ms
|
||||
ULONG min, max, current;
|
||||
if (NtQueryTimerResolution(&min, &max, ¤t) == 0) {
|
||||
@@ -385,31 +399,33 @@ HAL_Bool HAL_Initialize(int32_t timeout, int32_t mode) {
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setprocessinformation
|
||||
// Enable HighQoS to achieve maximum performance, and turn off power saving.
|
||||
{
|
||||
PROCESS_POWER_THROTTLING_STATE PowerThrottling{};
|
||||
PowerThrottling.Version = PROCESS_POWER_THROTTLING_CURRENT_VERSION;
|
||||
PowerThrottling.ControlMask = PROCESS_POWER_THROTTLING_EXECUTION_SPEED;
|
||||
PowerThrottling.StateMask = 0;
|
||||
|
||||
SetProcessInformation(GetCurrentProcess(), ProcessPowerThrottling,
|
||||
&PowerThrottling, sizeof(PowerThrottling));
|
||||
}
|
||||
|
||||
// https://forums.oculusvr.com/t5/General/SteamVR-has-fixed-the-problems-with-Windows-11/td-p/956413
|
||||
// Always honor Timer Resolution Requests. This is to ensure that the timer
|
||||
// resolution set-up above sticks through transitions of the main window (eg:
|
||||
// minimization).
|
||||
{
|
||||
// This setting was introduced in Windows 11 and the definition is not
|
||||
// available in older headers.
|
||||
// This setting was introduced in Windows 11 and the definition is not
|
||||
// available in older headers.
|
||||
#ifndef PROCESS_POWER_THROTTLING_IGNORE_TIMER_RESOLUTION
|
||||
const auto PROCESS_POWER_THROTTLING_IGNORE_TIMER_RESOLUTION = 0x4U;
|
||||
const auto PROCESS_POWER_THROTTLING_IGNORE_TIMER_RESOLUTION = 0x4U;
|
||||
#endif
|
||||
|
||||
PROCESS_POWER_THROTTLING_STATE PowerThrottling{};
|
||||
// Try both at once, and if that doesn't succeed, only set HighQoS
|
||||
PROCESS_POWER_THROTTLING_STATE PowerThrottling{};
|
||||
PowerThrottling.Version = PROCESS_POWER_THROTTLING_CURRENT_VERSION;
|
||||
PowerThrottling.ControlMask =
|
||||
PROCESS_POWER_THROTTLING_IGNORE_TIMER_RESOLUTION |
|
||||
PROCESS_POWER_THROTTLING_EXECUTION_SPEED;
|
||||
PowerThrottling.StateMask = 0;
|
||||
|
||||
auto status =
|
||||
SetProcessInformation(GetCurrentProcess(), ProcessPowerThrottling,
|
||||
&PowerThrottling, sizeof(PowerThrottling));
|
||||
|
||||
// setting both failed, fall back to HighQoS only
|
||||
if (status == 0) {
|
||||
PowerThrottling.Version = PROCESS_POWER_THROTTLING_CURRENT_VERSION;
|
||||
PowerThrottling.ControlMask =
|
||||
PROCESS_POWER_THROTTLING_IGNORE_TIMER_RESOLUTION;
|
||||
PowerThrottling.ControlMask = PROCESS_POWER_THROTTLING_EXECUTION_SPEED;
|
||||
PowerThrottling.StateMask = 0;
|
||||
|
||||
SetProcessInformation(GetCurrentProcess(), ProcessPowerThrottling,
|
||||
|
||||
Reference in New Issue
Block a user