[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 (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION =
*)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_0056_01CBFEA7.C9F1ED60
Content-Type: text/plain;
	name="The -Final-Code.txt"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="The -Final-Code.txt"

    case SystemProcessorPerformanceInformation:
        {
                  SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *sppib;  /* =
base     */
                  SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *sppic;  /* =
current  */
            CONST SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *sppil;  /* =
limit    */
            ULONG count;
            ULONG clk_tick;                 /* clock ticks per second    =
       */
            ULONG num_cpus;                 /* number of CPUs the system =
has    */
            ULONG 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 );

#ifdef __APPLE__
            {
                      processor_cpu_load_info_data_t *pinfo;
                const processor_cpu_load_info_data_t *pwork;
                mach_msg_type_number_t info_count;

                if( !host_processor_info( mach_host_self(),
                                          PROCESSOR_CPU_LOAD_INFO,
                                          &got_cpus,
                                          (processor_info_array_t =
*)&pinfo,
                                          &info_count ) )
                {
                    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) );
                }
            }
#else
            {
                ULONG 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 )
                {
                    /* 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->Reserved1[0].QuadPart =3D (ULONGLONG)wait =
* 10000000 / clk_tick;
                        sppic->Reserved1[1].QuadPart =3D (ULONGLONG)hirq =
* 10000000 / clk_tick;
                    }
                    fclose(cpu_file);
                }
            }
#endif
            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++)
                {
                    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->Reserved1[0].QuadPart =3D done *   5;      /* =
 0.5% DPC    */
                    sppic->Reserved1[1].QuadPart =3D done *   2;      /* =
 0.2% Int    */
                }
            }

            len =3D got_cpus * sizeof(*sppib);
        }
        break;

------=_NextPart_000_0056_01CBFEA7.C9F1ED60--




More information about the wine-patches mailing list