[NTVDM]
authorAleksandar Andrejevic <aandrejevic@reactos.org>
Mon, 28 Oct 2013 02:25:54 +0000 (02:25 +0000)
committerAleksandar Andrejevic <aandrejevic@reactos.org>
Mon, 28 Oct 2013 02:25:54 +0000 (02:25 +0000)
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
subsystems/ntvdm/timer.c
subsystems/ntvdm/timer.h

index 60d7898..b919c81 100644 (file)
@@ -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)
index bdb45c4..239a5ab 100644 (file)
@@ -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 */
index 8331d7f..01ec154 100644 (file)
@@ -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_