[PATCH] Tidy CPU time reporting, add DPC and interrupt=0A=

Ray Hinchliffe ray at pobox.co.uk
Tue Apr 19 15:20:46 CDT 2011


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

------=_NextPart_000_0001_01CBFF28.E00FD5E0--




More information about the wine-patches mailing list