Opened 6 years ago

Closed 6 years ago

Last modified 5 years ago

#12744 closed Bugs (fixed)

winapi::set_timer_resolution inadvertently changes timer resolution (Windows)

Reported by: Terry Kim <yuminkim@…> Owned by: Ion Gaztañaga
Milestone: To Be Determined Component: interprocess
Version: Boost 1.63.0 Severity: Problem
Keywords: timer resolution Cc:

Description

boost::interprocess::ipcdetail::spin_wait calls get_system_tick_in_highres_counts(), which ultimately calls winapi::set_timer_resolution() to get the current timer resolution. However, this changes the timer resolution inadvertently.

I verified this with PwrTest.exe (https://msdn.microsoft.com/windows/hardware/drivers/devtest/pwrtest).

Can we use winapi::query_timer_resolution() instead of winapi::set_timer_resolution()?

Change History (3)

comment:1 by Ion Gaztañaga, 6 years ago

In theory the second parameter is set_timer_resolution is zero, which should not change the current resolution. But if you verified the change, then your suggestion seems the right way to go.

comment:2 by Ion Gaztañaga, 6 years ago

Resolution: fixed
Status: newclosed

comment:3 by anonymous, 5 years ago

I know this bug is closed, but I wanted to add a comment explaining the previous behavior. I just spent 2 days tracking down why our timer resolution was getting messed up. (We were using a previous Boost version).

First of all, the call to NtSetTimerResolution is a private ntdll function. Not an API you should be using, or especially assuming the behavior of. There is no official documentation. The second argument (called 'set') that was false, is not meant to be a benign query of the timer resolution. Instead, it 'unsets' the process's request for a custom timer resolution. This would be used by the proper Public api in winmm.dll and the calls for timeBeginPeriod/timeEndPeriod.

By calling NtSetTimerResolution with set=false. Future calls to timeBeginPeriod/timeEndPeriod had no effect if there was already a timeBeginPeriod call outstanding. Most likely winmm (which likely tracks the pairs of timeBeginPeriod/timeEndPeriod calls) was now out of sync with its interaction with ntdll.

Note: See TracTickets for help on using tickets.