windows-nt/Source/XPSP1/NT/base/ntos/ke/yield.c
2020-09-26 16:20:57 +08:00

119 lines
2.4 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
yield.c
Abstract:
This module implements the function to yield execution for one quantum
to any other runnable thread.
Author:
David N. Cutler (davec) 15-Mar-1996
Environment:
Kernel mode only.
Revision History:
--*/
#include "ki.h"
NTSTATUS
NtYieldExecution (
VOID
)
/*++
Routine Description:
This function yields execution to any ready thread for up to one
quantum.
Arguments:
None.
Return Value:
None.
--*/
{
KIRQL OldIrql;
PRKPRCB Prcb;
KPRIORITY Priority;
NTSTATUS Status;
PRKTHREAD Thread;
//
// If any other threads are ready, then attempt to yield execution.
//
Status = STATUS_NO_YIELD_PERFORMED;
if (KiReadySummary != 0) {
//
// If a thread has not already been selected for execution, then
// attempt to select another thread for execution.
//
Thread = KeGetCurrentThread();
KiLockDispatcherDatabase(&Thread->WaitIrql);
Prcb = KeGetCurrentPrcb();
if (Prcb->NextThread == NULL) {
Prcb->NextThread = KiFindReadyThread(Thread->NextProcessor, 1);
}
//
// If a new thread has been selected for execution, then switch
// immediately to the selected thread.
//
if (Prcb->NextThread != NULL) {
//
// Give the current thread a new quantum, simulate a quantum
// end, insert the current thread in the appropriate ready list,
// and switch context to selected thread.
//
Thread->Quantum = Thread->ApcState.Process->ThreadQuantum;
Thread->State = Ready;
Priority = Thread->Priority;
if (Priority < LOW_REALTIME_PRIORITY) {
Priority = Priority - Thread->PriorityDecrement - 1;
if (Priority < Thread->BasePriority) {
Priority = Thread->BasePriority;
}
Thread->PriorityDecrement = 0;
}
Thread->Priority = (SCHAR)Priority;
InsertTailList(&KiDispatcherReadyListHead[Priority],
&Thread->WaitListEntry);
SetMember(Priority, KiReadySummary);
KiSwapThread();
Status = STATUS_SUCCESS;
} else {
KiUnlockDispatcherDatabase(Thread->WaitIrql);
}
}
return Status;
}