Implement thread preemption and context switching in dispatch interrupt handler

This commit is contained in:
2026-06-18 11:18:36 +02:00
parent 156ae3efab
commit bae43034a6
3 changed files with 96 additions and 2 deletions

View File

@@ -115,8 +115,64 @@ XTCDECL
VOID
KE::Dispatcher::HandleDispatchInterrupt(IN PKTRAP_FRAME TrapFrame)
{
PKTHREAD CurrentThread, NextThread;
PKPROCESSOR_CONTROL_BLOCK Prcb;
/* Receive the Processor Control Block*/
Prcb = KE::Processor::GetCurrentProcessorControlBlock();
/* Raise runlevel to DISPATCH level */
KE::RaiseRunLevel RunLevel(DISPATCH_LEVEL);
/* End the interrupt */
HL::Pic::SendEoi();
/* Check if there is pending deferred work */
if(Prcb->DeferredReadyListHead.Next ||
Prcb->DpcData[0].DpcQueueDepth ||
Prcb->TimerRequest)
{
UNIMPLEMENTED;
}
/* Re-enable hardware interrupts */
AR::CpuFunctions::SetInterruptFlag();
/* Check if the current thread has exhausted its execution quantum */
if((Prcb->CurrentThread->Quantum <= 0) && (Prcb->CurrentThread != Prcb->IdleThread))
{
/* Trigger the scheduler to recalculate thread parameters */
KE::Scheduler::ProcessQuantumEnd();
}
else if(Prcb->NextThread)
{
/* Start a guarded code block */
{
/* Lock the processor control block */
KE::SpinLockGuard ControlBlockGuard(&Prcb->PrcbLock);
/* Capture the outgoing (preempted) and incoming threads */
CurrentThread = Prcb->CurrentThread;
NextThread = Prcb->NextThread;
/* Acknowledge the pending thread and swap the pointers */
Prcb->NextThread = NULLPTR;
Prcb->CurrentThread = NextThread;
/* Update scheduling states */
NextThread->State = Running;
CurrentThread->WaitReason = WrDispatchInt;
/* Re-queue the preempted thread back into the local run queue or defer it */
KE::Scheduler::QueueReadyThread(CurrentThread, Prcb);
}
/* Perform the context switch */
SwitchContext(CurrentThread, APC_LEVEL);
}
/* Disable hardware interrupts before returning from the handler */
AR::CpuFunctions::ClearInterruptFlag();
}
/**
@@ -198,7 +254,7 @@ KE::Dispatcher::UpdateRunTime(IN PKTRAP_FRAME TrapFrame,
/* Reset the adjustment threshold counter */
ControlBlock->AdjustDpcThreshold = DPC_ADJUST_THRESHOLD;
/* Request a DISPATCH_LEVEL software interrupt to process the pending DPCs */
/* Request a DISPATCH level software interrupt to process the pending DPCs */
HL::Irq::SendSoftwareInterrupt(DISPATCH_LEVEL);
/* Evaluate if the DPC request rate is below the ideal threshold */
@@ -231,7 +287,7 @@ KE::Dispatcher::UpdateRunTime(IN PKTRAP_FRAME TrapFrame,
/* Check if the thread has exhausted its quantum, ignoring the idle thread */
if((Thread->Quantum <= 0) && (Thread != ControlBlock->IdleThread))
{
/* Request a DISPATCH_LEVEL software interrupt to preempt the thread */
/* Request a DISPATCH level software interrupt to preempt the thread */
HL::Irq::SendSoftwareInterrupt(DISPATCH_LEVEL);
}
}

View File

@@ -36,6 +36,20 @@ KE::Scheduler::InsertDeferredReadyList(IN PKTHREAD Thread)
RTL::LifoQueue::PushEntryList(&Prcb->DeferredReadyListHead, &Thread->SwapListEntry);
}
/**
* Handles the expiration of the currently executing thread's time quantum.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTAPI
VOID
KE::Scheduler::ProcessQuantumEnd(VOID)
{
UNIMPLEMENTED;
}
/**
* Transitions a thread to the ready state and queues it for execution within the dispatcher database.
*
@@ -74,6 +88,27 @@ KE::Scheduler::ProcessReadyThread(IN PKTHREAD Thread)
}
}
/**
* Enqueues a thread into the target processor's execution queue.
*
* @param Thread
* Supplies a pointer to the thread that is ready for execution.
*
* @param Prcb
* Supplies a pointer to the Processor Control Block of the target core.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTFASTCALL
VOID
KE::Scheduler::QueueReadyThread(IN PKTHREAD Thread,
IN PKPROCESSOR_CONTROL_BLOCK Prcb)
{
UNIMPLEMENTED;
}
/**
* Prepares a thread for execution by safely acquiring the dispatcher database lock.
*