[ros-diffs] [fireball] 37934: - Implement KeQueryRuntimeProcess for querying total user/kernel times of a process. - Use it for obtaining idle process times, and per-process information in QuerySystemInformation routines. - Fix incorrect multiplier being applied to user/kernel times (should be KeMaximumIncrement instead of 100000). - Slightly rework SystemProcessorPerformanceInformation to provide valid data. - This fixed a bug existing since revision 24148, 2 years ago. See issue #2329 for more details.

fireball at svn.reactos.org fireball at svn.reactos.org
Mon Dec 8 13:57:53 CET 2008


Author: fireball
Date: Mon Dec  8 06:57:53 2008
New Revision: 37934

URL: http://svn.reactos.org/svn/reactos?rev=37934&view=rev
Log:
- Implement KeQueryRuntimeProcess for querying total user/kernel times of a process.
- Use it for obtaining idle process times, and per-process information in QuerySystemInformation routines.
- Fix incorrect multiplier being applied to user/kernel times (should be KeMaximumIncrement instead of 100000).
- Slightly rework SystemProcessorPerformanceInformation to provide valid data.
- This fixed a bug existing since revision 24148, 2 years ago.
See issue #2329 for more details.

Modified:
    trunk/reactos/ntoskrnl/ex/sysinfo.c
    trunk/reactos/ntoskrnl/include/internal/ke.h
    trunk/reactos/ntoskrnl/ke/procobj.c

Modified: trunk/reactos/ntoskrnl/ex/sysinfo.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ex/sysinfo.c?rev=37934&r1=37933&r2=37934&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ex/sysinfo.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ex/sysinfo.c [iso-8859-1] Mon Dec  8 06:57:53 2008
@@ -538,6 +538,7 @@
 /* Class 2 - Performance Information */
 QSI_DEF(SystemPerformanceInformation)
 {
+	ULONG IdleUser, IdleKernel;
 	PSYSTEM_PERFORMANCE_INFORMATION Spi
 		= (PSYSTEM_PERFORMANCE_INFORMATION) Buffer;
 
@@ -554,8 +555,8 @@
 
 	TheIdleProcess = PsIdleProcess;
 
-	Spi->IdleProcessTime.QuadPart = TheIdleProcess->Pcb.KernelTime * 100000LL;
-
+	IdleKernel = KeQueryRuntimeProcess(&TheIdleProcess->Pcb, &IdleUser);
+	Spi->IdleProcessTime.QuadPart = UInt32x32To64(IdleKernel, KeMaximumIncrement);
 	Spi->IoReadTransferCount = IoReadTransferCount;
 	Spi->IoWriteTransferCount = IoWriteTransferCount;
 	Spi->IoOtherTransferCount = IoOtherTransferCount;
@@ -699,7 +700,8 @@
 {
 	ULONG ovlSize = 0, nThreads;
 	PEPROCESS pr = NULL, syspr;
-	unsigned char *pCur;
+	PUCHAR pCur;
+	ULONG TotalUser, TotalKernel;
 	NTSTATUS Status = STATUS_SUCCESS;
 
 	_SEH2_TRY
@@ -757,8 +759,6 @@
 			SpiCur->NextEntryOffset = curSize+inLen; // relative offset to the beginnnig of the next structure
 			SpiCur->NumberOfThreads = nThreads;
 			SpiCur->CreateTime = pr->CreateTime;
-			SpiCur->UserTime.QuadPart = pr->Pcb.UserTime * 100000LL;
-			SpiCur->KernelTime.QuadPart = pr->Pcb.KernelTime * 100000LL;
 			SpiCur->ImageName.Length = strlen(pr->ImageFileName) * sizeof(WCHAR);
 			SpiCur->ImageName.MaximumLength = (USHORT)inLen;
 			SpiCur->ImageName.Buffer = (void*)(pCur+curSize);
@@ -798,8 +798,8 @@
 				current = CONTAINING_RECORD(current_entry, ETHREAD,
 				                            ThreadListEntry);
 
-				ThreadInfo->KernelTime.QuadPart = current->Tcb.KernelTime * 100000LL;
-				ThreadInfo->UserTime.QuadPart = current->Tcb.UserTime * 100000LL;
+				ThreadInfo->KernelTime.QuadPart = UInt32x32To64(current->Tcb.KernelTime, KeMaximumIncrement);
+				ThreadInfo->UserTime.QuadPart = UInt32x32To64(current->Tcb.UserTime, KeMaximumIncrement);
 				ThreadInfo->CreateTime.QuadPart = current->CreateTime.QuadPart;
 				ThreadInfo->WaitTime = current->Tcb.WaitTime;
 				ThreadInfo->StartAddress = (PVOID) current->StartAddress;
@@ -809,9 +809,15 @@
 				ThreadInfo->ContextSwitches = current->Tcb.ContextSwitches;
 				ThreadInfo->ThreadState = current->Tcb.State;
 				ThreadInfo->WaitReason = current->Tcb.WaitReason;
+
 				ThreadInfo++;
 				current_entry = current_entry->Flink;
 			}
+
+			/* Query total user/kernel times of a process */
+			TotalKernel = KeQueryRuntimeProcess(&pr->Pcb, &TotalUser);
+			SpiCur->UserTime.QuadPart = UInt32x32To64(TotalUser, KeMaximumIncrement);
+			SpiCur->KernelTime.QuadPart = UInt32x32To64(TotalKernel, KeMaximumIncrement);
 
 			/* Handle idle process entry */
 			if (pr == PsIdleProcess) pr = NULL;
@@ -882,37 +888,39 @@
 /* Class 8 - Processor Performance Information */
 QSI_DEF(SystemProcessorPerformanceInformation)
 {
-	PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION Spi
-		= (PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) Buffer;
-
-        LONG i;
-	LARGE_INTEGER CurrentTime;
-	PKPRCB Prcb;
-
-	*ReqSize = KeNumberProcessors * sizeof (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION);
-	/*
-	 * Check user buffer's size
-	 */
-	if (Size < KeNumberProcessors * sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION))
-	{
-		return (STATUS_INFO_LENGTH_MISMATCH);
-	}
-
-	CurrentTime.QuadPart = KeQueryInterruptTime();
-	Prcb = KeGetPcr()->Prcb;
-	for (i = 0; i < KeNumberProcessors; i++)
-	{
-	   Spi->IdleTime.QuadPart = (Prcb->IdleThread->KernelTime + Prcb->IdleThread->UserTime) * 100000LL;
-           Spi->KernelTime.QuadPart =  Prcb->KernelTime * 100000LL;
-           Spi->UserTime.QuadPart = Prcb->UserTime * 100000LL;
-           Spi->DpcTime.QuadPart = Prcb->DpcTime * 100000LL;
-           Spi->InterruptTime.QuadPart = Prcb->InterruptTime * 100000LL;
-           Spi->InterruptCount = Prcb->InterruptCount;
-	   Spi++;
-	   Prcb = (PKPRCB)((ULONG_PTR)Prcb + PAGE_SIZE);
-	}
-
-	return (STATUS_SUCCESS);
+    PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION Spi
+        = (PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) Buffer;
+
+    LONG i;
+    ULONG TotalTime;
+    LARGE_INTEGER CurrentTime;
+    PKPRCB Prcb;
+
+    *ReqSize = KeNumberProcessors * sizeof (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION);
+
+    /* Check user buffer's size */
+    if (Size < *ReqSize)
+    {
+        return STATUS_INFO_LENGTH_MISMATCH;
+    }
+
+    CurrentTime.QuadPart = KeQueryInterruptTime();
+    Prcb = KeGetPcr()->Prcb;
+    for (i = 0; i < KeNumberProcessors; i++)
+    {
+        /* Calculate total user and kernel times */
+        TotalTime = Prcb->IdleThread->KernelTime + Prcb->IdleThread->UserTime;
+        Spi->IdleTime.QuadPart = UInt32x32To64(TotalTime, KeMaximumIncrement);
+        Spi->KernelTime.QuadPart =  UInt32x32To64(Prcb->KernelTime, KeMaximumIncrement);
+        Spi->UserTime.QuadPart = UInt32x32To64(Prcb->UserTime, KeMaximumIncrement);
+        Spi->DpcTime.QuadPart = UInt32x32To64(Prcb->DpcTime, KeMaximumIncrement);
+        Spi->InterruptTime.QuadPart = UInt32x32To64(Prcb->InterruptTime, KeMaximumIncrement);
+        Spi->InterruptCount = Prcb->InterruptCount;
+        Spi++;
+        Prcb = (PKPRCB)((ULONG_PTR)Prcb + PAGE_SIZE);
+    }
+
+    return STATUS_SUCCESS;
 }
 
 /* Class 9 - Flags Information */

Modified: trunk/reactos/ntoskrnl/include/internal/ke.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/ke.h?rev=37934&r1=37933&r2=37934&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ke.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/ke.h [iso-8859-1] Mon Dec  8 06:57:53 2008
@@ -716,6 +716,16 @@
 FASTCALL
 KiActivateWaiterQueue(IN PKQUEUE Queue);
 
+ULONG
+NTAPI
+KeQueryRuntimeProcess(IN PKPROCESS Process,
+                      OUT PULONG UserTime);
+
+ULONG
+NTAPI
+KeQueryRuntimeThread(IN PKTHREAD Thread,
+                     OUT PULONG UserTime);
+
 /* INITIALIZATION FUNCTIONS *************************************************/
 
 BOOLEAN

Modified: trunk/reactos/ntoskrnl/ke/procobj.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/procobj.c?rev=37934&r1=37933&r2=37934&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ke/procobj.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/procobj.c [iso-8859-1] Mon Dec  8 06:57:53 2008
@@ -722,6 +722,54 @@
 /*
  * @implemented
  */
+ULONG
+NTAPI
+KeQueryRuntimeProcess(IN PKPROCESS Process,
+                      OUT PULONG UserTime)
+{
+    ULONG TotalUser, TotalKernel;
+    KLOCK_QUEUE_HANDLE ProcessLock;
+    PLIST_ENTRY NextEntry, ListHead;
+    PKTHREAD Thread;
+
+    ASSERT_PROCESS(Process);
+
+    /* Initialize user and kernel times */
+    TotalUser = Process->UserTime;
+    TotalKernel = Process->KernelTime;
+
+    /* Lock the process */
+    KiAcquireProcessLock(Process, &ProcessLock);
+
+    /* Loop all child threads and sum up their times */
+    ListHead = &Process->ThreadListHead;
+    NextEntry = ListHead->Flink;
+    while (ListHead != NextEntry)
+    {
+        /* Get the thread */
+        Thread = CONTAINING_RECORD(NextEntry, KTHREAD, ThreadListEntry);
+
+        /* Sum up times */
+        TotalKernel += Thread->KernelTime;
+        TotalUser += Thread->UserTime;
+
+        /* Go to the next one */
+        NextEntry = NextEntry->Flink;
+    }
+
+    /* Release lock */
+    KiReleaseProcessLock(&ProcessLock);
+
+    /* Return the user time */
+    *UserTime = TotalUser;
+
+    /* Return the kernel time */
+    return TotalKernel;
+}
+
+/*
+ * @implemented
+ */
 BOOLEAN
 NTAPI
 KeAddSystemServiceTable(IN PULONG_PTR Base,



More information about the Ros-diffs mailing list