添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

Hello everybody,

I try to set a finer timer resolution in kernel mode and thus read about ExSetTimerResolution, NtSetTimerResolution and NtQueryTimerResolution from various sources, including here. What I want to do is to make a KTIMER plus KDPC that has been scheduled via KeSetTimer() fire with a smaller time interval than the usual 10 or 15ms.

Right now, I can measure how many timer callbacks I get and it’s 64 per 1 sec on my Win2k3 box, 100 on my XP box. I would like to increase that number (of course they should be sort of evenly spaced).

From what I read I assumed that using ExSetTimerResolution(50000, TRUE) would do exactly this, i.e. in my example generate about 200 callbacks per 1 sec. Unfortunately, the effect is exactly zero. Nothing changes at all, exept that a call to ExSetTimerResolution(1000000, TRUE) (some very high value) returns about 50000, the formerly set value. So it *says* it did it, but didn’t do it :slight_smile: ??

I even tried to use NtSetTimerResolution() from user mode via native API, same effect, i.e. the return value suggests success, but nothing changes.

I tried this on two machines: one running Windows Server 2003 Multiprocessor Free (2 procs) v5.02.3790.4035, SP2 (15 ms resolution) and one running Windows XP Uniprocessor Free v5.01.2600, SP2 (10 ms resolution).

At last, I tried to change the clock resolution with the BOOT.INI switch /TIMERES=21000, as is suggested in Windows Internals. Same here, no effect at all. Here, even ExSetTimerResolution(1000000, TRUE) returns the default value.

Mark’s CLOCKRES tool always prints the default value (15 ms resp. 10 ms).

So, I’m wondering, what did I do wrong? Or is what I’m trying to do unsupported in the first place?

Please help & take care,
Chris

[email protected] wrote:

I try to set a finer timer resolution in kernel mode and thus read about ExSetTimerResolution, NtSetTimerResolution and NtQueryTimerResolution from various sources, including here. What I want to do is to make a KTIMER plus KDPC that has been scheduled via KeSetTimer() fire with a smaller time interval than the usual 10 or 15ms.

Right now, I can measure how many timer callbacks I get and it’s 64 per 1 sec on my Win2k3 box, 100 on my XP box. I would like to increase that number (of course they should be sort of evenly spaced).

I have to give you the standard timer disclaimer: Windows is not a
real-time operating system. There are no guarantees about
responsiveness and latency. Even if you increase the timer value, a
misbehaving driver can easily cause you to miss ticks.

I even tried to use NtSetTimerResolution() from user mode via native API, same effect, i.e. the return value suggests success, but nothing changes.

Before giving up, you might try using timeBeginPeriod from user-mode.
For me, that makes a Sleep(1) actually take 1 ms.

Tim Roberts, [email protected]
Providenza & Boekelheide, Inc.

Jumping Jehova! You’re right.

It seems I got caught in the tangles of my own code. Since GetTickCount() doesn’t increase the resolution (and some coding flaw), I didn’t detect the higher timer rate.

Great, thanks.

Now, there is one more (minor) question: is there a GetTickCount()-like function that returns the “real” number of msec since system start? I.e., one that uses the higher timer resolution? I know I can use the perfcounter or RDTSC, but I’m looking for an easier method, since both perfcounter and RDTSC sometimes have their problems.

Hello,

I’m not sure I have understood your reply, but KeQueryInterruptTime might be what you want.

By the way, ExSetTimerResolution is a bit problematic.
Martin Puryear wrote:

This particular DDI still exists mainly because it is not abused.
( http://www.freelists.org/archives/wdmaudiodev/07-2003/msg00070.html )

Actually, ExSetTimerResolution is the guts of the user space mult-media
timers. It has been around for a long time, just undocumented. Most of
the abuse comes from user space.

Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr
Remove StopSpam to reply

wrote in message news:xxxxx@ntdev…
> Hello,
>
> I’m not sure I have understood your reply, but KeQueryInterruptTime might
> be what you want.
>
> By the way, ExSetTimerResolution is a bit problematic.
> Martin Puryear wrote:
>> This particular DDI still exists mainly because it is not abused.
> ( http://www.freelists.org/archives/wdmaudiodev/07-2003/msg00070.html )
>

[email protected] wrote:

Now, there is one more (minor) question: is there a GetTickCount()-like function that returns the “real” number of msec since system start? I.e., one that uses the higher timer resolution? I know I can use the perfcounter or RDTSC, but I’m looking for an easier method, since both perfcounter and RDTSC sometimes have their problems.

What do you mean by “real number of msec”? GetTickCount is updated at
every timer interrupt, and uses the current resolution to bump its
counter. It is probably the most consistent of the timing APIs. The
uniprocessor version of QueryPerformanceCounter uses GetTickCount, and
adjusts it by the value of the countdown register in the timer.

If you really need accurate, long-term, millisecond-level timing, you
need to buy a real-time clock board.

Tim Roberts, [email protected]
Providenza & Boekelheide, Inc.

The uniprocessor version of QueryPerformanceCounter uses GetTickCount,
and adjusts it by the value of the countdown register in the timer.

This is most certainly wrong.
The system clock’s granularity is far too low for a high-precision counter.

On uniprocessor systems, QPC might use RDTSC, the 8254 PIT, the ACPI PM timer or HPET.

Tim Roberts wrote:

> The uniprocessor version of QueryPerformanceCounter uses GetTickCount,
> and adjusts it by the value of the countdown register in the timer.

This is most certainly wrong.
The system clock’s granularity is far too low for a high-precision counter.

Nope, I am correct. Here are the details for the older systems; the
exact counts are different on 2K and beyond, but the principle is the same.

The 8254 PIT is fed a clock of 1.19 MHz. All that the 8254 can do is
decrement a timer, and fire an interrupt when it goes to zero. The
timer is 16 bits, and it is programmed to interrupt every 65,536
clocks. This results in an interrupt every 54.5ms, that familiar number
from DOS days. During that interrupt, the GetTickCount counter is
updated, and the scheduling runs.

What QueryPerformanceCounter does in a standard uniprocessor HAL is read
the current value of the countdown timer from the 8254. That tells it
how many clocks have elapsed since the last interrupt. It adds that
offset to the GetTickCount value (scaled) and returns it. Just that simple.

On uniprocessor systems, QPC might use RDTSC, the 8254 PIT, the ACPI PM timer or HPET.

Unless you have a custom HAL, QPC on a uniprocessor system uses the
8254. On a multiprocessor system, it uses RDTSC.

Tim Roberts, [email protected]
Providenza & Boekelheide, Inc.

Nope, I am correct. […]
Thanks, that’s a plausible explanation. I should have exercised more modesty.

Tim Roberts wrote:

Unless you have a custom HAL,
QPC on a uniprocessor system uses the 8254.
That might have been true for Windows 2000 (and below?), but if you disassemble halacpi.dll (x86-32, 6.0.6000.16386), KeQueryPerformanceCounter conditionally jumps to subroutines named “HalpHpetQueryPerformanceCounter”, “HalpBrokenPmTimerQueryPerformanceCounter” & “HalpPmTimerQueryPerformanceCounter”.

Tim Roberts wrote:

> Unless you have a custom HAL,
> QPC on a uniprocessor system uses the 8254.
That might have been true for Windows 2000 (and below?), but if you disassemble halacpi.dll (x86-32, 6.0.6000.16386), KeQueryPerformanceCounter conditionally jumps to subroutines named “HalpHpetQueryPerformanceCounter”, “HalpBrokenPmTimerQueryPerformanceCounter” & “HalpPmTimerQueryPerformanceCounter”.

KQPC has always vectored directly into the HAL – that’s why the
mechanism varies based on the HAL in use.

That’s the ACPI HAL for Vista. The ACPI HAL is different from the basic
uniprocessor HAL (hal.dll).

Tim Roberts, [email protected]
Providenza & Boekelheide, Inc.