- 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
* PROJECT: ReactOS kernel
@ -720,8 +720,8 @@ QSI_DEF(SystemProcessorPerformanceInformation)
Spi->TotalProcessorTime.QuadPart = KiKernelTime * 100000LL; // KernelTime
Spi->TotalProcessorUserTime.QuadPart = KiUserTime * 100000LL;
Spi->TotalDPCTime.QuadPart = KiDpcTime * 100000LL;
Spi->TotalInterruptTime = CurrentTime;
Spi->TotalInterrupts = CurrentTime.QuadPart / 100000LL; // Interrupt Count
Spi->TotalInterruptTime.QuadPart = KiInterruptTime * 100000LL;
Spi->TotalInterrupts = KiInterruptCount; // Interrupt Count
ObDereferenceObject(TheIdleProcess);

View file

@ -119,6 +119,27 @@ typedef struct _KTRAP_FRAME
USHORT Reserved9;
} 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;
VOID
KiInitializeGdt(struct _KPCR* Pcr);
@ -135,7 +156,7 @@ VOID KeFreeGdtSelector(ULONG Entry);
VOID
NtEarlyInitVdm(VOID);
#define X86_EFLAGS_VM 0x00020000 /* Virtual Mode */
#define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */
#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__
struct _KTHREAD;
struct _KIRQ_TRAPFRAME;
VOID STDCALL
DbgBreakPointNoBugCheck(VOID);
@ -73,7 +74,7 @@ KeUpdateSystemTime(
IN ULONG Increment
);
VOID KiUpdateSystemTime (KIRQL oldIrql, ULONG Eip);
VOID KiUpdateSystemTime (KIRQL oldIrql, struct _KIRQ_TRAPFRAME* Tf);
KIRQL KeAcquireDispatcherDatabaseLock(VOID);
VOID KeAcquireDispatcherDatabaseLockAtDpcLevel(VOID);
@ -102,6 +103,8 @@ extern LARGE_INTEGER SystemBootTime;
extern volatile ULONGLONG KiKernelTime;
extern volatile ULONGLONG KiUserTime;
extern volatile ULONGLONG KiDpcTime;
extern volatile ULONGLONG KiInterruptTime;
extern volatile ULONG KiInterruptCount;
/* INITIALIZATION FUNCTIONS *************************************************/
@ -158,7 +161,7 @@ VOID
KiDumpTrapFrame(PKTRAP_FRAME Tf, ULONG ExceptionNr, ULONG cr2);
VOID
KiUpdateProcessThreadTime(VOID);
KiUpdateProcessThreadTime(KIRQL pldIrql, struct _KIRQ_TRAPFRAME* Tf);
VOID
STDCALL

View file

@ -18,7 +18,7 @@
* along with this program; if not, write to the Free Software
* 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
* PROJECT: ReactOS kernel
@ -40,15 +40,12 @@
#define NDEBUG
#include <internal/debug.h>
extern volatile ULONGLONG KeTickCount;
/* TYPES *******************************************************************/
/* GLOBALS ******************************************************************/
static LIST_ENTRY DpcQueueHead; /* Head of the list of pending DPCs */
static KSPIN_LOCK DpcQueueLock; /* Lock for the above list */
static ULONGLONG DpcTimeInside = 0;
/*
* Number of pending DPCs. This is inspected by
@ -109,7 +106,6 @@ KiDispatchInterrupt(VOID)
KeRaiseIrql(HIGH_LEVEL, &oldlvl);
KiAcquireSpinLock(&DpcQueueLock);
DpcTimeInside = KeTickCount;
DpcCount = DpcCount + DpcQueueSize;
while (!IsListEmpty(&DpcQueueHead))
@ -130,7 +126,6 @@ KiDispatchInterrupt(VOID)
KeRaiseIrql(HIGH_LEVEL, &oldlvl);
KiAcquireSpinLock(&DpcQueueLock);
}
KiDpcTime += (KeTickCount - DpcTimeInside);
KiReleaseSpinLock(&DpcQueueLock);
KeLowerIrql(oldlvl);

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* 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
* 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
KeIRQTrapFrameToTrapFrame(PKIRQ_TRAPFRAME IrqTrapFrame,
PKTRAP_FRAME TrapFrame)
@ -425,30 +406,23 @@ KiInterruptDispatch2 (ULONG Irq, KIRQL old_level)
PKINTERRUPT isr;
PLIST_ENTRY current;
if (Irq == 0)
{
KiUpdateSystemTime(old_level, 0);
}
else
{
/*
* 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);
/*
* 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 (isr->ServiceRoutine(isr, isr->ServiceContext))
{
break;
}
if (isr->ServiceRoutine(isr, isr->ServiceContext))
{
break;
}
#else
isr->ServiceRoutine(isr, isr->ServiceContext);
isr->ServiceRoutine(isr, isr->ServiceContext);
#endif
current = current->Flink;
}
}
current = current->Flink;
}
}
VOID
@ -469,6 +443,8 @@ KiInterruptDispatch (ULONG irq, PKIRQ_TRAPFRAME Trapframe)
* the PIC.
*/
KiInterruptCount++;
/*
* Notify the rest of the kernel of the raised irq level. For the
* default HAL this will send an EOI to the PIC and alter the IRQL.
@ -487,10 +463,18 @@ KiInterruptDispatch (ULONG irq, PKIRQ_TRAPFRAME Trapframe)
*/
Ke386EnableInterrupts();
/*
* Actually call the ISR.
*/
KiInterruptDispatch2(irq, old_level);
if (irq == 0)
{
KiUpdateSystemTime(old_level, Trapframe);
}
else
{
/*
* Actually call the ISR.
*/
KiInterruptDispatch2(irq, old_level);
}
#ifdef KDBG
if (irq == 0)
@ -515,11 +499,6 @@ KiInterruptDispatch (ULONG irq, PKIRQ_TRAPFRAME Trapframe)
HalEndSystemInterrupt (old_level, 0);
if (old_level==PASSIVE_LEVEL)
{
KiUpdateProcessThreadTime();
}
if (old_level==PASSIVE_LEVEL && Trapframe->Cs != KERNEL_CS)
{
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
* PROJECT: ReactOS kernel
@ -37,6 +37,8 @@ CHAR KiTimerSystemAuditing = 0;
volatile ULONGLONG KiKernelTime;
volatile ULONGLONG KiUserTime;
volatile ULONGLONG KiDpcTime;
volatile ULONGLONG KiInterruptTime;
volatile ULONG KiInterruptCount;
/*
* Number of timer interrupts since initialisation
@ -60,7 +62,6 @@ static LIST_ENTRY AbsoluteTimerListHead;
static LIST_ENTRY RelativeTimerListHead;
static KSPIN_LOCK TimerListLock;
static KSPIN_LOCK TimerValueLock;
static KSPIN_LOCK TimeLock;
static KDPC ExpireTimerDpc;
/* must raise IRQL to PROFILE_LEVEL and grab spin lock there, to sync with ISR */
@ -617,7 +618,7 @@ KeExpireTimers(PKDPC Dpc,
VOID
KiUpdateSystemTime(KIRQL oldIrql,
ULONG Eip)
PKIRQ_TRAPFRAME Tf)
/*
* FUNCTION: Handles a timer interrupt
*/
@ -655,10 +656,13 @@ KiUpdateSystemTime(KIRQL oldIrql,
KiReleaseSpinLock(&TimerValueLock);
/* Update process and thread times */
KiUpdateProcessThreadTime(oldIrql, Tf);
/*
* 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);
KeInitializeSpinLock(&TimerListLock);
KeInitializeSpinLock(&TimerValueLock);
KeInitializeSpinLock(&TimeLock);
KeInitializeDpc(&ExpireTimerDpc, KeExpireTimers, 0);
/*
* Calculate the starting time for the system clock
@ -699,12 +702,12 @@ KeInitializeTimerImpl(VOID)
VOID
KiUpdateProcessThreadTime(VOID)
KiUpdateProcessThreadTime(KIRQL oldIrql, PKIRQ_TRAPFRAME Tf)
{
PKTHREAD CurrentThread;
PKPROCESS CurrentProcess;
PEPROCESS ThreadsProcess;
assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
/*
* Make sure no counting can take place until Processes and Threads are
* running!
@ -715,31 +718,46 @@ KiUpdateProcessThreadTime(VOID)
return;
}
CurrentProcess = KeGetCurrentProcess();
CurrentThread = KeGetCurrentThread();
DPRINT("KiKernelTime %u, KiUserTime %u \n", KiKernelTime, KiUserTime);
/* Over kill with locks. */
KiAcquireSpinLock(&TimeLock);
if (CurrentThread->PreviousMode == UserMode)
{
/* Lock the process & thread time. This should lock everything
* all the way down to the process & thread stuct.
*/
InterlockedIncrement((LONG *)&CurrentProcess->UserTime);
InterlockedIncrement((LONG *)&CurrentThread->UserTime);
++KiUserTime;
}
if (CurrentThread->PreviousMode == KernelMode)
{
InterlockedIncrement((LONG *)&CurrentProcess->KernelTime);
InterlockedIncrement((LONG *)&CurrentThread->KernelTime);
++KiKernelTime;
}
KiReleaseSpinLock(&TimeLock);
if (oldIrql > DISPATCH_LEVEL)
{
KiInterruptTime++;
}
else if (oldIrql == DISPATCH_LEVEL)
{
KiDpcTime++;
}
else
{
CurrentThread = KeGetCurrentThread();
ThreadsProcess = ((PETHREAD)CurrentThread)->ThreadsProcess;
/*
* Cs bit 0 is always set for user mode if we are in protected mode.
* V86 mode is counted as user time.
*/
if (Tf->Cs & 0x1 ||
Tf->Eflags & X86_EFLAGS_VM)
{
#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++;
}
}
}
/*