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/k... ============================================================================== --- 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=25502... ============================================================================== --- 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?rev... ============================================================================== --- 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=2... ============================================================================== --- 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=2... ============================================================================== --- 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=255... ============================================================================== --- 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");