mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
[22 bug fixes]:
- Make KiComputeNewPriority accept various priority adjuments instead of always assuming an increase of 1 priority level. - Fix ASSERT in KeSetEventBoostPriority: API is valid *only* for Synchronization events, not notification ones. - Use proper KiComputeNewPriority call in KeSetEventBoostPriority, since we're not adjusting by 1. - Make sure the FreezeCount is also 0 in KeAlertResumeThread, before signalling the suspend semaphore. - Simply alert-mode check in KeAlertThread. - Don't exit the critical region in KeFreezeAllThreads, it needs to be held. - Don't enter a critical region in KeThawAllThreads, it should already have been entered; release it after thawing is complete. - Also change the list loop in these functions to always start with the first thread. - Copy over boost-disable flag in KeStartThread. - Don't acquire the dispatcher lock in KeTestAlertThread. - Set the KernelStackResident flag to TRUE in KeInitThread. - Fix KeSetIdealProcessorThread to check the CPU is valid on the system, not valid across all valid CPU numbers. Also fix it to compare affinity, not processor. - Fix KeSetBasePriorityThread to properly call KiComputeNewPriority with an adjustment of 0, and then properly manually adjust with the delta between the new base priority and the old base priority. - Also normalize the new priority if it's too low. - Always set the priority decrement back to 0 when KeSetPriorityThread is called. - Normalize the priority in KeSetPriorityThread if it falls too low. - Fix process stack count check in KeTerminateThread. - Acquire thread and PRCB lock in KiAdjustQuantumThread. - Use KiComputeNewPriority in KiAdjustQuantumThread. - Dispatch a new thread in KiAdjustQuantumThread to take into account the new scheduler settings. - Thread priorities should make more sense now... svn path=/trunk/; revision=25490
This commit is contained in:
parent
dde6333e88
commit
c15d054bad
5 changed files with 70 additions and 61 deletions
|
@ -1304,7 +1304,8 @@ KiSelectReadyThread(IN KPRIORITY Priority,
|
|||
//
|
||||
SCHAR
|
||||
FORCEINLINE
|
||||
KiComputeNewPriority(IN PKTHREAD Thread)
|
||||
KiComputeNewPriority(IN PKTHREAD Thread,
|
||||
IN SCHAR Adjustment)
|
||||
{
|
||||
SCHAR Priority;
|
||||
|
||||
|
@ -1319,7 +1320,7 @@ KiComputeNewPriority(IN PKTHREAD Thread)
|
|||
if (Priority < LOW_REALTIME_PRIORITY)
|
||||
{
|
||||
/* Decrease priority by the priority decrement */
|
||||
Priority -= (Thread->PriorityDecrement + 1);
|
||||
Priority -= (Thread->PriorityDecrement + Adjustment);
|
||||
|
||||
/* Don't go out of bounds */
|
||||
if (Priority < Thread->BasePriority) Priority = Thread->BasePriority;
|
||||
|
|
|
@ -39,7 +39,6 @@ VOID
|
|||
NTAPI
|
||||
KiQuantumEnd(VOID)
|
||||
{
|
||||
KPRIORITY Priority;
|
||||
PKPRCB Prcb = KeGetCurrentPrcb();
|
||||
PKTHREAD NextThread, Thread = Prcb->CurrentThread;
|
||||
|
||||
|
@ -66,7 +65,7 @@ KiQuantumEnd(VOID)
|
|||
Thread->Quantum = Thread->QuantumReset;
|
||||
|
||||
/* Calculate new priority */
|
||||
Priority = Thread->Priority = KiComputeNewPriority(Thread);
|
||||
Thread->Priority = KiComputeNewPriority(Thread, 1);
|
||||
|
||||
/* Check if a new thread is scheduled */
|
||||
if (!Prcb->NextThread)
|
||||
|
@ -337,7 +336,7 @@ KeInsertQueueDpc(IN PKDPC Dpc,
|
|||
if (&Prcb->DpcData[DPC_THREADED].DpcListHead == &DpcData->DpcListHead)
|
||||
{
|
||||
/* Make sure a threaded DPC isn't already active */
|
||||
if (!(Prcb->DpcThreadActive) && (!Prcb->DpcThreadRequested))
|
||||
if (!(Prcb->DpcThreadActive) && !(Prcb->DpcThreadRequested))
|
||||
{
|
||||
/* FIXME: Setup Threaded DPC */
|
||||
ASSERT(FALSE);
|
||||
|
@ -346,7 +345,7 @@ KeInsertQueueDpc(IN PKDPC Dpc,
|
|||
else
|
||||
{
|
||||
/* Make sure a DPC isn't executing already */
|
||||
if ((!Prcb->DpcRoutineActive) && (!Prcb->DpcInterruptRequested))
|
||||
if (!(Prcb->DpcRoutineActive) && !(Prcb->DpcInterruptRequested))
|
||||
{
|
||||
/* Check if this is the same CPU */
|
||||
if (Prcb != CurrentPrcb)
|
||||
|
|
|
@ -237,7 +237,7 @@ KeSetEventBoostPriority(IN PKEVENT Event,
|
|||
KIRQL OldIrql;
|
||||
PKWAIT_BLOCK WaitBlock;
|
||||
PKTHREAD Thread = KeGetCurrentThread(), WaitThread;
|
||||
ASSERT_EVENT(Event);
|
||||
ASSERT(Event->Header.Type == SynchronizationEvent);
|
||||
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
|
||||
|
||||
/* Acquire Dispatcher Database Lock */
|
||||
|
@ -275,14 +275,14 @@ KeSetEventBoostPriority(IN PKEVENT Event,
|
|||
if (WaitingThread) *WaitingThread = WaitThread;
|
||||
|
||||
/* Calculate new priority */
|
||||
Thread->Priority = KiComputeNewPriority(Thread);
|
||||
Thread->Priority = KiComputeNewPriority(Thread, 0);
|
||||
|
||||
/* Unlink the waiting thread */
|
||||
KiUnlinkThread(WaitThread, STATUS_WAIT_0);
|
||||
KiUnlinkThread(WaitThread, STATUS_SUCCESS);
|
||||
|
||||
/* Request priority boosting */
|
||||
WaitThread->AdjustIncrement = Thread->Priority;
|
||||
WaitThread->AdjustReason = 2;
|
||||
WaitThread->AdjustReason = AdjustBoost;
|
||||
|
||||
/* Ready the thread */
|
||||
KiReadyThread(WaitThread);
|
||||
|
|
|
@ -134,7 +134,8 @@ KeAlertResumeThread(IN PKTHREAD Thread)
|
|||
if (PreviousCount)
|
||||
{
|
||||
/* Decrease count. If we are now zero, unwait it completely */
|
||||
if (--Thread->SuspendCount)
|
||||
Thread->SuspendCount--;
|
||||
if (!(Thread->SuspendCount) && !(Thread->FreezeCount))
|
||||
{
|
||||
/* Signal and satisfy */
|
||||
Thread->SuspendSemaphore.Header.SignalState++;
|
||||
|
@ -171,8 +172,8 @@ KeAlertThread(IN PKTHREAD Thread,
|
|||
{
|
||||
/* Check if the thread is alertable, and blocked in the given mode */
|
||||
if ((Thread->State == Waiting) &&
|
||||
((AlertMode == KernelMode) || (Thread->WaitMode == AlertMode)) &&
|
||||
(Thread->Alertable))
|
||||
(Thread->Alertable) &&
|
||||
(AlertMode <= Thread->WaitMode))
|
||||
{
|
||||
/* Abort the wait to alert the thread */
|
||||
KiUnwaitThread(Thread, STATUS_ALERTED, THREAD_ALERT_INCREMENT);
|
||||
|
@ -260,7 +261,7 @@ KeFreezeAllThreads(VOID)
|
|||
/* Loop the Process's Threads */
|
||||
ListHead = &Process->ThreadListHead;
|
||||
NextEntry = ListHead->Flink;
|
||||
while (NextEntry != ListHead)
|
||||
do
|
||||
{
|
||||
/* Get the current thread */
|
||||
Current = CONTAINING_RECORD(NextEntry, KTHREAD, ThreadListEntry);
|
||||
|
@ -307,14 +308,11 @@ KeFreezeAllThreads(VOID)
|
|||
|
||||
/* Move to the next thread */
|
||||
NextEntry = NextEntry->Flink;
|
||||
}
|
||||
} while (NextEntry != ListHead);
|
||||
|
||||
/* Release the process lock and exit the dispatcher */
|
||||
KiReleaseProcessLock(&LockHandle);
|
||||
KiExitDispatcher(LockHandle.OldIrql);
|
||||
|
||||
/* Leave the critical region */
|
||||
KeLeaveCriticalRegion();
|
||||
}
|
||||
|
||||
ULONG
|
||||
|
@ -367,6 +365,7 @@ KeRundownThread(VOID)
|
|||
PKTHREAD Thread = KeGetCurrentThread();
|
||||
PLIST_ENTRY NextEntry, ListHead;
|
||||
PKMUTANT Mutant;
|
||||
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
|
||||
|
||||
/* Optimized path if nothing is on the list at the moment */
|
||||
if (IsListEmpty(&Thread->MutantListHead)) return;
|
||||
|
@ -430,6 +429,7 @@ KeStartThread(IN OUT PKTHREAD Thread)
|
|||
PKPROCESS Process = Thread->ApcState.Process;
|
||||
|
||||
/* Setup static fields from parent */
|
||||
Thread->DisableBoost = Process->DisableBoost;
|
||||
Thread->Iopl = Process->Iopl;
|
||||
Thread->Quantum = Process->QuantumReset;
|
||||
Thread->QuantumReset = Process->QuantumReset;
|
||||
|
@ -593,13 +593,10 @@ KeThawAllThreads(VOID)
|
|||
/* Lock the process */
|
||||
KiAcquireProcessLock(Process, &LockHandle);
|
||||
|
||||
/* Enter a critical region */
|
||||
KeEnterCriticalRegion();
|
||||
|
||||
/* Loop the Process's Threads */
|
||||
ListHead = &Process->ThreadListHead;
|
||||
NextEntry = ListHead->Flink;
|
||||
while (NextEntry != ListHead)
|
||||
do
|
||||
{
|
||||
/* Get the current thread */
|
||||
Current = CONTAINING_RECORD(NextEntry, KTHREAD, ThreadListEntry);
|
||||
|
@ -634,7 +631,7 @@ KeThawAllThreads(VOID)
|
|||
|
||||
/* Go to the next one */
|
||||
NextEntry = NextEntry->Flink;
|
||||
}
|
||||
} while (NextEntry != ListHead);
|
||||
|
||||
/* Release the process lock and exit the dispatcher */
|
||||
KiReleaseProcessLock(&LockHandle);
|
||||
|
@ -656,7 +653,6 @@ KeTestAlertThread(IN KPROCESSOR_MODE AlertMode)
|
|||
|
||||
/* Lock the Dispatcher Database and the APC Queue */
|
||||
KiAcquireApcLock(Thread, &ApcLock);
|
||||
KiAcquireDispatcherLockAtDpcLevel();
|
||||
|
||||
/* Save the old State */
|
||||
OldState = Thread->Alerted[AlertMode];
|
||||
|
@ -675,9 +671,7 @@ KeTestAlertThread(IN KPROCESSOR_MODE AlertMode)
|
|||
}
|
||||
|
||||
/* Release Locks and return the Old State */
|
||||
KiReleaseDispatcherLockFromDpcLevel();
|
||||
KiReleaseApcLockFromDpcLevel(&ApcLock);
|
||||
KiExitDispatcher(ApcLock.OldIrql);
|
||||
KiReleaseApcLock(&ApcLock);
|
||||
return OldState;
|
||||
}
|
||||
|
||||
|
@ -718,7 +712,8 @@ KeInitThread(IN OUT PKTHREAD Thread,
|
|||
Thread->EnableStackSwap = FALSE;//TRUE;
|
||||
Thread->IdealProcessor = 1;
|
||||
Thread->SwapBusy = FALSE;
|
||||
Thread->AdjustReason = 0;
|
||||
Thread->KernelStackResident = TRUE;
|
||||
Thread->AdjustReason = AdjustNone;
|
||||
|
||||
/* Initialize the lock */
|
||||
KeInitializeSpinLock(&Thread->ThreadLock);
|
||||
|
@ -1020,10 +1015,10 @@ KeSetIdealProcessorThread(IN PKTHREAD Thread,
|
|||
OldIdealProcessor = Thread->UserIdealProcessor;
|
||||
|
||||
/* Make sure a valid CPU was given */
|
||||
if (Processor < MAXIMUM_PROCESSORS)
|
||||
if (Processor < KeNumberProcessors)
|
||||
{
|
||||
/* Check if the user ideal CPU is in the affinity */
|
||||
if (Thread->UserIdealProcessor & AFFINITY_MASK(Processor))
|
||||
if (Thread->Affinity & AFFINITY_MASK(Processor))
|
||||
{
|
||||
/* Set the ideal processor */
|
||||
Thread->IdealProcessor = Processor;
|
||||
|
@ -1197,7 +1192,8 @@ KeSetBasePriorityThread(IN PKTHREAD Thread,
|
|||
else
|
||||
{
|
||||
/* Otherwise, calculate the new priority */
|
||||
Priority = KiComputeNewPriority(Thread);
|
||||
Priority = KiComputeNewPriority(Thread, 0);
|
||||
Priority += (BasePriority - OldBasePriority);
|
||||
|
||||
/* Check if it entered the real-time range */
|
||||
if (Priority >= LOW_REALTIME_PRIORITY)
|
||||
|
@ -1205,6 +1201,11 @@ KeSetBasePriorityThread(IN PKTHREAD Thread,
|
|||
/* Normalize it down to the highest dynamic priority */
|
||||
Priority = LOW_REALTIME_PRIORITY - 1;
|
||||
}
|
||||
else if (Priority <= LOW_PRIORITY)
|
||||
{
|
||||
/* It went too low, normalize it */
|
||||
Priority = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1291,6 +1292,7 @@ KeSetPriorityThread(IN PKTHREAD Thread,
|
|||
ASSERT_THREAD(Thread);
|
||||
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
|
||||
ASSERT((Priority <= HIGH_PRIORITY) && (Priority >= LOW_PRIORITY));
|
||||
ASSERT(KeIsExecutingDpc() == FALSE);
|
||||
|
||||
/* Lock the Dispatcher Database */
|
||||
OldIrql = KiAcquireDispatcherLock();
|
||||
|
@ -1298,15 +1300,18 @@ KeSetPriorityThread(IN PKTHREAD Thread,
|
|||
/* Lock the thread */
|
||||
KiAcquireThreadLock(Thread);
|
||||
|
||||
/* Save the old Priority */
|
||||
/* Save the old Priority and reset decrement */
|
||||
OldPriority = Thread->Priority;
|
||||
Thread->PriorityDecrement = 0;
|
||||
|
||||
/* Make sure that an actual change is being done */
|
||||
if (OldPriority != Priority)
|
||||
if (Priority != Thread->Priority)
|
||||
{
|
||||
/* Reset the Quantum and Decrements */
|
||||
/* Reset the quantum */
|
||||
Thread->Quantum = Thread->QuantumReset;
|
||||
Thread->PriorityDecrement = 0;
|
||||
|
||||
/* Check if priority is being set too low and normalize if so */
|
||||
if ((Thread->BasePriority != 0) && !(Priority)) Priority = 1;
|
||||
|
||||
/* Set the new Priority */
|
||||
KiSetPriorityThread(Thread, Priority, &Released);
|
||||
|
@ -1417,7 +1422,7 @@ KeTerminateThread(IN KPRIORITY Increment)
|
|||
ASSERT(Process->StackCount != 0);
|
||||
ASSERT(Process->State == ProcessInMemory);
|
||||
Process->StackCount--;
|
||||
if (!Process->StackCount)
|
||||
if (!(Process->StackCount) && !(IsListEmpty(&Process->ThreadListHead)))
|
||||
{
|
||||
/* FIXME: Swap stacks */
|
||||
}
|
||||
|
|
|
@ -252,11 +252,15 @@ VOID
|
|||
STDCALL
|
||||
KiAdjustQuantumThread(IN PKTHREAD Thread)
|
||||
{
|
||||
KPRIORITY Priority;
|
||||
PKPRCB Prcb = KeGetCurrentPrcb();
|
||||
|
||||
/* Acquire thread and PRCB lock */
|
||||
KiAcquireThreadLock(Thread);
|
||||
KiAcquirePrcbLock(Prcb);
|
||||
|
||||
/* Don't adjust for RT threads */
|
||||
if ((Thread->Priority < LOW_REALTIME_PRIORITY) &&
|
||||
Thread->BasePriority < LOW_REALTIME_PRIORITY - 2)
|
||||
(Thread->BasePriority < (LOW_REALTIME_PRIORITY - 2)))
|
||||
{
|
||||
/* Decrease Quantum by one and see if we've ran out */
|
||||
if (--Thread->Quantum <= 0)
|
||||
|
@ -265,46 +269,45 @@ KiAdjustQuantumThread(IN PKTHREAD Thread)
|
|||
Thread->Quantum = Thread->QuantumReset;
|
||||
|
||||
/* Calculate new Priority */
|
||||
Priority = Thread->Priority - (Thread->PriorityDecrement + 1);
|
||||
Thread->Priority = KiComputeNewPriority(Thread, 1);
|
||||
|
||||
/* Normalize it if we've gone too low */
|
||||
if (Priority < Thread->BasePriority) Priority = Thread->BasePriority;
|
||||
|
||||
/* Reset the priority decrement, we've done it */
|
||||
Thread->PriorityDecrement = 0;
|
||||
|
||||
/* Set the new priority, if needed */
|
||||
if (Priority != Thread->Priority)
|
||||
#ifdef NEW_SCHEDULER
|
||||
/* Check if there's no next thread scheduled */
|
||||
if (!Prcb->NextThread)
|
||||
{
|
||||
/*
|
||||
* FIXME: This should be a call to KiSetPriorityThread but
|
||||
* due to the current ""scheduler"" in ROS, it can't be done
|
||||
* cleanly since it actualyl dispatches threads instead.
|
||||
*/
|
||||
Thread->Priority = (SCHAR)Priority;
|
||||
/* Select a new thread and set it on standby */
|
||||
NextThread = KiSelectNextThread(Prcb);
|
||||
NextThread->State = Standby;
|
||||
Prcb->NextThread = NextThread;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME: Priority hasn't changed, find a new thread */
|
||||
/* This thread can be preempted again */
|
||||
Thread->Preempted = FALSE;
|
||||
}
|
||||
#else
|
||||
/* We need to dispatch a new thread */
|
||||
KiDispatchThread(Ready);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Nothing to do... */
|
||||
return;
|
||||
/* Release locks */
|
||||
KiReleasePrcbLock(Prcb);
|
||||
KiReleaseThreadLock(Thread);
|
||||
}
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
KiSetPriorityThread(PKTHREAD Thread,
|
||||
KPRIORITY Priority,
|
||||
PBOOLEAN Released)
|
||||
KiSetPriorityThread(IN PKTHREAD Thread,
|
||||
IN KPRIORITY Priority,
|
||||
OUT PBOOLEAN Released)
|
||||
{
|
||||
KPRIORITY OldPriority = Thread->Priority;
|
||||
ULONG Mask;
|
||||
int i;
|
||||
ULONG i;
|
||||
PKPCR Pcr;
|
||||
DPRINT("Changing prio to : %lx\n", Priority);
|
||||
ASSERT((Priority >= 0) && (Priority <= HIGH_PRIORITY));
|
||||
|
||||
/* Check if priority changed */
|
||||
if (OldPriority != Priority)
|
||||
|
@ -459,3 +462,4 @@ NtYieldExecution(VOID)
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue