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, <[email protected]> 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; > } > > >
_______________________________________________ Ros-dev mailing list [email protected] http://www.reactos.org/mailman/listinfo/ros-dev
