Author: ion
Date: Thu Jan 18 00:53:45 2007
New Revision: 25502
URL: 
http://svn.reactos.org/svn/reactos?rev=25502&view=rev
Log:
- Remove hack from KiSetPriorityThread. Now it doesn't dispatch threads anymore, but
this cleans up the IRQL/Dispatcher hack (it will still insert the higher priority thread
in the right queue though, so there's not much visible change, just that priorities
suck a bit more -- but this is temporary).
- Guard some more code with #ifdef NEW_SCHEDULER.
- Fix bugs in KiDispatchInterrupt.
- Use PRCB fields instead of PriorityListHead/PriorityListMask to reduces number of code
changes between NEW_SCHEDULER and old.
- Fully implement KiDeferredReadyThread, but only for Uni-Processor systems. Supports
unwait boosts as well as lock boosts. Not yet used.
- Implement NEW_SCHEDULER version of KiSwapThread and NtYieldExecution.
Modified:
    trunk/reactos/ntoskrnl/include/internal/ke.h
    trunk/reactos/ntoskrnl/ke/dpc.c
    trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S
    trunk/reactos/ntoskrnl/ke/i386/trap.s
    trunk/reactos/ntoskrnl/ke/process.c
    trunk/reactos/ntoskrnl/ke/thrdobj.c
    trunk/reactos/ntoskrnl/ke/thrdschd.c
    trunk/reactos/ntoskrnl/ps/psmgr.c
Modified: trunk/reactos/ntoskrnl/include/internal/ke.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ke.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/ke.h Thu Jan 18 00:53:45 2007
@@ -449,11 +449,10 @@
 KeQueryBasePriorityThread(IN PKTHREAD Thread);
 VOID
-NTAPI
+FASTCALL
 KiSetPriorityThread(
     IN PKTHREAD Thread,
-    IN KPRIORITY Priority,
-    IN PBOOLEAN Released // hack
+    IN KPRIORITY Priority
 );
 BOOLEAN
Modified: trunk/reactos/ntoskrnl/ke/dpc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/dpc.c?rev=2550…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/dpc.c (original)
+++ trunk/reactos/ntoskrnl/ke/dpc.c Thu Jan 18 00:53:45 2007
@@ -76,8 +76,8 @@
                 if (NextThread)
                 {
                     /* Found one, set it on standby */
-                    NextThread->Standby;
-                    Prcb->NextThread = NewThread;
+                    NextThread->State = Standby;
+                    Prcb->NextThread = NextThread;
                 }
 #else
                 /* Just leave now */
Modified: trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/ctxswitch…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S (original)
+++ trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S Thu Jan 18 00:53:45 2007
@@ -643,8 +643,10 @@
     call @KfLowerIrql@4
 CheckSchedule:
+#ifndef NEW_SCHEDULER
     /* FIXME: ROS HACK */
     call _NtYieldExecution@0
+#endif
     /* Check if a next thread is queued */
     cmp dword ptr [ebx+KPCR_PRCB_NEXT_THREAD], 0
Modified: trunk/reactos/ntoskrnl/ke/i386/trap.s
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/trap.s?re…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/trap.s (original)
+++ trunk/reactos/ntoskrnl/ke/i386/trap.s Thu Jan 18 00:53:45 2007
@@ -2099,13 +2099,13 @@
     /* Check if we have a thread to swap to */
     cmp byte ptr [ebx+KPCR_PRCB_NEXT_THREAD], 0
-    jmp Return
+    je Return
     /* Make space on the stack to save registers */
     sub esp, 3 * 4
     mov [esp+8], esi
-    mov [esi+4], edi
-    mov [esi+0], ebp
+    mov [esp+4], edi
+    mov [esp+0], ebp
     /* Get the current thread */
     mov edi, [ebx+KPCR_CURRENT_THREAD]
Modified: trunk/reactos/ntoskrnl/ke/process.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/process.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/process.c (original)
+++ trunk/reactos/ntoskrnl/ke/process.c Thu Jan 18 00:53:45 2007
@@ -289,7 +289,6 @@
     PLIST_ENTRY NextEntry, ListHead;
     KPRIORITY NewPriority, OldPriority;
     PKTHREAD Thread;
-    BOOLEAN Released;
     ASSERT_PROCESS(Process);
     ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
@@ -368,7 +367,7 @@
                 /* Disable decrements and update priority */
                 Thread->PriorityDecrement = 0;
-                KiSetPriorityThread(Thread, NewPriority, &Released);
+                KiSetPriorityThread(Thread, NewPriority);
             }
             /* Release the thread lock */
@@ -430,7 +429,7 @@
                 /* Disable decrements and update priority */
                 Thread->PriorityDecrement = 0;
-                KiSetPriorityThread(Thread, NewPriority, &Released);
+                KiSetPriorityThread(Thread, NewPriority);
             }
             /* Release the thread lock */
@@ -442,7 +441,7 @@
     }
     /* Release Dispatcher Database */
-    if (!Released) KiReleaseDispatcherLockFromDpcLevel();
+    KiReleaseDispatcherLockFromDpcLevel();
     /* Release the process lock */
     KiReleaseProcessLockFromDpcLevel(&ProcessLock);
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 Thu Jan 18 00:53:45 2007
@@ -1126,7 +1126,6 @@
     KPRIORITY OldBasePriority, Priority, BasePriority;
     LONG OldIncrement;
     PKPROCESS Process;
-    BOOLEAN Released = FALSE;
     ASSERT_THREAD(Thread);
     ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
@@ -1220,25 +1219,14 @@
     {
         /* Reset the quantum and do the actual priority modification */
         Thread->Quantum = Thread->QuantumReset;
-        KiSetPriorityThread(Thread, Priority, &Released);
+        KiSetPriorityThread(Thread, Priority);
     }
     /* Release thread lock */
     KiReleaseThreadLock(Thread);
-    /* Check if lock was released */
-    if (!Released)
-    {
-        /* Release the dispatcher database */
-        KiReleaseDispatcherLock(OldIrql);
-    }
-    else
-    {
-        /* Lower IRQL only */
-        KeLowerIrql(OldIrql);
-    }
-
-    /* Return old increment */
+    /* Release the dispatcher database and return old increment */
+    KiReleaseDispatcherLock(OldIrql);
     return OldIncrement;
 }
@@ -1276,7 +1264,6 @@
 {
     KIRQL OldIrql;
     KPRIORITY OldPriority;
-    BOOLEAN Released = FALSE;
     ASSERT_THREAD(Thread);
     ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
     ASSERT((Priority <= HIGH_PRIORITY) && (Priority >= LOW_PRIORITY));
@@ -1302,23 +1289,14 @@
         if ((Thread->BasePriority != 0) && !(Priority)) Priority = 1;
         /* Set the new Priority */
-        KiSetPriorityThread(Thread, Priority, &Released);
+        KiSetPriorityThread(Thread, Priority);
     }
     /* Release thread lock */
     KiReleaseThreadLock(Thread);
-    /* Check if lock was released */
-    if (!Released)
-    {
-        /* Release the dispatcher database */
-        KiReleaseDispatcherLock(OldIrql);
-    }
-    else
-    {
-        /* Lower IRQL only */
-        KeLowerIrql(OldIrql);
-    }
+    /* Release the dispatcher database */
+    KiReleaseDispatcherLock(OldIrql);
     /* Return Old Priority */
     return OldPriority;
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 Thu Jan 18 00:53:45 2007
@@ -14,8 +14,6 @@
 /* GLOBALS *******************************************************************/
-LIST_ENTRY PriorityListHead[MAXIMUM_PRIORITY];
-ULONG PriorityListMask = 0;
 ULONG KiIdleSummary;
 ULONG KiIdleSMTSummary;
@@ -30,7 +28,243 @@
     KxQueueReadyThread(Thread, Prcb);
 }
-static
+VOID
+NTAPI
+KiDeferredReadyThread(IN PKTHREAD Thread)
+{
+    PKPRCB Prcb;
+    BOOLEAN Preempted;
+    ULONG Processor = 0;
+    KPRIORITY OldPriority;
+    PKTHREAD NextThread;
+
+    /* Sanity checks */
+    ASSERT(Thread->State == DeferredReady);
+    ASSERT((Thread->Priority >= 0) && (Thread->Priority <=
HIGH_PRIORITY));
+
+    /* Check if we have any adjusts to do */
+    if (Thread->AdjustReason == AdjustBoost)
+    {
+        /* Lock the thread */
+        KiAcquireThreadLock(Thread);
+
+        /* Check if the priority is low enough to qualify for boosting */
+        if ((Thread->Priority <= Thread->AdjustIncrement) &&
+            (Thread->Priority < (LOW_REALTIME_PRIORITY - 3)) &&
+            !(Thread->DisableBoost))
+        {
+            /* Calculate the new priority based on the adjust increment */
+            OldPriority = min(Thread->AdjustIncrement + 1,
+                              LOW_REALTIME_PRIORITY - 1);
+
+            /* Make sure we're not decreasing outside of the priority range */
+            ASSERT((Thread->PriorityDecrement >= 0) &&
+                   (Thread->PriorityDecrement <= Thread->Priority));
+
+            /* Calculate the new priority decrement based on the boost */
+            Thread->PriorityDecrement += ((SCHAR)OldPriority - Thread->Priority);
+
+            /* Again verify that this decrement is valid */
+            ASSERT((Thread->PriorityDecrement >= 0) &&
+                   (Thread->PriorityDecrement <= OldPriority));
+
+            /* Set the new priority */
+            Thread->Priority = (SCHAR)OldPriority;
+        }
+
+        /* We need 4 quanta, make sure we have them, then decrease by one */
+        if (Thread->Quantum < 4) Thread->Quantum = 4;
+        Thread->Quantum--;
+
+        /* Make sure the priority is still valid */
+        ASSERT((Thread->Priority >= 0) && (Thread->Priority <=
HIGH_PRIORITY));
+
+        /* Release the lock and clear the adjust reason */
+        KiReleaseThreadLock(Thread);
+        Thread->AdjustReason = AdjustNone;
+    }
+    else if (Thread->AdjustReason == AdjustUnwait)
+    {
+        /* Acquire the thread lock and check if this is a real-time thread */
+        KiAcquireThreadLock(Thread);
+        if (Thread->Priority < LOW_REALTIME_PRIORITY)
+        {
+            /* It's not real time, but is it time critical? */
+            if (Thread->BasePriority >= (LOW_REALTIME_PRIORITY - 2))
+            {
+                /* It is, so simply reset its quantum */
+                Thread->Quantum = Thread->QuantumReset;
+            }
+            else
+            {
+                /* Has the priority been adjusted previously? */
+                if (!(Thread->PriorityDecrement) &&
(Thread->AdjustIncrement))
+                {
+                    /* Yes, reset its quantum */
+                    Thread->Quantum = Thread->QuantumReset;
+                }
+
+                /* Wait code already handles quantum adjustment during APCs */
+                if (Thread->WaitStatus != STATUS_KERNEL_APC)
+                {
+                    /* Decrease the quantum by one and check if we're out */
+                    if (--Thread->Quantum <= 0)
+                    {
+                        /* We are, reset the quantum and get a new priority */
+                        Thread->Quantum = Thread->QuantumReset;
+                        Thread->Priority = KiComputeNewPriority(Thread, 1);
+                    }
+                }
+            }
+
+            /* Now check if we have no decrement and boosts are enabled */
+            if (!(Thread->PriorityDecrement) && !(Thread->DisableBoost))
+            {
+                /* Make sure we have an increment */
+                ASSERT(Thread->AdjustIncrement >= 0);
+
+                /* Calculate the new priority after the increment */
+                OldPriority = Thread->BasePriority + Thread->AdjustIncrement;
+
+                /* Check if this new priority is higher */
+                if (OldPriority > Thread->Priority)
+                {
+                    /* Make sure we don't go into the real time range */
+                    if (OldPriority >= LOW_REALTIME_PRIORITY)
+                    {
+                        /* Normalize it back down one notch */
+                        OldPriority = LOW_REALTIME_PRIORITY - 1;
+                    }
+
+                    /* Check if the priority is higher then the boosted base */
+                    if (OldPriority > (Thread->BasePriority +
+                                       Thread->AdjustIncrement))
+                    {
+                        /* Setup a priority decrement to nullify the boost  */
+                        Thread->PriorityDecrement = ((SCHAR)OldPriority -
+                                                    Thread->BasePriority -
+                                                    Thread->AdjustIncrement);
+                    }
+
+                    /* Make sure that the priority decrement is valid */
+                    ASSERT((Thread->PriorityDecrement >= 0) &&
+                           (Thread->PriorityDecrement <= OldPriority));
+
+                    /* Set this new priority */
+                    Thread->Priority = (SCHAR)OldPriority;
+                }
+            }
+        }
+        else
+        {
+            /* It's a real-time thread, so just reset its quantum */
+            Thread->Quantum = Thread->QuantumReset;
+        }
+
+        /* Make sure the priority makes sense */
+        ASSERT((Thread->Priority >= 0) && (Thread->Priority <=
HIGH_PRIORITY));
+
+        /* Release the thread lock and reset the adjust reason */
+        KiReleaseThreadLock(Thread);
+        Thread->AdjustReason = AdjustNone;
+    }
+
+    /* Clear thread preemption status and save current values */
+    Preempted = Thread->Preempted;
+    OldPriority = Thread->Priority;
+    Thread->Preempted = FALSE;
+
+    /* Queue the thread on CPU 0 and get the PRCB */
+    Thread->NextProcessor = 0;
+    Prcb = KiProcessorBlock[0];
+
+    /* Check if we have an idle summary */
+    if (KiIdleSummary)
+    {
+        /* Clear it and set this thread as the next one */
+        KiIdleSummary = 0;
+        Thread->State = Standby;
+        Prcb->NextThread = Thread;
+        return;
+    }
+
+    /* Set the CPU number */
+    Thread->NextProcessor = (UCHAR)Processor;
+
+    /* Get the next scheduled thread */
+    NextThread = Prcb->NextThread;
+    if (NextThread)
+    {
+        /* Sanity check */
+        ASSERT(NextThread->State == Standby);
+
+        /* Check if priority changed */
+        if (OldPriority > NextThread->Priority)
+        {
+            /* Preempt the thread */
+            NextThread->Preempted = TRUE;
+
+            /* Put this one as the next one */
+            Thread->State = Standby;
+            Prcb->NextThread = Thread;
+
+            /* Set it in deferred ready mode */
+            NextThread->State = DeferredReady;
+            NextThread->DeferredProcessor = Prcb->Number;
+            KiReleasePrcbLock(Prcb);
+            KiDeferredReadyThread(NextThread);
+            return;
+        }
+    }
+    else
+    {
+        /* Set the next thread as the current thread */
+        NextThread = Prcb->CurrentThread;
+        if (OldPriority > NextThread->Priority)
+        {
+            /* Preempt it if it's already running */
+            if (NextThread->State == Running) NextThread->Preempted = TRUE;
+
+            /* Set the thread on standby and as the next thread */
+            Thread->State = Standby;
+            Prcb->NextThread = Thread;
+
+            /* Release the lock */
+            KiReleasePrcbLock(Prcb);
+
+            /* Check if we're running on another CPU */
+            if (KeGetCurrentProcessorNumber() != Thread->NextProcessor)
+            {
+                /* We are, send an IPI */
+                KiIpiSendRequest(AFFINITY_MASK(Thread->NextProcessor), IPI_DPC);
+            }
+            return;
+        }
+    }
+
+    /* Sanity check */
+    ASSERT((OldPriority >= 0) && (OldPriority <= HIGH_PRIORITY));
+
+    /* Set this thread as ready */
+    Thread->State = Ready;
+    Thread->WaitTime = KeTickCount.LowPart;
+
+    /* Insert this thread in the appropriate order */
+    Preempted ? InsertHeadList(&Prcb->DispatcherReadyListHead[OldPriority],
+                               &Thread->WaitListEntry) :
+                InsertTailList(&Prcb->DispatcherReadyListHead[OldPriority],
+                               &Thread->WaitListEntry);
+
+    /* Update the ready summary */
+    Prcb->ReadySummary |= PRIORITY_MASK(OldPriority);
+
+    /* Sanity check */
+    ASSERT(OldPriority == Thread->Priority);
+
+    /* Release the lock */
+    KiReleasePrcbLock(Prcb);
+}
+
 VOID
 KiInsertIntoThreadList(KPRIORITY Priority,
                        PKTHREAD Thread)
@@ -44,23 +278,21 @@
         KEBUGCHECK(0);
     }
-    InsertTailList(&PriorityListHead[Priority], &Thread->WaitListEntry);
-    PriorityListMask |= (1 << Priority);
-}
-
-static
+    InsertTailList(&KeGetCurrentPrcb()->DispatcherReadyListHead[Priority],
&Thread->WaitListEntry);
+    KeGetCurrentPrcb()->ReadySummary |= (1 << Priority);
+}
+
 VOID
 KiRemoveFromThreadList(PKTHREAD Thread)
 {
     ASSERT(Ready == Thread->State);
     RemoveEntryList(&Thread->WaitListEntry);
-    if (IsListEmpty(&PriorityListHead[(ULONG)Thread->Priority])) {
-
-        PriorityListMask &= ~(1 << Thread->Priority);
-    }
-}
-
-static
+    if
(IsListEmpty(&KeGetCurrentPrcb()->DispatcherReadyListHead[Thread->Priority])) {
+
+        KeGetCurrentPrcb()->ReadySummary &= ~(1 << Thread->Priority);
+    }
+}
+
 PKTHREAD
 KiScanThreadList(KPRIORITY Priority,
                  KAFFINITY Affinity)
@@ -70,9 +302,9 @@
     Mask = (1 << Priority);
-    if (PriorityListMask & Mask) {
-
-        LIST_FOR_EACH(current, &PriorityListHead[Priority], KTHREAD, WaitListEntry) {
+    if (KeGetCurrentPrcb()->ReadySummary & Mask) {
+
+        LIST_FOR_EACH(current,
&KeGetCurrentPrcb()->DispatcherReadyListHead[Priority], KTHREAD, WaitListEntry) {
             if (current->State != Ready) {
@@ -165,11 +397,18 @@
 }
 VOID
-NTAPI
-KiDeferredReadyThread(IN PKTHREAD Thread)
-{
-    /* FIXME: Not yet implemented */
-    KEBUGCHECK(0);
+STDCALL
+KiDispatchThread(ULONG NewThreadStatus)
+{
+    KIRQL OldIrql;
+
+    if (KeGetCurrentPrcb()->IdleThread == NULL) {
+        return;
+    }
+
+    OldIrql = KiAcquireDispatcherLock();
+    KiDispatchThreadNoLock(NewThreadStatus);
+    KeLowerIrql(OldIrql);
 }
 PKTHREAD
@@ -203,15 +442,71 @@
 KiSwapThread(IN PKTHREAD CurrentThread,
              IN PKPRCB Prcb)
 {
-    BOOLEAN ApcState;
+    BOOLEAN ApcState = FALSE;
+    KIRQL WaitIrql;
+    LONG_PTR WaitStatus;
+    PKTHREAD NextThread;
+#ifdef NEW_SCHEDULER
+    PEPROCESS HackOfDoom = PsGetCurrentProcess();
+#endif
     ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL);
+    /* Acquire the PRCB lock */
+    KiAcquirePrcbLock(Prcb);
+
+    /* Get the next thread */
+    NextThread = Prcb->NextThread;
+    if (NextThread)
+    {
+        /* Already got a thread, set it up */
+        Prcb->NextThread = NULL;
+        Prcb->CurrentThread = NextThread;
+        NextThread->State = Running;
+    }
+    else
+    {
 #ifdef NEW_SCHEDULER
-
+        /* Try to find a ready thread */
+        NextThread = KiSelectReadyThread(0, Prcb);
+        if (NextThread)
+        {
+            /* Switch to it */
+            Prcb->CurrentThread = NextThread;
+            NextThread->State = Running;
+        }
+        else
+        {
+            /* Set the idle summary */
+            InterlockedOr(&KiIdleSummary, Prcb->SetMember);
+
+            /* Schedule the idle thread */
+            NextThread = Prcb->IdleThread;
+            Prcb->CurrentThread = NextThread;
+            NextThread->State = Running;
+        }
 #else
-    /* Find a new thread to run */
-    ApcState = KiDispatchThreadNoLock(Waiting);
+        /* Find a new thread to run */
+        ApcState = KiDispatchThreadNoLock(Waiting);
 #endif
+    }
+
+    /* Sanity check and release the PRCB */
+    ASSERT(CurrentThread != Prcb->IdleThread);
+    KiReleasePrcbLock(Prcb);
+
+    /* Save the wait IRQL */
+    WaitIrql = CurrentThread->WaitIrql;
+
+#ifdef NEW_SCHEDULER
+    /* REACTOS Mm Hack of Doom */
+    MmUpdatePageDir(HackOfDoom,((PETHREAD)NextThread)->ThreadsProcess,
sizeof(EPROCESS));
+
+    /* Swap contexts */
+    ApcState = KiSwapContext(CurrentThread, NextThread);
+#endif
+
+    /* Get the wait status */
+    WaitStatus = CurrentThread->WaitStatus;
     /* Check if we need to deliver APCs */
     if (ApcState)
@@ -221,29 +516,12 @@
         /* Deliver APCs */
         KiDeliverApc(KernelMode, NULL, NULL);
-        ASSERT(CurrentThread->WaitIrql == 0);
-    }
-
-    /* Lower IRQL back to what it was */
-    KfLowerIrql(CurrentThread->WaitIrql);
-
-    /* Return the wait status */
-    return CurrentThread->WaitStatus;
-}
-
-VOID
-STDCALL
-KiDispatchThread(ULONG NewThreadStatus)
-{
-    KIRQL OldIrql;
-
-    if (KeGetCurrentPrcb()->IdleThread == NULL) {
-        return;
-    }
-
-    OldIrql = KiAcquireDispatcherLock();
-    KiDispatchThreadNoLock(NewThreadStatus);
-    KeLowerIrql(OldIrql);
+        ASSERT(WaitIrql == 0);
+    }
+
+    /* Lower IRQL back to what it was and return the wait status */
+    KeLowerIrql(WaitIrql);
+    return WaitStatus;
 }
 VOID
@@ -289,6 +567,7 @@
 KiAdjustQuantumThread(IN PKTHREAD Thread)
 {
     PKPRCB Prcb = KeGetCurrentPrcb();
+    PKTHREAD NextThread;
     /* Acquire thread and PRCB lock */
     KiAcquireThreadLock(Thread);
@@ -327,6 +606,7 @@
             }
 #else
             /* We need to dispatch a new thread */
+            NextThread = NULL;
             KiDispatchThread(Ready);
 #endif
         }
@@ -339,10 +619,9 @@
 }
 VOID
-NTAPI
+FASTCALL
 KiSetPriorityThread(IN PKTHREAD Thread,
-                    IN KPRIORITY Priority,
-                    OUT PBOOLEAN Released)
+                    IN KPRIORITY Priority)
 {
     PKPRCB Prcb;
     ULONG Processor;
@@ -381,7 +660,8 @@
                         if (RemoveEntryList(&Thread->WaitListEntry))
                         {
                             /* Update the ready summary */
-                            Prcb->ReadySummary ^= PRIORITY_MASK(Thread->Priority);
+                            Prcb->ReadySummary ^= PRIORITY_MASK(Thread->
+                                                                Priority);
                         }
 #else
                         KiRemoveFromThreadList(Thread);
@@ -393,8 +673,7 @@
                         /* Re-insert it at its current priority */
 #ifndef NEW_SCHEDULER
                         KiInsertIntoThreadList(Priority, Thread);
-                        KiDispatchThreadNoLock(Ready);
-                        *Released = TRUE;
+                        //KiDispatchThreadNoLock(Ready);
 #else
                         KiInsertDeferredReadyList(Thread);
 #endif
@@ -486,14 +765,13 @@
                         }
 #else
                         /* Check for threads with a higher priority */
-                        if (PriorityListMask & ~((1 << (Priority + 1)) - 1))
+                        if (KeGetCurrentPrcb()->ReadySummary & ~((1 <<
(Priority + 1)) - 1))
                         {
                             /* Found a thread, is it us? */
                             if (Thread == KeGetCurrentThread())
                             {
                                 /* Dispatch us */
-                                KiDispatchThreadNoLock(Ready);
-                                *Released = TRUE;
+                                //KiDispatchThreadNoLock(Ready);
                                 return;
                             }
                         }
@@ -535,9 +813,6 @@
             break;
         }
     }
-
-    /* Return to caller */
-    *Released = FALSE;
 }
 KAFFINITY
@@ -579,13 +854,75 @@
 NTAPI
 NtYieldExecution(VOID)
 {
-    //
-    // TODO (nothing too hard, just want to test out other code)
-    //
-    //DPRINT1("NO YIELD PERFORMED! If you see this, contact Alex\n");
-    //return STATUS_NO_YIELD_PERFORMED;
+#ifdef NEW_SCHEDULER
+    NTSTATUS Status = STATUS_NO_YIELD_PERFORMED;
+    KIRQL OldIrql;
+    PKPRCB Prcb = KeGetCurrentPrcb();
+    PKTHREAD Thread = KeGetCurrentThread(), NextThread;
+
+    /* Fail if there's no ready summary */
+    if (!Prcb->ReadySummary) return Status;
+
+    /* Raise IRQL to synch */
+    OldIrql = KeRaiseIrqlToSynchLevel();
+
+    /* Now check if there's still a ready summary */
+    if (Prcb->ReadySummary)
+    {
+        /* Acquire thread and PRCB lock */
+        KiAcquireThreadLock(Thread);
+        KiAcquirePrcbLock(Prcb);
+
+        /* Find a new thread to run if none was selected */
+        if (!Prcb->NextThread) Prcb->NextThread = KiSelectReadyThread(1, Prcb);
+
+        /* Make sure we still have a next thread to schedule */
+        NextThread = Prcb->NextThread;
+        if (NextThread)
+        {
+            /* Reset quantum and recalculate priority */
+            Thread->Quantum = Thread->QuantumReset;
+            Thread->Priority = KiComputeNewPriority(Thread, 1);
+
+            /* Release the thread lock */
+            KiReleaseThreadLock(Thread);
+
+            /* Set context swap busy */
+            KiSetThreadSwapBusy(Thread);
+
+            /* Set the new thread as running */
+            Prcb->NextThread = NULL;
+            Prcb->CurrentThread = NextThread;
+            NextThread->State = Running;
+
+            /* Setup a yield wait and queue the thread */
+            Thread->WaitReason = WrYieldExecution;
+            KxQueueReadyThread(Thread, Prcb);
+
+            /* Make it wait at APC_LEVEL */
+            Thread->WaitIrql = APC_LEVEL;
+
+            /* Sanity check */
+            ASSERT(OldIrql <= DISPATCH_LEVEL);
+
+            /* Swap to new thread */
+            KiSwapContext(Thread, NextThread);
+            Status = STATUS_SUCCESS;
+        }
+        else
+        {
+            /* Release the PRCB and thread lock */
+            KiReleasePrcbLock(Prcb);
+            KiReleaseThreadLock(Thread);
+        }
+    }
+
+    /* Lower IRQL and return */
+    KeLowerIrql(OldIrql);
+    return Status;
+#else
     KiDispatchThread(Ready);
     return STATUS_SUCCESS;
-}
-
-
+#endif
+}
+
Modified: trunk/reactos/ntoskrnl/ps/psmgr.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ps/psmgr.c?rev=25…
==============================================================================
--- trunk/reactos/ntoskrnl/ps/psmgr.c (original)
+++ trunk/reactos/ntoskrnl/ps/psmgr.c Thu Jan 18 00:53:45 2007
@@ -289,7 +289,6 @@
     PETHREAD SysThread;
     MM_SYSTEMSIZE SystemSize;
     UNICODE_STRING Name;
-    ULONG i;
     OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
     /* FIXME: Initialize Lock Data do it STATIC */
@@ -379,12 +378,6 @@
     ObjectTypeInitializer.ValidAccessMask = PROCESS_ALL_ACCESS;
     ObjectTypeInitializer.DeleteProcedure = PspDeleteProcess;
     ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &PsProcessType);
-
-    /* Setup ROS Scheduler lists (HACK!) */
-    for (i = 0; i < MAXIMUM_PRIORITY; i++)
-    {
-        InitializeListHead(&PriorityListHead[i]);
-    }
     /*  Initialize the Thread type  */
     RtlInitUnicodeString(&Name, L"Thread");