mirror of
https://github.com/reactos/reactos.git
synced 2025-02-28 19:32:59 +00:00
WIP [NTOS:KE/x64] Handle NewThread == OldThread in KiIdleLoop
This commit is contained in:
parent
e118c6a769
commit
5faf6ed339
3 changed files with 47 additions and 9 deletions
|
@ -158,14 +158,22 @@ KiIdleLoop(VOID)
|
|||
/* The thread is now running */
|
||||
NewThread->State = Running;
|
||||
|
||||
/* Clear idle summary bit */
|
||||
InterlockedBitTestAndResetAffinity(&KiIdleSummary, Prcb->Number);
|
||||
/* Check if we're actually running a different thread */
|
||||
if (NewThread != OldThread)
|
||||
{
|
||||
/* Clear idle summary bit */
|
||||
InterlockedBitTestAndResetAffinity(&KiIdleSummary, Prcb->Number);
|
||||
|
||||
/* Switch away from the idle thread */
|
||||
KiSwapContext(APC_LEVEL, OldThread);
|
||||
/* Switch away from the idle thread */
|
||||
KiSwapContext(APC_LEVEL, OldThread);
|
||||
|
||||
/* Set idle summary bit */
|
||||
InterlockedBitTestAndSetAffinity(&KiIdleSummary, Prcb->Number);
|
||||
/* Set idle summary bit */
|
||||
InterlockedBitTestAndSetAffinity(&KiIdleSummary, Prcb->Number);
|
||||
}
|
||||
else
|
||||
{
|
||||
NewThread->SwapBusy = FALSE;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/* Go back to DISPATCH_LEVEL */
|
||||
|
|
|
@ -66,6 +66,17 @@ KiDpcInterruptHandler(VOID)
|
|||
/* Acquire the PRCB lock */
|
||||
KiAcquirePrcbLock(Prcb);
|
||||
|
||||
if (Prcb->NextThread == Prcb->CurrentThread)
|
||||
{
|
||||
__debugbreak();
|
||||
/* This can happen, when the idle thread is running and a different
|
||||
processor reschedules the thread */
|
||||
ASSERT(Prcb->NextThread == Prcb->IdleThread);
|
||||
Prcb->NextThread = NULL;
|
||||
KiReleasePrcbLock(Prcb);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* Capture current thread data */
|
||||
OldThread = Prcb->CurrentThread;
|
||||
NewThread = Prcb->NextThread;
|
||||
|
@ -78,7 +89,7 @@ KiDpcInterruptHandler(VOID)
|
|||
NewThread->State = Running;
|
||||
OldThread->WaitReason = WrDispatchInt;
|
||||
|
||||
/* Make the old thread ready */
|
||||
/* Make the old thread ready (this releases the PRCB lock) */
|
||||
KxQueueReadyThread(OldThread, Prcb);
|
||||
|
||||
/* Swap to the new thread */
|
||||
|
|
|
@ -485,8 +485,27 @@ KiSwapThread(IN PKTHREAD CurrentThread,
|
|||
/* Save the wait IRQL */
|
||||
WaitIrql = CurrentThread->WaitIrql;
|
||||
|
||||
/* Swap contexts */
|
||||
ApcState = KiSwapContext(WaitIrql, CurrentThread);
|
||||
#ifdef CONFIG_SMP
|
||||
/* On SMP builds it is possible that the new thread is the old thread. */
|
||||
if (NextThread == CurrentThread)
|
||||
{
|
||||
/* Unset SwapBusy */
|
||||
CurrentThread->SwapBusy = FALSE;
|
||||
|
||||
/* Check for pending APCs */
|
||||
if ((NextThread->ApcState.KernelApcPending) &&
|
||||
(NextThread->SpecialApcDisable == FALSE) &&
|
||||
(WaitIrql == PASSIVE_LEVEL))
|
||||
{
|
||||
ApcState = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* Swap contexts */
|
||||
ApcState = KiSwapContext(WaitIrql, CurrentThread);
|
||||
}
|
||||
|
||||
/* Get the wait status */
|
||||
WaitStatus = CurrentThread->WaitStatus;
|
||||
|
|
Loading…
Reference in a new issue