Repository navigation
Description
User story
As an engineer running Motion Master on a Windows PC,
I want the RT loop to keep its period when Windows saves power, and to be told when it does not,
so that a slow loop cannot fail file reads, abort a procedure or trip the drive's watchdog without a trace.
Context
A loop that waits with timeSetEvent depends on the timer resolution the process asks for with timeBeginPeriod. Since Windows 11, Windows does not guarantee that resolution to a window-owning process that is minimised, covered or otherwise unseen (timeBeginPeriod). Such a loop then falls to the default timer tick of 15.625 ms, about 64 cycles per second.
Motion Master waits differently. libs/core/cyclic_timer_windows.cc arms a one-shot waitable timer created with CREATE_WAITABLE_TIMER_HIGH_RESOLUTION (Windows 10 1803 or newer) each cycle, on a grid kept with QueryPerformanceCounter, and never calls timeBeginPeriod. Such a timer has its own resolution (CreateWaitableTimerExW), so that cause most likely does not apply. No Microsoft documentation says how this timer behaves under power throttling, and nothing has measured it.
Five gaps remain:
- The timer is not checked.
CreateWaitableTimerExWreturns NULL on failure, for example on Windows before 10 1803, andCyclicTimerkeeps the NULL handle.SetWaitableTimerthen fails andWaitForSingleObjectreturns at once, so the RT loop runs with no wait at all. - No power-throttling opt-out. Nothing calls
SetProcessInformation(ProcessPowerThrottling, ...). EcoQoS lowers the CPU frequency or moves the process to efficiency cores, whatever timer it uses. WithPROCESS_POWER_THROTTLING_EXECUTION_SPEEDin ControlMask and a StateMask of 0 a process asks for HighQoS, and withPROCESS_POWER_THROTTLING_IGNORE_TIMER_RESOLUTIONit asks Windows to always honour its timer resolution requests. - A low cycle rate is silent.
GameLoopcounts skipped cycles andGET /api/game-loopreports them, but nothing logs or notifies. A loop running at a fraction of its rate shows nowhere unless somebody opens that page. - Not measured on Windows 11 with the window minimised or covered, on battery saver, or in Efficiency mode.
- An outdated comment.
cyclic_timer_windows.ccsaystimeBeginPeriodis "a system-wide change that affects all processes". Since Windows 10, version 2004, it no longer changes the global timer resolution (timeBeginPeriod). The reason to avoid it is now the Windows 11 rule above.
Acceptance criteria
-
CyclicTimeron Windows checks the handleCreateWaitableTimerExWreturns. On failure it does not run the loop without a wait: it fails at startup with a message that names the Windows version requirement, or falls back to a timer that waits. - On Windows, startup calls
SetProcessInformation(ProcessPowerThrottling, ...)withPROCESS_POWER_THROTTLING_EXECUTION_SPEEDandPROCESS_POWER_THROTTLING_IGNORE_TIMER_RESOLUTIONin ControlMask and a StateMask of 0, and logs a warning when the call fails. - A NotificationBus source warns when the loop skips cycles at a sustained rate, with the measured cycle rate, and says again when the rate is back. It logs as well as notifies, like the short working counter source in
apps/motion_master/bus_health_source.{h,cc}. The threshold is stated, and a short burst at startup or after a period change does not trigger it. - The comment in
cyclic_timer_windows.ccsays whytimeBeginPeriodis avoided as Windows 10 2004 and Windows 11 have it. - On a Windows 11 laptop, the cycle rate is measured with the window of the Console minimised and covered, on battery saver, and with Efficiency mode set on the process in Task Manager, before and after the opt-out. The results go in this issue.
Out of scope
- Real-time priority on Windows.
libs/core/realtime.{h,cc}has no Windows path on purpose.
References
libs/core/cyclic_timer_windows.cc,libs/core/cyclic_timer.h,libs/core/realtime.{h,cc}apps/motion_master/game_loop.h,apps/motion_master/bus_health_source.{h,cc}
Activity
markosankovic commentedon Oct 29, 2026
Decisions (2026-10-29)
setRealtimePriorityinlibs/core/realtime.cc. A failed call is a warning, not fatal.cyclic_timer_windows.ccis corrected.feat: keep the RT loop period on Windows, and log a slow loop
feat: keep the RT loop period on Windows, and log a slow loop (#164)
markosankovic commentedon Oct 29, 2026
Reopened: the measurement on a Windows 11 laptop is still open. #164 closed it through a closing keyword in a commit of its branch.