mirror of
https://github.com/reactos/reactos.git
synced 2025-08-02 06:15:52 +00:00
- Fix a critical bug in KiComputeNewPriority.
- Fix a bug in KiSetPriorityThread which wasn't setting *released = FALSE, which left the var uninitailized and usually = TRUE on the stack. - Half-copy KiQuantumEnd from my new scheduler code. Main difference is usage of newly created locks, support for quantum-disable and RT threads, and usage of KiComputeNewPriority. svn path=/trunk/; revision=24060
This commit is contained in:
parent
8028be67cb
commit
6c853c9c32
3 changed files with 50 additions and 53 deletions
|
@ -827,8 +827,8 @@ KiComputeNewPriority(IN PKTHREAD Thread)
|
|||
Priority = Thread->Priority;
|
||||
if (Priority < LOW_REALTIME_PRIORITY)
|
||||
{
|
||||
/* Set the New Priority and add the Priority Decrement */
|
||||
Priority += (Priority - Thread->PriorityDecrement - 1);
|
||||
/* Decrease priority by the priority decrement */
|
||||
Priority -= (Thread->PriorityDecrement + 1);
|
||||
|
||||
/* Don't go out of bounds */
|
||||
if (Priority < Thread->BasePriority) Priority = Thread->BasePriority;
|
||||
|
|
|
@ -26,16 +26,21 @@ KMUTEX KiGenericCallDpcMutex;
|
|||
|
||||
/* PRIVATE FUNCTIONS *********************************************************/
|
||||
|
||||
//
|
||||
// This routine executes at the end of a thread's quantum.
|
||||
// If the thread's quantum has expired, then a new thread is attempted
|
||||
// to be scheduled.
|
||||
//
|
||||
// If no candidate thread has been found, the routine will return, otherwise
|
||||
// it will swap contexts to the next scheduled thread.
|
||||
//
|
||||
VOID
|
||||
NTAPI
|
||||
KiQuantumEnd(VOID)
|
||||
{
|
||||
KPRIORITY Priority;
|
||||
PKPRCB Prcb = KeGetCurrentPrcb();
|
||||
PKTHREAD CurrentThread = KeGetCurrentThread();
|
||||
KIRQL OldIrql;
|
||||
PKPROCESS Process;
|
||||
KPRIORITY OldPriority;
|
||||
KPRIORITY NewPriority;
|
||||
PKTHREAD NextThread, Thread = Prcb->CurrentThread;
|
||||
|
||||
/* Check if a DPC Event was requested to be signaled */
|
||||
if (InterlockedExchange(&Prcb->DpcSetEventRequest, 0))
|
||||
|
@ -44,68 +49,59 @@ KiQuantumEnd(VOID)
|
|||
KeSetEvent(&Prcb->DpcEvent, 0, 0);
|
||||
}
|
||||
|
||||
/* Lock dispatcher */
|
||||
OldIrql = KeRaiseIrqlToSynchLevel();
|
||||
ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL);
|
||||
|
||||
/* Get the Thread's Process */
|
||||
Process = CurrentThread->ApcState.Process;
|
||||
/* Raise to synchronization level and lock the PRCB and thread */
|
||||
KeRaiseIrqlToSynchLevel();
|
||||
KiAcquireThreadLock(Thread);
|
||||
KiAcquirePrcbLock(Prcb);
|
||||
|
||||
/* Check if Quantum expired */
|
||||
if (CurrentThread->Quantum <= 0)
|
||||
if (Thread->Quantum <= 0)
|
||||
{
|
||||
/* Reset the new Quantum */
|
||||
CurrentThread->Quantum = CurrentThread->QuantumReset;
|
||||
|
||||
/* Calculate new priority */
|
||||
OldPriority = CurrentThread->Priority;
|
||||
if (OldPriority < LOW_REALTIME_PRIORITY)
|
||||
/* Make sure that we're not real-time or without a quantum */
|
||||
if ((Thread->Priority < LOW_REALTIME_PRIORITY) &&
|
||||
!(Thread->ApcState.Process->DisableQuantum))
|
||||
{
|
||||
/* Set the New Priority and add the Priority Decrement */
|
||||
NewPriority = OldPriority - CurrentThread->PriorityDecrement - 1;
|
||||
/* Reset the new Quantum */
|
||||
Thread->Quantum = Thread->QuantumReset;
|
||||
|
||||
/* Don't go out of bounds */
|
||||
if (NewPriority < CurrentThread->BasePriority)
|
||||
/* Calculate new priority */
|
||||
Priority = Thread->Priority = KiComputeNewPriority(Thread);
|
||||
|
||||
/* Check if a new thread is scheduled */
|
||||
if (!Prcb->NextThread)
|
||||
{
|
||||
NewPriority = CurrentThread->BasePriority;
|
||||
}
|
||||
|
||||
/* Reset the priority decrement */
|
||||
CurrentThread->PriorityDecrement = 0;
|
||||
|
||||
/* Set a new priority if needed */
|
||||
if (OldPriority != NewPriority)
|
||||
{
|
||||
/* Set new Priority */
|
||||
BOOLEAN Dummy; /* <- This is a hack anyways... */
|
||||
KiSetPriorityThread(CurrentThread, NewPriority, &Dummy);
|
||||
/* FIXME: TODO. Add code from new scheduler */
|
||||
NextThread = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Queue new thread if none is already */
|
||||
if (!Prcb->NextThread)
|
||||
{
|
||||
/* FIXME: Schedule a New Thread, when ROS will have NT Scheduler */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Make the current thread non-premeptive if a new thread is queued */
|
||||
CurrentThread->Preempted = FALSE;
|
||||
}
|
||||
/* Otherwise, make sure that this thread doesn't get preempted */
|
||||
Thread->Preempted = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set the Quantum back to Maximum */
|
||||
//if (CurrentThread->DisableQuantum) {
|
||||
// CurrentThread->Quantum = MAX_QUANTUM;
|
||||
//}
|
||||
/* Otherwise, set maximum quantum */
|
||||
Thread->Quantum = MAX_QUANTUM;
|
||||
}
|
||||
}
|
||||
|
||||
/* Dispatch the Thread */
|
||||
KeLowerIrql(DISPATCH_LEVEL);
|
||||
KiDispatchThread(Ready);
|
||||
/* Release the thread lock */
|
||||
KiReleaseThreadLock(Thread);
|
||||
|
||||
/* Check if there's no thread scheduled */
|
||||
if (!Prcb->NextThread)
|
||||
{
|
||||
/* Just leave now */
|
||||
KiReleasePrcbLock(Prcb);
|
||||
KeLowerIrql(DISPATCH_LEVEL);
|
||||
KiDispatchThread(Ready); // FIXME: ROS
|
||||
return;
|
||||
}
|
||||
|
||||
/* This shouldn't happen on ROS yet */
|
||||
DPRINT1("The impossible happened - Tell Alex\n");
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
|
||||
VOID
|
||||
|
|
|
@ -339,6 +339,7 @@ KiSetPriorityThread(PKTHREAD Thread,
|
|||
}
|
||||
|
||||
/* Return to caller */
|
||||
*Released = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue