As I saw the word ‘synchronize’ I thought I’d jump in with a warning, in
case anyone is about to use the performance counter on MPS systems or rdtsc
instruction directly to get the clock time with a better resolution than
the scheduler’s 10-15 millis.
The basic idea is that you synchronize the system time to a specific
counter value and then use the counter to get time stamps with better
resolution (note: we’re talking clock timestamps here, like
‘12:23:34.12345’). Some things you’ll have to be aware of:
* You’ll have to synchronize the counter value to the system time exactly
when it (the system time) changes to avoid a constant offset of +/- tick
period (this is obvious).
This is a simplified method on how to perform the synchronization:
* Get counter frequency using KeQueryPerformanceFrequency.
* Busy spin (at an elevated IRQL/thread priority) calling KeQuerySystemTime
until it changes.
* Get counter value using KeQueryPerformanceCounter.
* Store these values as your base for you calculations.
Once this is done, each time you need the clock time - use the elapsed
counter ticks since synchronization in combination with the frequency to
get the amount of millis/micros/whatever since the synchronization. Add
this to the base time at that point and you’ll have ‘continuously’ updated
clock time.
BUT: Note that the performance frequency reported is not entirely accurate.
On my system (dual PIII@550MHz) the error is ~8 ppm. This results in a
situation where the calculated time ‘drifts’ away from the real system
time, resulting in milliseconds offsets after some time. What ‘some time’
means is of course hardware dependent, in my case t’was something like
1ms/minute on a dual PII@400MHz.
I guess that there are ways of getting round this, a few suggestions:
* Periodically resynchronize (not too often, as busy spinning takes down
the overall performance of the system).
* Determine the frequency more accurately (could be done by a supporting
driver, or background thread, or service in UM that continously
measures/calibrates the CPU frequency).
I’ve tried both, but there are still some problems with the approaches. Not
mentioning the fact that someone might actually change the system time
after after/between synchronizations …
Disclaimer: My results are totally based on user-mode experiences, but
should hold in KM as well.
If anyone here has been doing the same stuff (and succeeded), please drop
me an direct e-mail in case you don’t want to post something to this list.
Regards,
Johan
On 06/26/01, ““Thomas F. Divine” ” wrote:
> I don’t recall if there is a Win32 clone.
>
> In my drivers I define an IOCTL to fetch a structure containing two value=
> s:
> 1.) the current value returned from KeQueryPerformanceCounter and 2.) the
> frequency value. These values can be used to synchronize time and to scal=
> e
> time.
>
> There may be a better way…
>
> Regards,
>
> Thomas F. Divine
>
> PCAUSA - Toolkits & Resources For Network Software Developers
> NDIS Protocol - NDIS Intermediate - TDI Client
> http: - http:
>
>
> ----- Original Message -----
> From: “Chen Miaobo”
> To: “NT Developers Interest List”
> Sent: Tuesday, June 26, 2001 9:47 PM
> Subject: [ntdev] Re: Clock resolution on a PC and WinNT
>
>
> > Does this KeQueryPerformanceCounter function have its Win32 API clone?
> >
> > Regards,
> >
> >
> > ----- Original Message -----
> > From: Norbert Kawulski
> > To: NT Developers Interest List
> > Sent: Tuesday, June 26, 2001 11:48 PM
> > Subject: [ntdev] Re: Clock resolution on a PC and WinNT
> >
> >
> > > Tim,
> > > you are 100% right. My point was to show that
> > > KeQueryPerformanceCounter would do no more harm as that dumb
> > > while-loop does anyhow. The thing is that I associate measuring time
> > > with KeQueryPerformanceCounter. Next thing I thought was: ‘Oh, people
> > > might poll this within a while-loop. Ah, that is it, what MS does not
> > > want to be done with this function."
> > > -----------------------------------------------------------------
> > > | Norbert Kawulski | mailto:xxxxx@stollmann.de |
> > > | Stollmann T.P.GmbH, Development | http://www.stollmann.de |
> > > --If it’s ISDN or Bluetooth, make sure it’s driven by Stollmann–
> > >
> > > “All that glitters has a high refractive index.”
> > >
> > >
> > > > While certainly less intrusive than polling at DISPATCH_LEVEL or in=
> an
> ISR,
> > > > running such a loop at PASSIVE_LEVEL does indeed prevent any thread=
> s
> with
> > > > lesser priority from running, and takes time away from other thread=
> s
> of the
> > > > same priority that may have useful work to do. The CPU usage would
> also be
> > > > pegged at 100%.
> > >
> > > > Additionally, using such a loop at PASSIVE_LEVEL is unlikely to
> consistantly
> > > > result in much better resolution than using KeDelayExecutionThread(=
> ).
> The
> > > > scheduler’s still going to run those other same-or-higher priority
> threads
> > > > in the system, which very well might be running at t+5000l. The
> result
> > > > would be that the while() condition check may not execute again unt=
> il
> after
> > > > the other thread(s) run.
> > >
> > > > -Tim
> > >
> > > > Timothy A. Johns — xxxxx@driverdev.com
> > > > Driver Development Corporation — 800.841.0092
> > > > Bring Up Your Hardware — Fast. www.driverdev.com
> > > ------- cut------------------
> > >
> > >
> > >
> > > —
> > > You are currently subscribed to ntdev as: xxxxx@sdtm.online.sh.c=
> n
> > > To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com
> >
> b> =BA=C6o=A2d=E8=BA{.n=C7+?=B7=ACzwZnV=A7’=E9sS[h.=E6=AFz{]z=FDy=E0=B9b=B2=DB=
> (=B2
> =B7(
>
>
> —
> You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
> To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com
—
You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com</http:></http:>