[ros-diffs] [ion] 25490: [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...

ion at svn.reactos.org ion at svn.reactos.org
Tue Jan 16 21:49:40 CET 2007


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/ke_x.h?rev=25490&r1=25489&r2=25490&view=diff
==============================================================================
--- 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=25490&r1=25489&r2=25490&view=diff
==============================================================================
--- 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=25490&r1=25489&r2=25490&view=diff
==============================================================================
--- 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=25490&r1=25489&r2=25490&view=diff
==============================================================================
--- 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=25490&r1=25489&r2=25490&view=diff
==============================================================================
--- 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;
 }
 
+




More information about the Ros-diffs mailing list