Author: ion
Date: Tue Jan 16 23:49:40 2007
New Revision: 25490
URL:
http://svn.reactos.org/svn/reactos?rev=25490&view=rev
Log:
[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...
Modified:
trunk/reactos/ntoskrnl/include/internal/ke_x.h
trunk/reactos/ntoskrnl/ke/dpc.c
trunk/reactos/ntoskrnl/ke/event.c
trunk/reactos/ntoskrnl/ke/thrdobj.c
trunk/reactos/ntoskrnl/ke/thrdschd.c
Modified: trunk/reactos/ntoskrnl/include/internal/ke_x.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ke_x.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/ke_x.h Tue Jan 16 23:49:40 2007
@@ -1304,7 +1304,8 @@
//
SCHAR
FORCEINLINE
-KiComputeNewPriority(IN PKTHREAD Thread)
+KiComputeNewPriority(IN PKTHREAD Thread,
+ IN SCHAR Adjustment)
{
SCHAR Priority;
@@ -1319,7 +1320,7 @@
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;
Modified: trunk/reactos/ntoskrnl/ke/dpc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/dpc.c?rev=2549…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/dpc.c (original)
+++ trunk/reactos/ntoskrnl/ke/dpc.c Tue Jan 16 23:49:40 2007
@@ -39,7 +39,6 @@
NTAPI
KiQuantumEnd(VOID)
{
- KPRIORITY Priority;
PKPRCB Prcb = KeGetCurrentPrcb();
PKTHREAD NextThread, Thread = Prcb->CurrentThread;
@@ -66,7 +65,7 @@
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 @@
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 @@
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)
Modified: trunk/reactos/ntoskrnl/ke/event.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/event.c?rev=25…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/event.c (original)
+++ trunk/reactos/ntoskrnl/ke/event.c Tue Jan 16 23:49:40 2007
@@ -237,7 +237,7 @@
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 @@
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);
Modified: trunk/reactos/ntoskrnl/ke/thrdobj.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/thrdobj.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/thrdobj.c (original)
+++ trunk/reactos/ntoskrnl/ke/thrdobj.c Tue Jan 16 23:49:40 2007
@@ -134,7 +134,8 @@
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 @@
{
/* 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 @@
/* 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 @@
/* 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 @@
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 @@
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 @@
/* 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 @@
/* 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 @@
/* Lock the Dispatcher Database and the APC Queue */
KiAcquireApcLock(Thread, &ApcLock);
- KiAcquireDispatcherLockAtDpcLevel();
/* Save the old State */
OldState = Thread->Alerted[AlertMode];
@@ -675,9 +671,7 @@
}
/* Release Locks and return the Old State */
- KiReleaseDispatcherLockFromDpcLevel();
- KiReleaseApcLockFromDpcLevel(&ApcLock);
- KiExitDispatcher(ApcLock.OldIrql);
+ KiReleaseApcLock(&ApcLock);
return OldState;
}
@@ -718,7 +712,8 @@
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 @@
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 @@
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 @@
/* 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 @@
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 @@
/* 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)
- {
- /* Reset the Quantum and Decrements */
+ if (Priority != Thread->Priority)
+ {
+ /* 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 @@
ASSERT(Process->StackCount != 0);
ASSERT(Process->State == ProcessInMemory);
Process->StackCount--;
- if (!Process->StackCount)
+ if (!(Process->StackCount) &&
!(IsListEmpty(&Process->ThreadListHead)))
{
/* FIXME: Swap stacks */
}
Modified: trunk/reactos/ntoskrnl/ke/thrdschd.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/thrdschd.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/thrdschd.c (original)
+++ trunk/reactos/ntoskrnl/ke/thrdschd.c Tue Jan 16 23:49:40 2007
@@ -252,11 +252,15 @@
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 @@
Thread->Quantum = Thread->QuantumReset;
/* Calculate new Priority */
- Priority = Thread->Priority - (Thread->PriorityDecrement + 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)
+ Thread->Priority = KiComputeNewPriority(Thread, 1);
+
+#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 */
- }
- }
- }
-
- /* Nothing to do... */
- return;
+ /* This thread can be preempted again */
+ Thread->Preempted = FALSE;
+ }
+#else
+ /* We need to dispatch a new thread */
+ KiDispatchThread(Ready);
+#endif
+ }
+ }
+
+ /* 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 @@
return STATUS_SUCCESS;
}
+