- Save and restore the trap frame for the current thread when we take an interrupt, so that ISRs can read it.

- We use this in the clock ISR, that can now actually send the trap frame to KeUpdateSystemTime.
- Implement KeUpdateRunTime to handle time accounting and DPC rescheduling as well as Quantum End.
- Ignore quantum end for now.
- We now have a working timebase, and we're back to our earlier checkpoint around CmInitSystem1!.


svn path=/trunk/; revision=34088
This commit is contained in:
ReactOS Portable Systems Group
2008-06-26 05:56:35 +00:00
parent 227dc95404
commit 241449fc0e
3 changed files with 149 additions and 10 deletions
+3 -1
View File
@@ -485,7 +485,9 @@ HalpClockInterrupt(VOID)
//
// Call the kernel
//
KeUpdateSystemTime(NULL, CLOCK2_LEVEL, HalpCurrentTimeIncrement);
KeUpdateSystemTime(KeGetCurrentThread()->TrapFrame,
CLOCK2_LEVEL,
HalpCurrentTimeIncrement);
//
// We're done
+135 -7
View File
@@ -39,10 +39,6 @@ KeUpdateSystemTime(IN PKTRAP_FRAME TrapFrame,
PKPRCB Prcb = KeGetPcr()->Prcb;
ULARGE_INTEGER SystemTime, InterruptTime;
ULONG Hand;
DPRINT1("TIMEBASE: %I64d %I64d %I64d\n",
*(PLARGE_INTEGER)&SharedUserData->InterruptTime,
*(PLARGE_INTEGER)&SharedUserData->SystemTime,
*(PLARGE_INTEGER)&SharedUserData->TickCount);
//
// Do nothing if this tick is being skipped
@@ -143,7 +139,7 @@ KeUpdateSystemTime(IN PKTRAP_FRAME TrapFrame,
//
// Update system runtime
//
KeUpdateRunTime(NULL, CLOCK2_LEVEL);
KeUpdateRunTime(TrapFrame, CLOCK2_LEVEL);
}
else
{
@@ -159,6 +155,138 @@ NTAPI
KeUpdateRunTime(IN PKTRAP_FRAME TrapFrame,
IN KIRQL Irql)
{
UNIMPLEMENTED;
while (TRUE);
PKTHREAD Thread = KeGetCurrentThread();
PKPROCESS Process = Thread->ApcState.Process;
PKPRCB Prcb = KeGetCurrentPrcb();
//
// Do nothing if this tick is being skipped
//
if (Prcb->SkipTick)
{
//
// Handle it next time
//
Prcb->SkipTick = FALSE;
return;
}
//
// Increase interrupt count
//
Prcb->InterruptCount++;
//
// Check if we came from user mode
//
if (0) //(TrapFrame->PreviousMode != KernelMode)
{
//
// Increase process user time
//
InterlockedIncrement((PLONG)&Process->UserTime);
Prcb->UserTime++;
Thread->UserTime++;
}
else
{
//
// See if we were in an ISR
//
if (TrapFrame->OldIrql > DISPATCH_LEVEL)
{
//
// Handle that
//
Prcb->InterruptTime++;
}
else if ((TrapFrame->OldIrql < DISPATCH_LEVEL) ||
!(Prcb->DpcRoutineActive))
{
//
// Handle being in kernel mode
//
Thread->KernelTime++;
InterlockedIncrement((PLONG)&Process->KernelTime);
}
else
{
//
// Handle being in a DPC
//
Prcb->DpcTime++;
//
// FIXME: Handle DPC checks
//
}
}
//
// Update DPC rates
//
Prcb->DpcRequestRate = ((Prcb->DpcData[0].DpcCount - Prcb->DpcLastCount) +
Prcb->DpcRequestRate) >> 1;
Prcb->DpcLastCount = Prcb->DpcData[0].DpcCount;
//
// Check if the queue is large enough
//
if ((Prcb->DpcData[0].DpcQueueDepth) && !(Prcb->DpcRoutineActive))
{
//
// Request a DPC
//
Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
//
// Fix the maximum queue depth
//
if ((Prcb->DpcRequestRate < KiIdealDpcRate) &&
(Prcb->MaximumDpcQueueDepth > 1))
{
//
// Make it smaller
//
Prcb->MaximumDpcQueueDepth--;
}
}
else
{
//
// Check if we've reached the adjustment limit
//
if (!(--Prcb->AdjustDpcThreshold))
{
//
// Reset it, and check the queue maximum
//
Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
if (KiMaximumDpcQueueDepth != Prcb->MaximumDpcQueueDepth)
{
//
// Increase it
//
Prcb->MaximumDpcQueueDepth++;
}
}
}
//
// Decrement the thread quantum
//
Thread->Quantum -= CLOCK_QUANTUM_DECREMENT;
//
// Check if the time expired
//
if ((Thread->Quantum <= 0) && (Thread != Prcb->IdleThread))
{
//
// Schedule a quantum end
//
Prcb->QuantumEnd = 1;
//HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
}
}
+11 -2
View File
@@ -310,6 +310,7 @@ KiInterruptHandler(IN PKTRAP_FRAME TrapFrame,
KIRQL OldIrql, Irql;
ULONG InterruptCause, InterruptMask;
PKPCR Pcr;
PKTRAP_FRAME OldTrapFrame;
//
// Increment interrupt count
@@ -339,12 +340,18 @@ KiInterruptHandler(IN PKTRAP_FRAME TrapFrame,
// Raise to the new IRQL
//
KfRaiseIrql(Irql);
//
// The clock ISR wants the trap frame as a parameter
//
OldTrapFrame = KeGetCurrentThread()->TrapFrame;
KeGetCurrentThread()->TrapFrame = TrapFrame;
//
// Check if this interrupt is at DISPATCH or higher
//
if (Irql > DISPATCH_LEVEL)
{
{
//
// FIXME: Switch to interrupt stack
//
@@ -358,11 +365,13 @@ KiInterruptHandler(IN PKTRAP_FRAME TrapFrame,
//DPRINT1("[DPC/APC]\n");
HalClearSoftwareInterrupt(Irql);
}
//
// Call the registered interrupt routine
//
Pcr->InterruptRoutine[Irql]();
ASSERT(KeGetCurrentThread()->TrapFrame == TrapFrame);
KeGetCurrentThread()->TrapFrame = OldTrapFrame;
// DPRINT1("[ISR RETURN]\n");
//