mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-07-05 03:21:42 +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
|
#ifdef _WIN32
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
#pragma comment(lib, "Winmm.lib")
|
||||||
#pragma comment(lib, "ntdll.lib")
|
#pragma comment(lib, "ntdll.lib")
|
||||||
extern "C" NTSYSAPI NTSTATUS NTAPI NtSetTimerResolution(
|
extern "C" NTSYSAPI NTSTATUS NTAPI NtSetTimerResolution(
|
||||||
ULONG DesiredResolution, BOOLEAN SetResolution, PULONG CurrentResolution);
|
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
|
// Set Timer Precision to 0.5ms on Windows
|
||||||
#ifdef _WIN32
|
#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
|
// https://stackoverflow.com/questions/3141556/how-to-setup-timer-resolution-to-0-5-ms
|
||||||
ULONG min, max, current;
|
ULONG min, max, current;
|
||||||
if (NtQueryTimerResolution(&min, &max, ¤t) == 0) {
|
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
|
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setprocessinformation
|
||||||
// Enable HighQoS to achieve maximum performance, and turn off power saving.
|
// 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
|
// 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
|
// Always honor Timer Resolution Requests. This is to ensure that the timer
|
||||||
// resolution set-up above sticks through transitions of the main window (eg:
|
// resolution set-up above sticks through transitions of the main window (eg:
|
||||||
// minimization).
|
// minimization).
|
||||||
{
|
// This setting was introduced in Windows 11 and the definition is not
|
||||||
// This setting was introduced in Windows 11 and the definition is not
|
// available in older headers.
|
||||||
// available in older headers.
|
|
||||||
#ifndef PROCESS_POWER_THROTTLING_IGNORE_TIMER_RESOLUTION
|
#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
|
#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.Version = PROCESS_POWER_THROTTLING_CURRENT_VERSION;
|
||||||
PowerThrottling.ControlMask =
|
PowerThrottling.ControlMask = PROCESS_POWER_THROTTLING_EXECUTION_SPEED;
|
||||||
PROCESS_POWER_THROTTLING_IGNORE_TIMER_RESOLUTION;
|
|
||||||
PowerThrottling.StateMask = 0;
|
PowerThrottling.StateMask = 0;
|
||||||
|
|
||||||
SetProcessInformation(GetCurrentProcess(), ProcessPowerThrottling,
|
SetProcessInformation(GetCurrentProcess(), ProcessPowerThrottling,
|
||||||
|
|||||||
Reference in New Issue
Block a user