[PATCH] Fix SystemProcessorPerformanceInformation to include =

Ray Hinchliffe ray at rh-software.com
Mon Apr 18 05:43:37 CDT 2011


DPC and Interrupt times

---
 dlls/ntdll/nt.c    |  187 =
++++++++++++++++++++++++++++-----------------------
 include/winternl.h |    5 +-
 2 files changed, 106 insertions(+), 86 deletions(-)
 mode change 100644 =3D> 100755 dlls/ntdll/nt.c
 mode change 100644 =3D> 100755 include/winternl.h

diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
old mode 100644
new mode 100755
index ef5f703..012c41b
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -1546,107 +1546,126 @@ NTSTATUS WINAPI NtQuerySystemInformation(
         break;
     case SystemProcessorPerformanceInformation:
         {
-            SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *sppi =3D NULL;
-            unsigned int cpus =3D 0;
-            int out_cpus =3D Length / =
sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION);
+                  SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *sppib;  /* =
base    */
+                  SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *sppic;  /* =
current */
+            const SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *sppil;  /* =
limit   */
+            unsigned long count;
+            unsigned long clk_tick;         /* clock ticks per second   =
        */
+            unsigned long num_cpus;         /* number of CPUs the =
system has    */
+            unsigned long got_cpus;         /* number of CPUs we got =
times for  */
+
+            num_cpus =3D NtCurrentTeb()->Peb->NumberOfProcessors;
+
+            if( Length < ( num_cpus * sizeof( *sppib ) ) )
+            {
+                ret =3D STATUS_INFO_LENGTH_MISMATCH;
+                len =3D 0;
+                break;
+            }
+
+            if( !( sppib =3D (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION =
*)SystemInformation ) )
+            {
+                ret =3D STATUS_ACCESS_VIOLATION;
+                len =3D 0;
+                break;
+            }
+
+            clk_tick =3D sysconf( _SC_CLK_TCK );
+            memset( sppib, got_cpus =3D 0, Length );
=20
-            if (out_cpus =3D=3D 0)
-            {
-                len =3D 0;
-                ret =3D STATUS_INFO_LENGTH_MISMATCH;
-                break;
-            }
-            else
 #ifdef __APPLE__
             {
-                processor_cpu_load_info_data_t *pinfo;
+                      processor_cpu_load_info_data_t *pinfo;
+                const processor_cpu_load_info_data_t *pwork;
                 mach_msg_type_number_t info_count;
=20
-                if (host_processor_info (mach_host_self (),
-                                         PROCESSOR_CPU_LOAD_INFO,
-                                         &cpus,
-                                         =
(processor_info_array_t*)&pinfo,
-                                         &info_count) =3D=3D 0)
+                if( !host_processor_info( mach_host_self (),
+                                          PROCESSOR_CPU_LOAD_INFO,
+                                          &got_cpus,
+                                          (processor_info_array_t =
*)&pinfo,
+                                          &info_count ) )
                 {
-                    int i;
-                    cpus =3D min(cpus,out_cpus);
-                    len =3D =
sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * cpus;
-                    sppi =3D RtlAllocateHeap(GetProcessHeap(), 0,len);
-                    for (i =3D 0; i < cpus; i++)
-                    {
-                        sppi[i].IdleTime.QuadPart =3D =
pinfo[i].cpu_ticks[CPU_STATE_IDLE];
-                        sppi[i].KernelTime.QuadPart =3D =
pinfo[i].cpu_ticks[CPU_STATE_SYSTEM];
-                        sppi[i].UserTime.QuadPart =3D =
pinfo[i].cpu_ticks[CPU_STATE_USER];
+                    for( sppil =3D ( sppic =3D sppib ) + ( got_cpus =3D =
min( num_cpus, got_cpus ) ), pwork =3D pinfo; sppic < sppil; sppic++, =
pwork++ )
+                    {
+                        sppic->IdleTime.QuadPart   =3D   =
pwork->cpu_ticks[ CPU_STATE_IDLE   ]   * 10000000 / clk_tick;
+                        sppic->UserTime.QuadPart   =3D ( =
pwork->cpu_ticks[ CPU_STATE_USER   ] +
+                                                       =
pwork->cpu_ticks[ CPU_STATE_NICE   ] ) * 10000000 / clk_tick;
+                        sppic->KernelTime.QuadPart =3D   =
pwork->cpu_ticks[ CPU_STATE_SYSTEM ]   * 10000000 / clk_tick + =
sppic->IdleTime.QuadPart;
                     }
-                    vm_deallocate (mach_task_self (), (vm_address_t) =
pinfo, info_count * sizeof(natural_t));
+                    vm_deallocate( mach_task_self(), =
(vm_address_t)pinfo, info_count * sizeof( natural_t ) );
                 }
             }
 #else
             {
-                FILE *cpuinfo =3D fopen("/proc/stat", "r");
-                if (cpuinfo)
+                unsigned long user, nice, syst, idle, wait, hirq, sirq, =
steal, guest;
+                FILE         *cpu_file;
+                char          name[  32 ];
+                char          line[ 255 ];
+
+                cpu_file =3D fopen( "/proc/stat", "r" );
+
+                if( cpu_file )
                 {
-                    unsigned long clk_tck =3D sysconf(_SC_CLK_TCK);
-                    unsigned long usr,nice,sys,idle,remainder[8];
-                    int i, count;
-                    char name[32];
-                    char line[255];
-
-                    /* first line is combined usage */
-                    while (fgets(line,255,cpuinfo))
-                    {
-                        count =3D sscanf(line, "%s %lu %lu %lu %lu %lu =
%lu %lu %lu %lu %lu %lu %lu",
-                                       name, &usr, &nice, &sys, &idle,
-                                       &remainder[0], &remainder[1], =
&remainder[2], &remainder[3],
-                                       &remainder[4], &remainder[5], =
&remainder[6], &remainder[7]);
-
-                        if (count < 5 || strncmp( name, "cpu", 3 )) =
break;
-                        for (i =3D 0; i + 5 < count; ++i) sys +=3D =
remainder[i];
-                        sys +=3D idle;
-                        usr +=3D nice;
-                        cpus =3D atoi( name + 3 ) + 1;
-                        if (cpus > out_cpus) break;
-                        len =3D =
sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * cpus;
-                        if (sppi)
-                            sppi =3D RtlReAllocateHeap( =
GetProcessHeap(), HEAP_ZERO_MEMORY, sppi, len );
-                        else
-                            sppi =3D RtlAllocateHeap( GetProcessHeap(), =
HEAP_ZERO_MEMORY, len );
-
-                        sppi[cpus-1].IdleTime.QuadPart   =3D =
(ULONGLONG)idle * 10000000 / clk_tck;
-                        sppi[cpus-1].KernelTime.QuadPart =3D =
(ULONGLONG)sys * 10000000 / clk_tck;
-                        sppi[cpus-1].UserTime.QuadPart   =3D =
(ULONGLONG)usr * 10000000 / clk_tck;
+                    /* first line is combined usage, set for CPU-0 then =
replaced */
+
+                    for( ; fgets( line, sizeof( line ), cpu_file ); =
got_cpus++ )
+                    {
+                        wait =3D hirq =3D sirq =3D steal =3D guest =3D =
0;
+
+                        count =3D sscanf( line, "%s %lu %lu %lu %lu %lu =
%lu %lu %lu %lu",
+                                        name, &user, &nice, &syst, =
&idle, &wait, &hirq, &sirq, &steal, &guest );
+
+                        if( ( count < 5                 ) ||
+                            ( strncmp( name, "cpu", 3 ) ) )
+                            break;
+
+                        got_cpus =3D atol( name + 3 );
+
+                        if( got_cpus >=3D num_cpus )
+                        {
+                            FIXME("/proc/stat %s is outside the range 0 =
to %lu\n", name, num_cpus );
+                            got_cpus =3D num_cpus;
+                            break;
+                        }
+
+                        hirq +=3D sirq;
+                        wait +=3D steal + guest;
+                        syst +=3D wait  + hirq + idle;
+                        user +=3D nice;
+                        sppic =3D sppib + got_cpus;
+
+                        sppic->UserTime.QuadPart   =3D (ULONGLONG)user =
* 10000000 / clk_tick;
+                        sppic->IdleTime.QuadPart   =3D (ULONGLONG)idle =
* 10000000 / clk_tick;
+                        sppic->KernelTime.QuadPart =3D (ULONGLONG)syst =
* 10000000 / clk_tick;
+                        sppic->DpcTime.QuadPart    =3D (ULONGLONG)wait =
* 10000000 / clk_tick;
+                        sppic->IntTime.QuadPart    =3D (ULONGLONG)hirq =
* 10000000 / clk_tick;
                     }
-                    fclose(cpuinfo);
+                    fclose( cpu_file );
                 }
             }
 #endif
-
-            if (cpus =3D=3D 0)
-            {
-                static int i =3D 1;
-                int n;
-                cpus =3D min(NtCurrentTeb()->Peb->NumberOfProcessors, =
out_cpus);
-                len =3D =
sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * cpus;
-                sppi =3D RtlAllocateHeap(GetProcessHeap(), 0, len);
-                FIXME("stub info_class =
SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION\n");
-                /* many programs expect these values to change so fake =
change */
-                for (n =3D 0; n < cpus; n++)
+            if( !got_cpus )
+            {
+                static ULONGLONG done =3D 0;
+
+                if( !done )
+                  FIXME("stub info_class =
SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION\n");
+
+                /* many programs expect these values to change so set =
60.0% idle, 30% user and 10% kernel */
+
+                done +=3D 10000;
+
+                for( sppil =3D ( sppic =3D sppib ) + ( got_cpus =3D =
num_cpus ); sppic < sppil; sppic++ )
                 {
-                    sppi[n].KernelTime.QuadPart =3D 1 * i;
-                    sppi[n].UserTime.QuadPart   =3D 2 * i;
-                    sppi[n].IdleTime.QuadPart   =3D 3 * i;
-                }
-                i++;
-            }
-
-            if (Length >=3D len)
-            {
-                if (!SystemInformation) ret =3D =
STATUS_ACCESS_VIOLATION;
-                else memcpy( SystemInformation, sppi, len);
-            }
-            else ret =3D STATUS_INFO_LENGTH_MISMATCH;
-
-            RtlFreeHeap(GetProcessHeap(),0,sppi);
+                    sppic->IdleTime.QuadPart   =3D done * 600;     /* =
60.0% idle   */
+                    sppic->UserTime.QuadPart   =3D done * 300;     /* =
30.0% user   */
+                    sppic->KernelTime.QuadPart =3D done * 700;     /* =
10.0% kernel */
+                    sppic->DpcTime.QuadPart    =3D done *   5;     /*  =
0.5% DPC    */
+                    sppic->IntTime.QuadPart    =3D done *   2;     /*  =
0.2% Int    */
+                }
+            }
+
+            len =3D got_cpus * sizeof( *sppib );
         }
         break;
     case SystemModuleInformation:
diff --git a/include/winternl.h b/include/winternl.h
old mode 100644
new mode 100755
index a1c9f0c..0899b20
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -1241,8 +1241,9 @@ typedef struct =
_SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION {
     LARGE_INTEGER IdleTime;
     LARGE_INTEGER KernelTime;
     LARGE_INTEGER UserTime;
-    LARGE_INTEGER Reserved1[2];
-    ULONG Reserved2;
+    LARGE_INTEGER DpcTime;
+    LARGE_INTEGER IntTime;
+    ULONG IntCount;
 } SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION, =
*PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION;
=20
 /* System Information Class 0x0b */
--=20
1.7.0.4


------=_NextPart_000_0013_01CBFDC0.1599A4D0
Content-Type: text/plain;
	name="test-one.txt"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="test-one.txt"

SIV32X - System Information Viewer V4.20 Beta-01 RUW::root  Built Apr 17 =
2011 at 15:49:28  [1252]  Command [Z:\home\ray\siv\siv32x.exe =
-save=3D[wine-perf]=3Dtest-one.txt] [[wine-perf]] =
[Z:\home\ray\siv\test-one.txt]


[wine-perf]  [wine]


Initial  CPU-0   Idle       5870.5100000  User        409.2400000  Krnl  =
     6063.3800000  DPC         52.1200000  Int          1.8600000  Int 0
         CPU-1   Idle       5809.3300000  User        462.9100000  Krnl  =
     6027.4700000  DPC         72.4300000  Int          0.8000000  Int 0
  1 Sec  CPU-0   Idle          0.8400000  User          0.0000000  Krnl  =
        0.8400000  DPC          0.0000000  Int          0.0000000  Int 0
         CPU-1   Idle          1.0000000  User          0.0000000  Krnl  =
        1.0100000  DPC          0.0000000  Int          0.0000000  Int 0
  2 Sec  CPU-0   Idle          1.8300000  User          0.0000000  Krnl  =
        1.8400000  DPC          0.0000000  Int          0.0000000  Int 0
         CPU-1   Idle          2.0000000  User          0.0000000  Krnl  =
        2.0100000  DPC          0.0000000  Int          0.0000000  Int 0
  3 Sec  CPU-0   Idle          2.9000000  User          0.0000000  Krnl  =
        2.9100000  DPC          0.0000000  Int          0.0000000  Int 0
         CPU-1   Idle          3.0100000  User          0.0000000  Krnl  =
        3.0200000  DPC          0.0000000  Int          0.0000000  Int 0
  4 Sec  CPU-0   Idle          3.8300000  User          0.0000000  Krnl  =
        3.8400000  DPC          0.0000000  Int          0.0000000  Int 0
         CPU-1   Idle          4.0100000  User          0.0000000  Krnl  =
        4.0200000  DPC          0.0000000  Int          0.0000000  Int 0


[=3D=3D=3D=3D=3D=3D=3D=3D]  [ Elapsed Time for Computer Information  =
0:05  Used 2.85KB of 8.00MB  "[wine-perf]" ]

------=_NextPart_000_0013_01CBFDC0.1599A4D0
Content-Type: text/plain;
	name="test-two.txt"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="test-two.txt"

SIV32X - System Information Viewer V4.20 Beta-01 RUW::root  Built Apr 17 =
2011 at 15:49:28  [1252]  Command [Z:\home\ray\siv\siv32x.exe =
-save=3D[wine-perf]=3Dtest-two.txt] [[wine-perf]] =
[Z:\home\ray\siv\test-two.txt]


[wine-perf]  [wine]


Initial  CPU-0   Idle          1.2000000  User          0.6000000  Krnl  =
        1.4000000  DPC          0.0100000  Int          0.0040000  Int 0
         CPU-1   Idle          1.2000000  User          0.6000000  Krnl  =
        1.4000000  DPC          0.0100000  Int          0.0040000  Int 0
  1 Sec  CPU-0   Idle          0.6000000  User          0.3000000  Krnl  =
        0.7000000  DPC          0.0050000  Int          0.0020000  Int 0
         CPU-1   Idle          0.6000000  User          0.3000000  Krnl  =
        0.7000000  DPC          0.0050000  Int          0.0020000  Int 0
  2 Sec  CPU-0   Idle          1.2000000  User          0.6000000  Krnl  =
        1.4000000  DPC          0.0100000  Int          0.0040000  Int 0
         CPU-1   Idle          1.2000000  User          0.6000000  Krnl  =
        1.4000000  DPC          0.0100000  Int          0.0040000  Int 0
  3 Sec  CPU-0   Idle          1.8000000  User          0.9000000  Krnl  =
        2.1000000  DPC          0.0150000  Int          0.0060000  Int 0
         CPU-1   Idle          1.8000000  User          0.9000000  Krnl  =
        2.1000000  DPC          0.0150000  Int          0.0060000  Int 0
  4 Sec  CPU-0   Idle          2.4000000  User          1.2000000  Krnl  =
        2.8000000  DPC          0.0200000  Int          0.0080000  Int 0
         CPU-1   Idle          2.4000000  User          1.2000000  Krnl  =
        2.8000000  DPC          0.0200000  Int          0.0080000  Int 0


[=3D=3D=3D=3D=3D=3D=3D=3D]  [ Elapsed Time for Computer Information  =
0:05  Used 2.85KB of 8.00MB  "[wine-perf]" ]

------=_NextPart_000_0013_01CBFDC0.1599A4D0--




More information about the wine-patches mailing list