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");