[ros-dev] [ros-diffs] [tkreuzer] 53496: [HAL] We cannot make any assumptions about the latency whith which the timer interrupt fires after a rollover, since VBox (other VMs probably as well) doesn't always meet this. Ad...
Alex Ionescu
ionucu at videotron.ca
Tue Aug 30 18:52:51 UTC 2011
Funny how Windows works without these hacks.
Let's hide more bugs :D
Best regards,
Alex Ionescu
On Tue, Aug 30, 2011 at 12:01 PM, <tkreuzer at svn.reactos.org> wrote:
> Author: tkreuzer
> Date: Tue Aug 30 12:01:01 2011
> New Revision: 53496
>
> URL: http://svn.reactos.org/svn/reactos?rev=53496&view=rev
> Log:
> [HAL]
> We cannot make any assumptions about the latency whith which the timer
> interrupt fires after a rollover, since VBox (other VMs probably as well)
> doesn't always meet this. Add another check to KeQueryPerformanceCounter
> that gracefully handles missing interrupts. Also raise to DISPATCH_LEVEL,
> since the function is not reentrant.
>
> Modified:
> trunk/reactos/hal/halx86/generic/timer.c
>
> Modified: trunk/reactos/hal/halx86/generic/timer.c
> URL:
> http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halx86/generic/timer.c?rev=53496&r1=53495&r2=53496&view=diff
>
> ==============================================================================
> --- trunk/reactos/hal/halx86/generic/timer.c [iso-8859-1] (original)
> +++ trunk/reactos/hal/halx86/generic/timer.c [iso-8859-1] Tue Aug 30
> 12:01:01 2011
> @@ -253,6 +253,7 @@
> {
> LARGE_INTEGER CurrentPerfCounter;
> ULONG CounterValue, ClockDelta;
> + KIRQL OldIrql;
>
> /* If caller wants performance frequency, return hardcoded value */
> if (PerformanceFrequency) PerformanceFrequency->QuadPart =
> PIT_FREQUENCY;
> @@ -262,6 +263,10 @@
>
> /* Check if interrupts are disabled */
> if(!(__readeflags() & EFLAGS_INTERRUPT_MASK)) return HalpPerfCounter;
> +
> + /* Raise irql to DISPATCH_LEVEL */
> + OldIrql = KeGetCurrentIrql();
> + if (OldIrql < DISPATCH_LEVEL) KfRaiseIrql(DISPATCH_LEVEL);
>
> do
> {
> @@ -287,13 +292,21 @@
> /* Add the clock delta */
> CurrentPerfCounter.QuadPart += ClockDelta;
>
> - /* This must be true unless HalpPerfCounter has changed sign,
> - which takes approximately 245,118 years */
> - ASSERT(CurrentPerfCounter.QuadPart >= HalpLastPerfCounter.QuadPart);
> + /* Check if the value is smaller then before, this means, we somehow
> + missed an interrupt. This is a sign that the timer interrupt
> + is very inaccurate. Probably a virtual machine. */
> + if (CurrentPerfCounter.QuadPart < HalpLastPerfCounter.QuadPart)
> + {
> + /* We missed an interrupt. Assume we will receive it later */
> + CurrentPerfCounter.QuadPart += HalpCurrentRollOver;
> + }
>
> /* Update the last counter value */
> HalpLastPerfCounter = CurrentPerfCounter;
>
> + /* Restore previous irql */
> + if (OldIrql < DISPATCH_LEVEL) KfLowerIrql(OldIrql);
> +
> /* Return the result */
> return CurrentPerfCounter;
> }
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.reactos.org/pipermail/ros-dev/attachments/20110830/5fffce0a/attachment.htm>
More information about the Ros-dev
mailing list