PerformanceCounterFrequency fix.

Rein Klazes wijn at wanadoo.nl
Tue Jan 25 11:44:04 CST 2005


On Mon, 24 Jan 2005 15:08:56 +0100, you wrote:

> > How bad is it to use the gettimeofday() method?
> 
> In my opinion, the RTDSC method should be suppressed from the code and we
> should always use the 'gettimeofday' method (despite the penalty hit of a
> syscall).

I was more concerned about the accuracy of gettimeofday (not
incrementing in usec's). So I did a small test and I find it behaves
very nicely.

That was the only reason I could see to justify the rdtsc method, so
here it goes. As the cpuHz variable is not used anymore, we might as
well move it to ntdll.

Changelog:
	dlls/kernel	: cpu.c
	dlls/ntdll	: nt.c
	include		: winternl.h

	Get rid of the rdtsc cpu instruction method for calculation of
	the performance counter. Put the calculation (based on 
	gettimeofday) in NtQueryPerformanceCounter() and use that
	in the kernel functions.

Rein. 
-------------- next part --------------
--- wine/dlls/kernel/cpu.c	2005-01-20 13:58:25.000000000 +0100
+++ mywine/dlls/kernel/cpu.c	2005-01-25 11:43:43.000000000 +0100
@@ -181,22 +181,8 @@ static void create_registry_keys( const 
  */
 BOOL WINAPI QueryPerformanceCounter(PLARGE_INTEGER counter)
 {
-    LARGE_INTEGER time;
-
-#if defined(__i386__) && defined(__GNUC__)
-    if (IsProcessorFeaturePresent( PF_RDTSC_INSTRUCTION_AVAILABLE )) {
-	/* i586 optimized version */
-	__asm__ __volatile__ ( "rdtsc"
-			       : "=a" (counter->u.LowPart), "=d" (counter->u.HighPart) );
-        /* see below */
-	counter->QuadPart = counter->QuadPart / ( cpuHz / 1193182 ) ;
-	return TRUE;
-    }
-#endif
-
-    /* fall back to generic routine (ie, for i386, i486) */
-    NtQuerySystemTime( &time );
-    counter->QuadPart = time.QuadPart;
+    LARGE_INTEGER frequency;
+    NtQueryPerformanceCounter( counter, &frequency);
     return TRUE;
 }
 
@@ -218,19 +204,8 @@ BOOL WINAPI QueryPerformanceCounter(PLAR
  */
 BOOL WINAPI QueryPerformanceFrequency(PLARGE_INTEGER frequency)
 {
-#if defined(__i386__) && defined(__GNUC__)
-    if (IsProcessorFeaturePresent( PF_RDTSC_INSTRUCTION_AVAILABLE )) {
-        /* On a standard PC, Windows returns the clock frequency for the
-         * 8253 Programmable Interrupt Timer, which has been 1193182 Hz
-         * since the first IBM PC (cpuHz/4). There are applications that
-         * crash when the returned frequency is much higher or lower, so
-         * do not try to be smart */
-        frequency->QuadPart = 1193182;
-        return TRUE;
-    }
-#endif
-    frequency->u.LowPart  = 10000000;
-    frequency->u.HighPart = 0;
+    LARGE_INTEGER counter;
+    NtQueryPerformanceCounter( &counter, frequency);
     return TRUE;
 }
 
--- wine/dlls/ntdll/nt.c	2004-11-04 10:17:35.000000000 +0100
+++ mywine/dlls/ntdll/nt.c	2005-01-25 12:47:04.000000000 +0100
@@ -467,14 +467,19 @@ NTSTATUS WINAPI NtSetIntervalProfile(DWO
 
 /******************************************************************************
  *  NtQueryPerformanceCounter	[NTDLL.@]
+ *
+ *  Note: Windows uses a timer clocked at a multiple of 1193182 Hz.
+ *  
  */
 NTSTATUS WINAPI NtQueryPerformanceCounter(
-	IN PLARGE_INTEGER Counter,
-	IN PLARGE_INTEGER Frequency)
+	OUT PLARGE_INTEGER Counter,
+	OUT PLARGE_INTEGER Frequency)
 {
-	FIXME("(%p, 0%p) stub\n",
-	Counter, Frequency);
-	return 0;
+    LARGE_INTEGER time;
+    NtQuerySystemTime( &time );
+    Counter->QuadPart = time.QuadPart;
+    Frequency->QuadPart = 10000000;
+    return 0;
 }
 
 /******************************************************************************
--- wine/include/winternl.h	2005-01-21 15:00:35.000000000 +0100
+++ mywine/include/winternl.h	2005-01-25 12:40:54.000000000 +0100
@@ -1411,6 +1411,7 @@ NTSTATUS  WINAPI NtQueryInstallUILanguag
 NTSTATUS  WINAPI NtQueryKey(HKEY,KEY_INFORMATION_CLASS,void *,DWORD,DWORD *);
 NTSTATUS  WINAPI NtQueryMultipleValueKey(HKEY,PVALENTW,ULONG,PVOID,ULONG,PULONG);
 NTSTATUS  WINAPI NtQueryObject(HANDLE, OBJECT_INFORMATION_CLASS, PVOID, ULONG, PULONG);
+NTSTATUS  WINAPI NtQueryPerformanceCounter( PLARGE_INTEGER, PLARGE_INTEGER);
 NTSTATUS  WINAPI NtQuerySecurityObject(HANDLE,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR,ULONG,PULONG);
 NTSTATUS  WINAPI NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS,PVOID,ULONG,PULONG);
 NTSTATUS  WINAPI NtQuerySystemTime(PLARGE_INTEGER);


More information about the wine-devel mailing list