Better NtQueryPerformanceCounter

Rein Klazes wijn at wanadoo.nl
Tue Feb 22 13:07:59 CST 2005


Hi,

Following the bug reports on wine-dev.

Changelog:
	dlls/ntdll	: nt.c
	dlls/kernel	: cpu.c
	NtQueryPerformanceCounter should return a frequency of 1193182
	Hz and counts like in Windows. Some applications depend on that.
	Simplify QueryPerformanceCounter a bit.

Rein.
-------------- next part --------------
--- wine/dlls/ntdll/nt.c	2005-02-22 10:16:50.000000000 +0100
+++ mywine/dlls/ntdll/nt.c	2005-02-22 19:34:25.000000000 +0100
@@ -37,6 +37,9 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
 
+/* FIXME: fixed at 2005/2/22 */
+static LONGLONG boottime = (LONGLONG)1275356510 * 100000000;
+
 /* Structures used by NtConnectPort */
 
 typedef struct LpcSectionInfo
@@ -512,8 +515,10 @@ NTSTATUS WINAPI NtSetIntervalProfile(DWO
 /******************************************************************************
  *  NtQueryPerformanceCounter	[NTDLL.@]
  *
- *  Note: Windows uses a timer clocked at a multiple of 1193182 Hz.
- *  
+ *  Note: Windows uses a timer clocked at a multiple of 1193182 Hz. There is a
+ *  good number of applications that crash when the returned frequency is either
+ *  lower or higher then what Windows gives. Also too high counter values are
+ *  reported to give problems.
  */
 NTSTATUS WINAPI NtQueryPerformanceCounter(
 	OUT PLARGE_INTEGER Counter,
@@ -523,9 +528,14 @@ NTSTATUS WINAPI NtQueryPerformanceCounte
 
     if (!Counter) return STATUS_ACCESS_VIOLATION;
     NtQuerySystemTime( &time );
-    Counter->QuadPart = time.QuadPart;
+    time.QuadPart -= boottime;
+    /* convert a counter that increments at a rate of 1 MHz
+     * to one of 1193182 Hz, with some care for arithmetic
+     * overflow ( will not overflow until 3396 or so ) and
+     * good accuracy ( 21/176 = 0.119318182) */
+    Counter->QuadPart = (time.QuadPart * 21) / 176;
     if (Frequency)
-        Frequency->QuadPart = 10000000;
+        Frequency->QuadPart = 1193182;
     return 0;
 }
 
@@ -625,7 +635,7 @@ NTSTATUS WINAPI NtQuerySystemInformation
             SYSTEM_TIMEOFDAY_INFORMATION* sti = (SYSTEM_TIMEOFDAY_INFORMATION*)SystemInformation;
             if (Length >= sizeof(*sti))
             {
-                sti->liKeBootTime.QuadPart = 0; /* FIXME */
+                sti->liKeBootTime.QuadPart = boottime;
                 sti->liKeSystemTime.QuadPart = 0; /* FIXME */
                 sti->liExpTimeZoneBias.QuadPart  = 0; /* FIXME */
                 sti->uCurrentTimeZoneId = 0; /* FIXME */
--- wine/dlls/kernel/cpu.c	2005-01-28 17:09:39.000000000 +0100
+++ mywine/dlls/kernel/cpu.c	2005-02-22 19:41:26.000000000 +0100
@@ -192,8 +192,7 @@ static void create_registry_keys( const 
  */
 BOOL WINAPI QueryPerformanceCounter(PLARGE_INTEGER counter)
 {
-    LARGE_INTEGER frequency;
-    NtQueryPerformanceCounter( counter, &frequency );
+    NtQueryPerformanceCounter( counter, NULL );
     return TRUE;
 }
 


More information about the wine-patches mailing list