From 97acc35c7ca288646bcc725cb03401025f9598f5 Mon Sep 17 00:00:00 2001 From: Aleksandar Andrejevic Date: Mon, 28 Oct 2013 02:25:54 +0000 Subject: [PATCH] [NTVDM] Improve performance by computing the resolution required by the PIT, and then using the standard tick count instead of performance counters when that resolution is low. svn path=/branches/ntvdm/; revision=60783 --- subsystems/ntvdm/ntvdm.c | 32 +++++++++++++++++++++++++------- subsystems/ntvdm/timer.c | 19 +++++++++++++++++++ subsystems/ntvdm/timer.h | 1 + 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/subsystems/ntvdm/ntvdm.c b/subsystems/ntvdm/ntvdm.c index 60d78986e84..b919c814695 100644 --- a/subsystems/ntvdm/ntvdm.c +++ b/subsystems/ntvdm/ntvdm.c @@ -151,19 +151,37 @@ INT wmain(INT argc, WCHAR *argv[]) /* Main loop */ while (VdmRunning) { + /* Get the resolution of the system timer */ + DWORD TimerResolution = PitGetResolution(); + /* Get the current number of ticks */ CurrentTickCount = GetTickCount(); - /* Get the current performance counter value */ - QueryPerformanceCounter(&Counter); + if (TimerResolution > 1000) + { + /* Get the current performance counter value */ + QueryPerformanceCounter(&Counter); - /* Get the number of PIT ticks that have passed */ - TimerTicks = ((Counter.QuadPart - LastTimerTick.QuadPart) - * PIT_BASE_FREQUENCY) / Frequency.QuadPart; + /* Get the number of PIT ticks that have passed */ + TimerTicks = ((Counter.QuadPart - LastTimerTick.QuadPart) + * PIT_BASE_FREQUENCY) / Frequency.QuadPart; + } + else + { + /* Use the standard tick count */ + Counter.QuadPart = CurrentTickCount; + + /* Get the number of PIT ticks that have passed */ + TimerTicks = ((Counter.QuadPart - LastTimerTick.QuadPart) + * PIT_BASE_FREQUENCY) / 1000; + } /* Update the PIT */ - for (i = 0; i < TimerTicks; i++) PitDecrementCount(); - LastTimerTick = Counter; + if (TimerTicks > 0) + { + for (i = 0; i < TimerTicks; i++) PitDecrementCount(); + LastTimerTick = Counter; + } /* Check for vertical retrace */ if ((CurrentTickCount - LastVerticalRefresh) >= 16) diff --git a/subsystems/ntvdm/timer.c b/subsystems/ntvdm/timer.c index bdb45c4438e..239a5abc29e 100644 --- a/subsystems/ntvdm/timer.c +++ b/subsystems/ntvdm/timer.c @@ -233,4 +233,23 @@ VOID PitDecrementCount() } } +DWORD PitGetResolution(VOID) +{ + INT i; + DWORD MinReloadValue = 65536; + + for (i = 0; i < PIT_CHANNELS; i++) + { + DWORD ReloadValue = PitChannels[i].ReloadValue; + + /* 0 means 65536 */ + if (ReloadValue == 0) ReloadValue = 65536; + + if (ReloadValue < MinReloadValue) MinReloadValue = ReloadValue; + } + + /* Return the frequency resolution */ + return PIT_BASE_FREQUENCY / MinReloadValue; +} + /* EOF */ diff --git a/subsystems/ntvdm/timer.h b/subsystems/ntvdm/timer.h index 8331d7f0346..01ec154e87b 100644 --- a/subsystems/ntvdm/timer.h +++ b/subsystems/ntvdm/timer.h @@ -49,6 +49,7 @@ VOID PitWriteCommand(BYTE Value); BYTE PitReadData(BYTE Channel); VOID PitWriteData(BYTE Channel, BYTE Value); VOID PitDecrementCount(); +DWORD PitGetResolution(VOID); #endif // _TIMER_H_