mirror of
https://github.com/reactos/reactos.git
synced 2024-09-11 05:12:43 +00:00
- Make KeUpdateSystemTime independent, so that it returns and exits from the current ROSterrupt by itself.
- Make KeUpdateRunTime increase the interrupt count, check for V86 as well as for user-mode by using the CS and EFLAGS (isntead of PreviousMode), also only request DPCs if DpcInterruptRequested isn't already set, and only perform Quantum End if this isn't the idle thread. - Add clock.S which will have the clock interrupt handlers of the kernel (UpdateSystemTime and UpdateRunTime) and ultimately replace the only reason irqhand.S is still around (the clock interrupt). Implement the current version of KeUpdateSystemTime in assembly, with stack optimizations since we'll be called from the HAL later. svn path=/trunk/; revision=23680
This commit is contained in:
parent
5e7ef1d665
commit
065837f112
|
@ -247,18 +247,15 @@ KeUpdateRunTime(IN PKTRAP_FRAME TrapFrame,
|
||||||
IN KIRQL Irql)
|
IN KIRQL Irql)
|
||||||
{
|
{
|
||||||
PKPRCB Prcb = KeGetCurrentPrcb();
|
PKPRCB Prcb = KeGetCurrentPrcb();
|
||||||
PKTHREAD CurrentThread;
|
PKTHREAD CurrentThread = Prcb->CurrentThread;
|
||||||
PKPROCESS CurrentProcess;
|
PKPROCESS CurrentProcess = CurrentThread->ApcState.Process;
|
||||||
|
|
||||||
/* Make sure we don't go further if we're in early boot phase. */
|
/* Increase interrupt count */
|
||||||
if (!(Prcb) || !(Prcb->CurrentThread)) return;
|
Prcb->InterruptCount++;
|
||||||
|
|
||||||
/* Get the current thread and process */
|
|
||||||
CurrentThread = Prcb->CurrentThread;
|
|
||||||
CurrentProcess = CurrentThread->ApcState.Process;
|
|
||||||
|
|
||||||
/* Check if we came from user mode */
|
/* Check if we came from user mode */
|
||||||
if (TrapFrame->PreviousPreviousMode != KernelMode)
|
if ((TrapFrame->EFlags & EFLAGS_V86_MASK) ||
|
||||||
|
(TrapFrame->SegCs & MODE_MASK))
|
||||||
{
|
{
|
||||||
/* Update user times */
|
/* Update user times */
|
||||||
CurrentThread->UserTime++;
|
CurrentThread->UserTime++;
|
||||||
|
@ -267,6 +264,9 @@ KeUpdateRunTime(IN PKTRAP_FRAME TrapFrame,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* Update CPU kernel time in all cases */
|
||||||
|
Prcb->KernelTime++;
|
||||||
|
|
||||||
/* Check IRQ */
|
/* Check IRQ */
|
||||||
if (Irql > DISPATCH_LEVEL)
|
if (Irql > DISPATCH_LEVEL)
|
||||||
{
|
{
|
||||||
|
@ -284,9 +284,6 @@ KeUpdateRunTime(IN PKTRAP_FRAME TrapFrame,
|
||||||
/* This was DPC time */
|
/* This was DPC time */
|
||||||
Prcb->DpcTime++;
|
Prcb->DpcTime++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update CPU kernel time in all cases */
|
|
||||||
Prcb->KernelTime++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the last DPC Count and request rate */
|
/* Set the last DPC Count and request rate */
|
||||||
|
@ -295,7 +292,9 @@ KeUpdateRunTime(IN PKTRAP_FRAME TrapFrame,
|
||||||
Prcb->DpcRequestRate) / 2;
|
Prcb->DpcRequestRate) / 2;
|
||||||
|
|
||||||
/* Check if we should request a DPC */
|
/* Check if we should request a DPC */
|
||||||
if ((Prcb->DpcData[0].DpcQueueDepth) && !(Prcb->DpcRoutineActive))
|
if ((Prcb->DpcData[0].DpcQueueDepth) &&
|
||||||
|
!(Prcb->DpcRoutineActive) &&
|
||||||
|
!(Prcb->DpcInterruptRequested))
|
||||||
{
|
{
|
||||||
/* Request one */
|
/* Request one */
|
||||||
HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
|
HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
|
||||||
|
@ -335,7 +334,8 @@ KeUpdateRunTime(IN PKTRAP_FRAME TrapFrame,
|
||||||
* we don't care about the quantum value anymore after the QuantumEnd
|
* we don't care about the quantum value anymore after the QuantumEnd
|
||||||
* flag is set.
|
* flag is set.
|
||||||
*/
|
*/
|
||||||
if ((CurrentThread->Quantum -= 3) <= 0)
|
if (((CurrentThread->Quantum -= 3) <= 0) &&
|
||||||
|
(Prcb->IdleThread != CurrentThread))
|
||||||
{
|
{
|
||||||
Prcb->QuantumEnd = TRUE;
|
Prcb->QuantumEnd = TRUE;
|
||||||
HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
|
HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
|
||||||
|
@ -414,6 +414,10 @@ KeUpdateSystemTime(IN PKTRAP_FRAME TrapFrame,
|
||||||
KiTickOffset += KeMaximumIncrement;
|
KiTickOffset += KeMaximumIncrement;
|
||||||
KeUpdateRunTime(TrapFrame, Irql);
|
KeUpdateRunTime(TrapFrame, Irql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return from the interrupt */
|
||||||
|
Ke386DisableInterrupts();
|
||||||
|
HalEndSystemInterrupt(Irql, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
113
reactos/ntoskrnl/ke/i386/clock.S
Normal file
113
reactos/ntoskrnl/ke/i386/clock.S
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
/*
|
||||||
|
* FILE: ntoskrnl/ke/i386/clock.S
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PURPOSE: System Clock Management
|
||||||
|
* PROGRAMMER: Alex Ionescu (alex@relsoft.net)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES ******************************************************************/
|
||||||
|
|
||||||
|
#include <asm.h>
|
||||||
|
#include <internal/i386/asmmacro.S>
|
||||||
|
.intel_syntax noprefix
|
||||||
|
|
||||||
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
||||||
|
.extern _KeTimeAdjustment
|
||||||
|
.extern _KiTickOffset
|
||||||
|
.extern _KeTickCount
|
||||||
|
.extern _KeMaximumIncrement
|
||||||
|
|
||||||
|
/* FUNCTIONS ******************************************************************/
|
||||||
|
|
||||||
|
.globl _KeUpdateSystemTime2@0
|
||||||
|
.func KeUpdateSystemTime2@0
|
||||||
|
_KeUpdateSystemTime2@0:
|
||||||
|
|
||||||
|
/* Get shared data in ECX */
|
||||||
|
mov ecx, USER_SHARED_DATA
|
||||||
|
|
||||||
|
/* Get interrupt time */
|
||||||
|
mov edi, [ecx+USER_SHARED_DATA_INTERRUPT_TIME]
|
||||||
|
mov esi, [ecx+USER_SHARED_DATA_INTERRUPT_TIME+4]
|
||||||
|
|
||||||
|
/* Add the increment and get the carry */
|
||||||
|
add edi, eax
|
||||||
|
adc esi, 0
|
||||||
|
|
||||||
|
/* Now store the updated times */
|
||||||
|
mov [ecx+USER_SHARED_DATA_INTERRUPT_TIME+8], esi
|
||||||
|
mov [ecx+USER_SHARED_DATA_INTERRUPT_TIME], edi
|
||||||
|
mov [ecx+USER_SHARED_DATA_INTERRUPT_TIME+4], esi
|
||||||
|
|
||||||
|
/* Substract tick count and get the low count */
|
||||||
|
LOCK sub _KiTickOffset, eax
|
||||||
|
mov eax, _KeTickCount
|
||||||
|
mov ebx, eax
|
||||||
|
jg IncompleteTick
|
||||||
|
|
||||||
|
/* Get shared data in ECX */
|
||||||
|
mov ebx, USER_SHARED_DATA
|
||||||
|
|
||||||
|
/* Get system time */
|
||||||
|
mov edi, [ebx+USER_SHARED_DATA_SYSTEM_TIME]
|
||||||
|
mov esi, [ebx+USER_SHARED_DATA_SYSTEM_TIME+4]
|
||||||
|
|
||||||
|
/* Add the increment and get the carry */
|
||||||
|
add ecx, _KeTimeAdjustment
|
||||||
|
adc edx, 0
|
||||||
|
|
||||||
|
/* Now store the updated times */
|
||||||
|
mov [ebx+USER_SHARED_DATA_SYSTEM_TIME+8], edx
|
||||||
|
mov [ebx+USER_SHARED_DATA_SYSTEM_TIME], ecx
|
||||||
|
mov [ebx+USER_SHARED_DATA_SYSTEM_TIME+4], edx
|
||||||
|
|
||||||
|
/* Put tick count back in EBX */
|
||||||
|
mov ebx, eax
|
||||||
|
|
||||||
|
/* Copyit in ECX and get hich count */
|
||||||
|
mov ecx, eax
|
||||||
|
mov edx, _KeTickCount + 4
|
||||||
|
|
||||||
|
/* Add the increment and get the carry */
|
||||||
|
add ecx, 1
|
||||||
|
adc edx, 0
|
||||||
|
|
||||||
|
/* Now store the updated tick */
|
||||||
|
mov [_KeTickCount+8], edx
|
||||||
|
mov [_KeTickCount], ecx
|
||||||
|
mov [_KeTickCount+4], edx
|
||||||
|
|
||||||
|
/* Store in in shared data too */
|
||||||
|
mov [USER_SHARED_DATA+USER_SHARED_DATA_TICK_COUNT+8], edx
|
||||||
|
mov [USER_SHARED_DATA+USER_SHARED_DATA_TICK_COUNT], ecx
|
||||||
|
mov [USER_SHARED_DATA+USER_SHARED_DATA_TICK_COUNT+4], edx
|
||||||
|
|
||||||
|
IncompleteTick:
|
||||||
|
|
||||||
|
/* Queue DPC to handle registered timers */
|
||||||
|
|
||||||
|
/* Check if this was a full tick */
|
||||||
|
cmp dword ptr _KiTickOffset, 0
|
||||||
|
jg IncompleteTick2
|
||||||
|
|
||||||
|
/* Increase tick offset */
|
||||||
|
mov eax, _KeMaximumIncrement
|
||||||
|
add _KiTickOffset, eax
|
||||||
|
|
||||||
|
/* Update system run time */
|
||||||
|
push esp
|
||||||
|
call _KeUpdateRunTime@8
|
||||||
|
jmp Done
|
||||||
|
|
||||||
|
IncompleteTick2:
|
||||||
|
/* Increase interrupt count */
|
||||||
|
inc dword ptr [fs:KPCR_PRCB_INTERRUPT_COUNT]
|
||||||
|
|
||||||
|
Done:
|
||||||
|
/* Exit the interrupt */
|
||||||
|
mov esi, $
|
||||||
|
cli
|
||||||
|
call _HalEndSystemInterrupt@8
|
||||||
|
jmp _Kei386EoiHelper@0
|
||||||
|
.endfunc
|
|
@ -156,7 +156,7 @@ KiInterruptDispatch (ULONG vector, PKIRQ_TRAPFRAME Trapframe)
|
||||||
if (KiClockSetupComplete)
|
if (KiClockSetupComplete)
|
||||||
{
|
{
|
||||||
KeIRQTrapFrameToTrapFrame(Trapframe, &KernelTrapFrame);
|
KeIRQTrapFrameToTrapFrame(Trapframe, &KernelTrapFrame);
|
||||||
KeUpdateSystemTime(&KernelTrapFrame, old_level, 100000);
|
return KeUpdateSystemTime(&KernelTrapFrame, old_level, 100000);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
<file first="true">main_asm.S</file>
|
<file first="true">main_asm.S</file>
|
||||||
<file>cpu.S</file>
|
<file>cpu.S</file>
|
||||||
<file>ctxswitch.S</file>
|
<file>ctxswitch.S</file>
|
||||||
|
<file>clock.S</file>
|
||||||
<file>exp.c</file>
|
<file>exp.c</file>
|
||||||
<file>fpu.c</file>
|
<file>fpu.c</file>
|
||||||
<file>gdt.c</file>
|
<file>gdt.c</file>
|
||||||
|
|
Loading…
Reference in a new issue