- Coalesce all calls to MmUpdatePageDir through a single inlined function - MiSyncProcessThreadViews, and fix callers which assumed that the kernel stack is KERNEL_STACK_SIZE, when in fact, it may be KERNEL_LARGE_STACK_SIZE. We now detect and handle this, fixing a bug in KiAttachProcess.

- Remove all old-scheduler code, it's not needed anymore, nor it's going to be ever supported.

svn path=/trunk/; revision=29247
This commit is contained in:
Aleksey Bragin 2007-09-27 16:28:56 +00:00
parent d4c51f18f7
commit ccc37f538c
6 changed files with 19 additions and 259 deletions

View file

@ -1474,7 +1474,7 @@ MmCheckSystemImage(
FORCEINLINE
VOID
NTAPI
MiSyncThreadProcessViews(IN PKPROCESS Process,
MiSyncThreadProcessViews(IN PVOID Process,
IN PVOID Address,
IN ULONG Size)
{

View file

@ -40,10 +40,6 @@ KiScanReadyQueues(IN PKDPC Dpc,
/* Lock the dispatcher and PRCB */
OldIrql = KiAcquireDispatcherLock();
KiAcquirePrcbLock(Prcb);
#ifndef NEW_SCHEDULER
goto OldSched;
#endif
/* Check if there's any thread that need help */
Summary = Prcb->ReadySummary & ((1 << THREAD_BOOST_PRIORITY) - 2);
if (Summary)
@ -76,7 +72,6 @@ KiScanReadyQueues(IN PKDPC Dpc,
if (WaitLimit >= Thread->WaitTime)
{
/* Remove the thread from the queue */
DPRINT1("Thread: %p\n", Thread);
NextEntry = NextEntry->Blink;
ASSERT((Prcb->ReadySummary & PRIORITY_MASK(Index)));
if (RemoveEntryList(NextEntry->Flink))
@ -114,9 +109,6 @@ KiScanReadyQueues(IN PKDPC Dpc,
}
/* Release the locks and dispatcher */
#ifndef NEW_SCHEDULER
OldSched:
#endif
KiReleasePrcbLock(Prcb);
KiReleaseDispatcherLock(OldIrql);

View file

@ -687,11 +687,6 @@ MainLoop:
call @KiRetireDpcList@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
#ifdef CONFIG_SMP

View file

@ -30,27 +30,6 @@ PVOID KeRaiseUserExceptionDispatcher;
/* PRIVATE FUNCTIONS *********************************************************/
FORCEINLINE
VOID
NTAPI
UpdatePageDirs(IN PKTHREAD Thread,
IN PKPROCESS Process)
{
/*
* The stack and the thread structure of the current process may be
* located in a page which is not present in the page directory of
* the process we're attaching to. That would lead to a page fault
* when this function returns. However, since the processor can't
* call the page fault handler 'cause it can't push EIP on the stack,
* this will show up as a stack fault which will crash the entire system.
* To prevent this, make sure the page directory of the process we're
* attaching to is up-to-date.
*/
MmUpdatePageDir((PEPROCESS)Process,
(PVOID)Thread->StackLimit,
KERNEL_STACK_SIZE);
}
VOID
NTAPI
KiAttachProcess(IN PKTHREAD Thread,
@ -463,13 +442,15 @@ NTAPI
KeAttachProcess(IN PKPROCESS Process)
{
KLOCK_QUEUE_HANDLE ApcLock;
PKTHREAD Thread;
PKTHREAD Thread = KeGetCurrentThread();
ASSERT_PROCESS(Process);
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
/* Make sure that we are in the right page directory */
Thread = KeGetCurrentThread();
UpdatePageDirs(Thread, Process);
MiSyncThreadProcessViews(Process,
(PVOID)Thread->StackLimit,
Thread->LargeStack ?
KERNEL_STACK_SIZE : KERNEL_LARGE_STACK_SIZE);
/* Check if we're already in that process */
if (Thread->ApcState.Process == Process) return;
@ -595,7 +576,10 @@ KeStackAttachProcess(IN PKPROCESS Process,
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
/* Make sure that we are in the right page directory */
UpdatePageDirs(Thread, Process);
MiSyncThreadProcessViews(Process,
(PVOID)Thread->StackLimit,
Thread->LargeStack ?
KERNEL_STACK_SIZE : KERNEL_LARGE_STACK_SIZE);
/* Crash system if DPC is being executed! */
if (KeIsExecutingDpc())

View file

@ -810,11 +810,11 @@ KeInitThread(IN OUT PKTHREAD Thread,
Thread->StackLimit = (ULONG_PTR)KernelStack - KERNEL_STACK_SIZE;
Thread->KernelStackResident = TRUE;
/* ROS Mm HACK */
MmUpdatePageDir((PEPROCESS)Process,
(PVOID)Thread->StackLimit,
KERNEL_STACK_SIZE);
MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread, sizeof(ETHREAD));
/* Make sure that we are in the right page directory */
MiSyncThreadProcessViews(Process,
Thread,
KERNEL_STACK_SIZE);
MiSyncThreadProcessViews(Process, Thread, sizeof(ETHREAD));
#if defined(_M_IX86)
/* Enter SEH to avoid crashes due to user mode */
@ -1006,7 +1006,6 @@ KeRevertToUserAffinityThread(VOID)
/* Lock the PRCB */
KiAcquirePrcbLock(Prcb);
#ifdef NEW_SCHEDULER
/* Check if there's no next thread scheduled */
if (!Prcb->NextThread)
{
@ -1015,14 +1014,6 @@ KeRevertToUserAffinityThread(VOID)
NextThread->State = Standby;
Prcb->NextThread = NextThread;
}
#else
/* We need to dispatch a new thread */
NextThread = NULL;
CurrentThread->WaitIrql = OldIrql;
KiDispatchThreadNoLock(Ready);
KeLowerIrql(OldIrql);
return;
#endif
/* Release the PRCB lock */
KiReleasePrcbLock(Prcb);
@ -1124,7 +1115,6 @@ KeSetSystemAffinityThread(IN KAFFINITY Affinity)
/* Lock the PRCB */
KiAcquirePrcbLock(Prcb);
#ifdef NEW_SCHEDULER
/* Check if there's no next thread scheduled */
if (!Prcb->NextThread)
{
@ -1133,14 +1123,6 @@ KeSetSystemAffinityThread(IN KAFFINITY Affinity)
NextThread->State = Standby;
Prcb->NextThread = NextThread;
}
#else
/* We need to dispatch a new thread */
NextThread = NULL;
CurrentThread->WaitIrql = OldIrql;
KiDispatchThreadNoLock(Ready);
KeLowerIrql(OldIrql);
return;
#endif
/* Release the PRCB lock */
KiReleasePrcbLock(Prcb);

View file

@ -265,152 +265,6 @@ KiDeferredReadyThread(IN PKTHREAD Thread)
KiReleasePrcbLock(Prcb);
}
VOID
KiInsertIntoThreadList(KPRIORITY Priority,
PKTHREAD Thread)
{
ASSERT(Ready == Thread->State);
ASSERT(Thread->Priority == Priority);
if (Priority >= MAXIMUM_PRIORITY || Priority < LOW_PRIORITY) {
DPRINT1("Invalid thread priority (%d)\n", Priority);
KEBUGCHECK(0);
}
InsertTailList(&KeGetCurrentPrcb()->DispatcherReadyListHead[Priority], &Thread->WaitListEntry);
KeGetCurrentPrcb()->ReadySummary |= (1 << Priority);
}
VOID
KiRemoveFromThreadList(PKTHREAD Thread)
{
ASSERT(Ready == Thread->State);
RemoveEntryList(&Thread->WaitListEntry);
if (IsListEmpty(&KeGetCurrentPrcb()->DispatcherReadyListHead[Thread->Priority])) {
KeGetCurrentPrcb()->ReadySummary &= ~(1 << Thread->Priority);
}
}
PKTHREAD
KiScanThreadList(KPRIORITY Priority,
KAFFINITY Affinity)
{
PKTHREAD current;
ULONG Mask;
Mask = (1 << Priority);
if (KeGetCurrentPrcb()->ReadySummary & Mask) {
LIST_FOR_EACH(current, &KeGetCurrentPrcb()->DispatcherReadyListHead[Priority], KTHREAD, WaitListEntry) {
if (current->State != Ready) {
DPRINT1("%p/%d\n", current, current->State);
}
ASSERT(current->State == Ready);
if (current->Affinity & Affinity) {
KiRemoveFromThreadList(current);
return(current);
}
}
}
return(NULL);
}
BOOLEAN
STDCALL
KiDispatchThreadNoLock(ULONG NewThreadStatus)
{
KPRIORITY CurrentPriority;
PKTHREAD Candidate;
ULONG Affinity;
PKTHREAD CurrentThread = KeGetCurrentThread();
BOOLEAN ApcState;
DPRINT("KiDispatchThreadNoLock() %d/%d/%d/%d\n", KeGetCurrentProcessorNumber(),
CurrentThread, NewThreadStatus, CurrentThread->State);
CurrentThread->State = (UCHAR)NewThreadStatus;
if (NewThreadStatus == Ready) {
KiInsertIntoThreadList(CurrentThread->Priority,
CurrentThread);
}
Affinity = 1 << KeGetCurrentProcessorNumber();
for (CurrentPriority = HIGH_PRIORITY; CurrentPriority >= LOW_PRIORITY; CurrentPriority--) {
Candidate = KiScanThreadList(CurrentPriority, Affinity);
if (Candidate == CurrentThread) {
Candidate->State = Running;
KiReleaseDispatcherLockFromDpcLevel();
return FALSE;
}
if (Candidate != NULL) {
PKTHREAD OldThread;
PKTHREAD IdleThread;
DPRINT("Scheduling %x(%d)\n",Candidate, CurrentPriority);
Candidate->State = Running;
OldThread = CurrentThread;
CurrentThread = Candidate;
IdleThread = KeGetCurrentPrcb()->IdleThread;
if (OldThread == IdleThread) {
KiIdleSummary &= ~Affinity;
} else if (CurrentThread == IdleThread) {
KiIdleSummary |= Affinity;
}
MmUpdatePageDir((PEPROCESS)PsGetCurrentProcess(),((PETHREAD)CurrentThread)->ThreadsProcess, sizeof(EPROCESS));
/* Special note for Filip: This will release the Dispatcher DB Lock ;-) -- Alex */
DPRINT("You are : %x, swapping to: %x.\n", OldThread, CurrentThread);
KeGetCurrentPrcb()->CurrentThread = CurrentThread;
ApcState = KiSwapContext(OldThread, CurrentThread);
DPRINT("You are : %x, swapped from: %x\n", OldThread, CurrentThread);
return ApcState;
}
}
DPRINT1("CRITICAL: No threads are ready (CPU%d)\n", KeGetCurrentProcessorNumber());
KEBUGCHECK(0);
return FALSE;
}
VOID
STDCALL
KiDispatchThread(ULONG NewThreadStatus)
{
KIRQL OldIrql;
if (KeGetCurrentPrcb()->IdleThread == NULL) {
return;
}
OldIrql = KiAcquireDispatcherLock();
KiDispatchThreadNoLock(NewThreadStatus);
KeLowerIrql(OldIrql);
}
PKTHREAD
FASTCALL
KiSelectNextThread(IN PKPRCB Prcb)
@ -446,9 +300,6 @@ KiSwapThread(IN PKTHREAD CurrentThread,
KIRQL WaitIrql;
LONG_PTR WaitStatus;
PKTHREAD NextThread;
#ifdef NEW_SCHEDULER
PEPROCESS HackOfDoom = PsGetCurrentProcess();
#endif
ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL);
/* Acquire the PRCB lock */
@ -465,7 +316,6 @@ KiSwapThread(IN PKTHREAD CurrentThread,
}
else
{
#ifdef NEW_SCHEDULER
/* Try to find a ready thread */
NextThread = KiSelectReadyThread(0, Prcb);
if (NextThread)
@ -484,10 +334,6 @@ KiSwapThread(IN PKTHREAD CurrentThread,
Prcb->CurrentThread = NextThread;
NextThread->State = Running;
}
#else
/* Find a new thread to run */
ApcState = KiDispatchThreadNoLock(Waiting);
#endif
}
/* Sanity check and release the PRCB */
@ -497,13 +343,13 @@ KiSwapThread(IN PKTHREAD CurrentThread,
/* Save the wait IRQL */
WaitIrql = CurrentThread->WaitIrql;
#ifdef NEW_SCHEDULER
/* REACTOS Mm Hack of Doom */
MmUpdatePageDir(HackOfDoom,((PETHREAD)NextThread)->ThreadsProcess, sizeof(EPROCESS));
MiSyncThreadProcessViews(PsGetCurrentProcess(),
((PETHREAD)NextThread)->ThreadsProcess,
sizeof(EPROCESS));
/* Swap contexts */
ApcState = KiSwapContext(CurrentThread, NextThread);
#endif
/* Get the wait status */
WaitStatus = CurrentThread->WaitStatus;
@ -552,13 +398,7 @@ KiReadyThread(IN PKTHREAD Thread)
else
{
/* Insert the thread on the deferred ready list */
#ifdef NEW_SCHEDULER
KiInsertDeferredReadyList(Thread);
#else
/* Insert the thread into the thread list */
Thread->State = Ready;
KiInsertIntoThreadList(Thread->Priority, Thread);
#endif
}
}
@ -586,7 +426,6 @@ KiAdjustQuantumThread(IN PKTHREAD Thread)
/* Calculate new Priority */
Thread->Priority = KiComputeNewPriority(Thread, 1);
#ifdef NEW_SCHEDULER
/* Check if there's no next thread scheduled */
if (!Prcb->NextThread)
{
@ -604,11 +443,6 @@ KiAdjustQuantumThread(IN PKTHREAD Thread)
/* This thread can be preempted again */
Thread->Preempted = FALSE;
}
#else
/* We need to dispatch a new thread */
NextThread = NULL;
KiDispatchThread(Ready);
#endif
}
}
@ -651,7 +485,6 @@ KiSetPriorityThread(IN PKTHREAD Thread,
if ((Thread->State == Ready) &&
(Thread->NextProcessor == Prcb->Number))
{
#ifdef NEW_SCHEDULER
/* Sanity check */
ASSERT((Prcb->ReadySummary &
PRIORITY_MASK(Thread->Priority)));
@ -663,20 +496,12 @@ KiSetPriorityThread(IN PKTHREAD Thread,
Prcb->ReadySummary ^= PRIORITY_MASK(Thread->
Priority);
}
#else
KiRemoveFromThreadList(Thread);
#endif
/* Update priority */
Thread->Priority = (SCHAR)Priority;
/* Re-insert it at its current priority */
#ifndef NEW_SCHEDULER
KiInsertIntoThreadList(Priority, Thread);
//KiDispatchThreadNoLock(Ready);
#else
KiInsertDeferredReadyList(Thread);
#endif
/* Release the PRCB Lock */
KiReleasePrcbLock(Prcb);
@ -751,7 +576,6 @@ KiSetPriorityThread(IN PKTHREAD Thread,
/* Check if there was a change and there's no new thread */
if ((Priority < OldPriority) && !(Prcb->NextThread))
{
#ifdef NEW_SCHEDULER
/* Find a new thread */
NewThread = KiSelectReadyThread(Priority + 1, Prcb);
if (NewThread)
@ -763,19 +587,6 @@ KiSetPriorityThread(IN PKTHREAD Thread,
/* Request an interrupt */
RequestInterrupt = TRUE;
}
#else
/* Check for threads with a higher priority */
if (KeGetCurrentPrcb()->ReadySummary & ~((1 << (Priority + 1)) - 1))
{
/* Found a thread, is it us? */
if (Thread == KeGetCurrentThread())
{
/* Dispatch us */
//KiDispatchThreadNoLock(Ready);
return;
}
}
#endif
}
/* Release the lock and check if we need an interrupt */
@ -854,7 +665,6 @@ NTSTATUS
NTAPI
NtYieldExecution(VOID)
{
#ifdef NEW_SCHEDULER
NTSTATUS Status = STATUS_NO_YIELD_PERFORMED;
KIRQL OldIrql;
PKPRCB Prcb = KeGetCurrentPrcb();
@ -920,9 +730,6 @@ NtYieldExecution(VOID)
/* Lower IRQL and return */
KeLowerIrql(OldIrql);
return Status;
#else
KiDispatchThread(Ready);
return STATUS_SUCCESS;
#endif
}