Author: ion
Date: Thu Aug 24 10:52:33 2006
New Revision: 23680
URL: http://svn.reactos.org/svn/reactos?rev=23680&view=rev
Log:
- 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.
Added:
trunk/reactos/ntoskrnl/ke/i386/clock.S
Modified:
trunk/reactos/ntoskrnl/ke/clock.c
trunk/reactos/ntoskrnl/ke/i386/irq.c
trunk/reactos/ntoskrnl/ntoskrnl.rbuild
Modified: trunk/reactos/ntoskrnl/ke/clock.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/clock.c?rev=23…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/clock.c (original)
+++ trunk/reactos/ntoskrnl/ke/clock.c Thu Aug 24 10:52:33 2006
@@ -247,18 +247,15 @@
IN KIRQL Irql)
{
PKPRCB Prcb = KeGetCurrentPrcb();
- PKTHREAD CurrentThread;
- PKPROCESS CurrentProcess;
-
- /* Make sure we don't go further if we're in early boot phase. */
- if (!(Prcb) || !(Prcb->CurrentThread)) return;
-
- /* Get the current thread and process */
- CurrentThread = Prcb->CurrentThread;
- CurrentProcess = CurrentThread->ApcState.Process;
+ PKTHREAD CurrentThread = Prcb->CurrentThread;
+ PKPROCESS CurrentProcess = CurrentThread->ApcState.Process;
+
+ /* Increase interrupt count */
+ Prcb->InterruptCount++;
/* Check if we came from user mode */
- if (TrapFrame->PreviousPreviousMode != KernelMode)
+ if ((TrapFrame->EFlags & EFLAGS_V86_MASK) ||
+ (TrapFrame->SegCs & MODE_MASK))
{
/* Update user times */
CurrentThread->UserTime++;
@@ -267,6 +264,9 @@
}
else
{
+ /* Update CPU kernel time in all cases */
+ Prcb->KernelTime++;
+
/* Check IRQ */
if (Irql > DISPATCH_LEVEL)
{
@@ -284,9 +284,6 @@
/* This was DPC time */
Prcb->DpcTime++;
}
-
- /* Update CPU kernel time in all cases */
- Prcb->KernelTime++;
}
/* Set the last DPC Count and request rate */
@@ -295,7 +292,9 @@
Prcb->DpcRequestRate) / 2;
/* 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 */
HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
@@ -335,7 +334,8 @@
* we don't care about the quantum value anymore after the QuantumEnd
* flag is set.
*/
- if ((CurrentThread->Quantum -= 3) <= 0)
+ if (((CurrentThread->Quantum -= 3) <= 0) &&
+ (Prcb->IdleThread != CurrentThread))
{
Prcb->QuantumEnd = TRUE;
HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
@@ -414,6 +414,10 @@
KiTickOffset += KeMaximumIncrement;
KeUpdateRunTime(TrapFrame, Irql);
}
+
+ /* Return from the interrupt */
+ Ke386DisableInterrupts();
+ HalEndSystemInterrupt(Irql, 0);
}
/*
Added: trunk/reactos/ntoskrnl/ke/i386/clock.S
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/clock.S?r…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/clock.S (added)
+++ trunk/reactos/ntoskrnl/ke/i386/clock.S Thu Aug 24 10:52:33 2006
@@ -1,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(a)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
Modified: trunk/reactos/ntoskrnl/ke/i386/irq.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/irq.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/irq.c (original)
+++ trunk/reactos/ntoskrnl/ke/i386/irq.c Thu Aug 24 10:52:33 2006
@@ -156,7 +156,7 @@
if (KiClockSetupComplete)
{
KeIRQTrapFrameToTrapFrame(Trapframe, &KernelTrapFrame);
- KeUpdateSystemTime(&KernelTrapFrame, old_level, 100000);
+ return KeUpdateSystemTime(&KernelTrapFrame, old_level, 100000);
}
/*
Modified: trunk/reactos/ntoskrnl/ntoskrnl.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ntoskrnl.rbuild?r…
==============================================================================
--- trunk/reactos/ntoskrnl/ntoskrnl.rbuild (original)
+++ trunk/reactos/ntoskrnl/ntoskrnl.rbuild Thu Aug 24 10:52:33 2006
@@ -29,6 +29,7 @@
<file first="true">main_asm.S</file>
<file>cpu.S</file>
<file>ctxswitch.S</file>
+ <file>clock.S</file>
<file>exp.c</file>
<file>fpu.c</file>
<file>gdt.c</file>