- Rewrote parts of the Process & Thread time count functions.

svn path=/trunk/; revision=11142
This commit is contained in:
Hartmut Birr 2004-10-01 20:09:57 +00:00
parent 96bb83f2a9
commit f6fb22a9ef
6 changed files with 109 additions and 93 deletions

View file

@ -1,4 +1,4 @@
/* $Id: sysinfo.c,v 1.48 2004/09/30 21:14:24 ea Exp $ /* $Id: sysinfo.c,v 1.49 2004/10/01 20:09:56 hbirr Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -720,8 +720,8 @@ QSI_DEF(SystemProcessorPerformanceInformation)
Spi->TotalProcessorTime.QuadPart = KiKernelTime * 100000LL; // KernelTime Spi->TotalProcessorTime.QuadPart = KiKernelTime * 100000LL; // KernelTime
Spi->TotalProcessorUserTime.QuadPart = KiUserTime * 100000LL; Spi->TotalProcessorUserTime.QuadPart = KiUserTime * 100000LL;
Spi->TotalDPCTime.QuadPart = KiDpcTime * 100000LL; Spi->TotalDPCTime.QuadPart = KiDpcTime * 100000LL;
Spi->TotalInterruptTime = CurrentTime; Spi->TotalInterruptTime.QuadPart = KiInterruptTime * 100000LL;
Spi->TotalInterrupts = CurrentTime.QuadPart / 100000LL; // Interrupt Count Spi->TotalInterrupts = KiInterruptCount; // Interrupt Count
ObDereferenceObject(TheIdleProcess); ObDereferenceObject(TheIdleProcess);

View file

@ -119,6 +119,27 @@ typedef struct _KTRAP_FRAME
USHORT Reserved9; USHORT Reserved9;
} KTRAP_FRAME, *PKTRAP_FRAME; } KTRAP_FRAME, *PKTRAP_FRAME;
typedef struct _KIRQ_TRAPFRAME
{
ULONG Magic;
ULONG Fs;
ULONG Es;
ULONG Ds;
ULONG Eax;
ULONG Ecx;
ULONG Edx;
ULONG Ebx;
ULONG Esp;
ULONG Ebp;
ULONG Esi;
ULONG Edi;
ULONG Eip;
ULONG Cs;
ULONG Eflags;
} KIRQ_TRAPFRAME, *PKIRQ_TRAPFRAME;
extern ULONG Ke386CacheAlignment;
struct _KPCR; struct _KPCR;
VOID VOID
KiInitializeGdt(struct _KPCR* Pcr); KiInitializeGdt(struct _KPCR* Pcr);
@ -135,7 +156,7 @@ VOID KeFreeGdtSelector(ULONG Entry);
VOID VOID
NtEarlyInitVdm(VOID); NtEarlyInitVdm(VOID);
#define X86_EFLAGS_VM 0x00020000 /* Virtual Mode */
#define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */ #define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */
#define X86_CR4_PAE 0x00000020 /* enable physical address extensions */ #define X86_CR4_PAE 0x00000020 /* enable physical address extensions */

View file

@ -39,6 +39,7 @@ VOID KeSetGdtSelector(ULONG Entry, ULONG Value1, ULONG Value2);
#ifndef __ASM__ #ifndef __ASM__
struct _KTHREAD; struct _KTHREAD;
struct _KIRQ_TRAPFRAME;
VOID STDCALL VOID STDCALL
DbgBreakPointNoBugCheck(VOID); DbgBreakPointNoBugCheck(VOID);
@ -73,7 +74,7 @@ KeUpdateSystemTime(
IN ULONG Increment IN ULONG Increment
); );
VOID KiUpdateSystemTime (KIRQL oldIrql, ULONG Eip); VOID KiUpdateSystemTime (KIRQL oldIrql, struct _KIRQ_TRAPFRAME* Tf);
KIRQL KeAcquireDispatcherDatabaseLock(VOID); KIRQL KeAcquireDispatcherDatabaseLock(VOID);
VOID KeAcquireDispatcherDatabaseLockAtDpcLevel(VOID); VOID KeAcquireDispatcherDatabaseLockAtDpcLevel(VOID);
@ -102,6 +103,8 @@ extern LARGE_INTEGER SystemBootTime;
extern volatile ULONGLONG KiKernelTime; extern volatile ULONGLONG KiKernelTime;
extern volatile ULONGLONG KiUserTime; extern volatile ULONGLONG KiUserTime;
extern volatile ULONGLONG KiDpcTime; extern volatile ULONGLONG KiDpcTime;
extern volatile ULONGLONG KiInterruptTime;
extern volatile ULONG KiInterruptCount;
/* INITIALIZATION FUNCTIONS *************************************************/ /* INITIALIZATION FUNCTIONS *************************************************/
@ -158,7 +161,7 @@ VOID
KiDumpTrapFrame(PKTRAP_FRAME Tf, ULONG ExceptionNr, ULONG cr2); KiDumpTrapFrame(PKTRAP_FRAME Tf, ULONG ExceptionNr, ULONG cr2);
VOID VOID
KiUpdateProcessThreadTime(VOID); KiUpdateProcessThreadTime(KIRQL pldIrql, struct _KIRQ_TRAPFRAME* Tf);
VOID VOID
STDCALL STDCALL

View file

@ -18,7 +18,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: dpc.c,v 1.35 2004/08/21 21:09:39 tamlin Exp $ /* $Id: dpc.c,v 1.36 2004/10/01 20:09:57 hbirr Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -40,15 +40,12 @@
#define NDEBUG #define NDEBUG
#include <internal/debug.h> #include <internal/debug.h>
extern volatile ULONGLONG KeTickCount;
/* TYPES *******************************************************************/ /* TYPES *******************************************************************/
/* GLOBALS ******************************************************************/ /* GLOBALS ******************************************************************/
static LIST_ENTRY DpcQueueHead; /* Head of the list of pending DPCs */ static LIST_ENTRY DpcQueueHead; /* Head of the list of pending DPCs */
static KSPIN_LOCK DpcQueueLock; /* Lock for the above list */ static KSPIN_LOCK DpcQueueLock; /* Lock for the above list */
static ULONGLONG DpcTimeInside = 0;
/* /*
* Number of pending DPCs. This is inspected by * Number of pending DPCs. This is inspected by
@ -109,7 +106,6 @@ KiDispatchInterrupt(VOID)
KeRaiseIrql(HIGH_LEVEL, &oldlvl); KeRaiseIrql(HIGH_LEVEL, &oldlvl);
KiAcquireSpinLock(&DpcQueueLock); KiAcquireSpinLock(&DpcQueueLock);
DpcTimeInside = KeTickCount;
DpcCount = DpcCount + DpcQueueSize; DpcCount = DpcCount + DpcQueueSize;
while (!IsListEmpty(&DpcQueueHead)) while (!IsListEmpty(&DpcQueueHead))
@ -130,7 +126,6 @@ KiDispatchInterrupt(VOID)
KeRaiseIrql(HIGH_LEVEL, &oldlvl); KeRaiseIrql(HIGH_LEVEL, &oldlvl);
KiAcquireSpinLock(&DpcQueueLock); KiAcquireSpinLock(&DpcQueueLock);
} }
KiDpcTime += (KeTickCount - DpcTimeInside);
KiReleaseSpinLock(&DpcQueueLock); KiReleaseSpinLock(&DpcQueueLock);
KeLowerIrql(oldlvl); KeLowerIrql(oldlvl);

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: irq.c,v 1.45 2004/08/15 16:39:05 chorns Exp $ /* $Id: irq.c,v 1.46 2004/10/01 20:09:57 hbirr Exp $
* *
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/i386/irq.c * FILE: ntoskrnl/ke/i386/irq.c
@ -246,25 +246,6 @@ KeInitInterrupts (VOID)
} }
typedef struct _KIRQ_TRAPFRAME
{
ULONG Magic;
ULONG Fs;
ULONG Es;
ULONG Ds;
ULONG Eax;
ULONG Ecx;
ULONG Edx;
ULONG Ebx;
ULONG Esp;
ULONG Ebp;
ULONG Esi;
ULONG Edi;
ULONG Eip;
ULONG Cs;
ULONG Eflags;
} KIRQ_TRAPFRAME, *PKIRQ_TRAPFRAME;
VOID VOID
KeIRQTrapFrameToTrapFrame(PKIRQ_TRAPFRAME IrqTrapFrame, KeIRQTrapFrameToTrapFrame(PKIRQ_TRAPFRAME IrqTrapFrame,
PKTRAP_FRAME TrapFrame) PKTRAP_FRAME TrapFrame)
@ -425,30 +406,23 @@ KiInterruptDispatch2 (ULONG Irq, KIRQL old_level)
PKINTERRUPT isr; PKINTERRUPT isr;
PLIST_ENTRY current; PLIST_ENTRY current;
if (Irq == 0) /*
{ * Iterate the list until one of the isr tells us its device interrupted
KiUpdateSystemTime(old_level, 0); */
} current = isr_table[Irq].Flink;
else while (current != &isr_table[Irq])
{ {
/* isr = CONTAINING_RECORD(current,KINTERRUPT,Entry);
* Iterate the list until one of the isr tells us its device interrupted
*/
current = isr_table[Irq].Flink;
while (current != &isr_table[Irq])
{
isr = CONTAINING_RECORD(current,KINTERRUPT,Entry);
#if 0 #if 0
if (isr->ServiceRoutine(isr, isr->ServiceContext)) if (isr->ServiceRoutine(isr, isr->ServiceContext))
{ {
break; break;
} }
#else #else
isr->ServiceRoutine(isr, isr->ServiceContext); isr->ServiceRoutine(isr, isr->ServiceContext);
#endif #endif
current = current->Flink; current = current->Flink;
} }
}
} }
VOID VOID
@ -468,6 +442,8 @@ KiInterruptDispatch (ULONG irq, PKIRQ_TRAPFRAME Trapframe)
* At this point we have interrupts disabled, nothing has been done to * At this point we have interrupts disabled, nothing has been done to
* the PIC. * the PIC.
*/ */
KiInterruptCount++;
/* /*
* Notify the rest of the kernel of the raised irq level. For the * Notify the rest of the kernel of the raised irq level. For the
@ -487,10 +463,18 @@ KiInterruptDispatch (ULONG irq, PKIRQ_TRAPFRAME Trapframe)
*/ */
Ke386EnableInterrupts(); Ke386EnableInterrupts();
/*
* Actually call the ISR. if (irq == 0)
*/ {
KiInterruptDispatch2(irq, old_level); KiUpdateSystemTime(old_level, Trapframe);
}
else
{
/*
* Actually call the ISR.
*/
KiInterruptDispatch2(irq, old_level);
}
#ifdef KDBG #ifdef KDBG
if (irq == 0) if (irq == 0)
@ -515,11 +499,6 @@ KiInterruptDispatch (ULONG irq, PKIRQ_TRAPFRAME Trapframe)
HalEndSystemInterrupt (old_level, 0); HalEndSystemInterrupt (old_level, 0);
if (old_level==PASSIVE_LEVEL)
{
KiUpdateProcessThreadTime();
}
if (old_level==PASSIVE_LEVEL && Trapframe->Cs != KERNEL_CS) if (old_level==PASSIVE_LEVEL && Trapframe->Cs != KERNEL_CS)
{ {
CurrentThread = KeGetCurrentThread(); CurrentThread = KeGetCurrentThread();

View file

@ -1,4 +1,4 @@
/* $Id: timer.c,v 1.78 2004/09/28 15:02:29 weiden Exp $ /* $Id: timer.c,v 1.79 2004/10/01 20:09:57 hbirr Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -37,6 +37,8 @@ CHAR KiTimerSystemAuditing = 0;
volatile ULONGLONG KiKernelTime; volatile ULONGLONG KiKernelTime;
volatile ULONGLONG KiUserTime; volatile ULONGLONG KiUserTime;
volatile ULONGLONG KiDpcTime; volatile ULONGLONG KiDpcTime;
volatile ULONGLONG KiInterruptTime;
volatile ULONG KiInterruptCount;
/* /*
* Number of timer interrupts since initialisation * Number of timer interrupts since initialisation
@ -60,7 +62,6 @@ static LIST_ENTRY AbsoluteTimerListHead;
static LIST_ENTRY RelativeTimerListHead; static LIST_ENTRY RelativeTimerListHead;
static KSPIN_LOCK TimerListLock; static KSPIN_LOCK TimerListLock;
static KSPIN_LOCK TimerValueLock; static KSPIN_LOCK TimerValueLock;
static KSPIN_LOCK TimeLock;
static KDPC ExpireTimerDpc; static KDPC ExpireTimerDpc;
/* must raise IRQL to PROFILE_LEVEL and grab spin lock there, to sync with ISR */ /* must raise IRQL to PROFILE_LEVEL and grab spin lock there, to sync with ISR */
@ -617,7 +618,7 @@ KeExpireTimers(PKDPC Dpc,
VOID VOID
KiUpdateSystemTime(KIRQL oldIrql, KiUpdateSystemTime(KIRQL oldIrql,
ULONG Eip) PKIRQ_TRAPFRAME Tf)
/* /*
* FUNCTION: Handles a timer interrupt * FUNCTION: Handles a timer interrupt
*/ */
@ -655,10 +656,13 @@ KiUpdateSystemTime(KIRQL oldIrql,
KiReleaseSpinLock(&TimerValueLock); KiReleaseSpinLock(&TimerValueLock);
/* Update process and thread times */
KiUpdateProcessThreadTime(oldIrql, Tf);
/* /*
* Queue a DPC that will expire timers * Queue a DPC that will expire timers
*/ */
KeInsertQueueDpc(&ExpireTimerDpc, (PVOID)Eip, 0); KeInsertQueueDpc(&ExpireTimerDpc, (PVOID)Tf->Eip, 0);
} }
@ -676,7 +680,6 @@ KeInitializeTimerImpl(VOID)
InitializeListHead(&RelativeTimerListHead); InitializeListHead(&RelativeTimerListHead);
KeInitializeSpinLock(&TimerListLock); KeInitializeSpinLock(&TimerListLock);
KeInitializeSpinLock(&TimerValueLock); KeInitializeSpinLock(&TimerValueLock);
KeInitializeSpinLock(&TimeLock);
KeInitializeDpc(&ExpireTimerDpc, KeExpireTimers, 0); KeInitializeDpc(&ExpireTimerDpc, KeExpireTimers, 0);
/* /*
* Calculate the starting time for the system clock * Calculate the starting time for the system clock
@ -699,12 +702,12 @@ KeInitializeTimerImpl(VOID)
VOID VOID
KiUpdateProcessThreadTime(VOID) KiUpdateProcessThreadTime(KIRQL oldIrql, PKIRQ_TRAPFRAME Tf)
{ {
PKTHREAD CurrentThread; PKTHREAD CurrentThread;
PKPROCESS CurrentProcess; PEPROCESS ThreadsProcess;
assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
/* /*
* Make sure no counting can take place until Processes and Threads are * Make sure no counting can take place until Processes and Threads are
* running! * running!
@ -715,31 +718,46 @@ KiUpdateProcessThreadTime(VOID)
return; return;
} }
CurrentProcess = KeGetCurrentProcess();
CurrentThread = KeGetCurrentThread();
DPRINT("KiKernelTime %u, KiUserTime %u \n", KiKernelTime, KiUserTime); DPRINT("KiKernelTime %u, KiUserTime %u \n", KiKernelTime, KiUserTime);
/* Over kill with locks. */ if (oldIrql > DISPATCH_LEVEL)
KiAcquireSpinLock(&TimeLock); {
KiInterruptTime++;
if (CurrentThread->PreviousMode == UserMode) }
{ else if (oldIrql == DISPATCH_LEVEL)
/* Lock the process & thread time. This should lock everything {
* all the way down to the process & thread stuct. KiDpcTime++;
*/ }
InterlockedIncrement((LONG *)&CurrentProcess->UserTime); else
InterlockedIncrement((LONG *)&CurrentThread->UserTime); {
++KiUserTime; CurrentThread = KeGetCurrentThread();
} ThreadsProcess = ((PETHREAD)CurrentThread)->ThreadsProcess;
if (CurrentThread->PreviousMode == KernelMode) /*
{ * Cs bit 0 is always set for user mode if we are in protected mode.
InterlockedIncrement((LONG *)&CurrentProcess->KernelTime); * V86 mode is counted as user time.
InterlockedIncrement((LONG *)&CurrentThread->KernelTime); */
++KiKernelTime; if (Tf->Cs & 0x1 ||
} Tf->Eflags & X86_EFLAGS_VM)
{
KiReleaseSpinLock(&TimeLock); #ifdef MP
InterlockedIncrement((PLONG)&ThreadsProcess->Pcb.UserTime);
#else
ThreadsProcess->Pcb.UserTime++;
#endif
CurrentThread->UserTime++;
KiUserTime++;
}
else
{
#ifdef MP
InterlockedIncrement((PLONG)&ThreadsProcess->Pcb.KernelTime);
#else
ThreadsProcess->Pcb.KernelTime++;
#endif
CurrentThread->KernelTime++;
KiKernelTime++;
}
}
} }
/* /*