mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
- Simplify KiSelectReadyThread.
- Disable KiSetAffinityThread to do nothing else but change affinity instead of doing re-scheduling (temporary change). - Cleanup KiQuantumEnd to prepare for new scheduler. - Fix up a large bug in KeInsertQueueDpc which was making every DPC become a Threaded DPC due to a bad assignment-instead-of-compare. - Copy KiSelectNextThread for new scheduler branch, without SMT support. - Fix a bug in KiAdjustQuantumThread under new scheduler. - Re-implement KiSetPriorityThread under new scheduler, leave hacks for current scheduler support. - Remove old testing assert from KiExitDispatcher. svn path=/trunk/; revision=25491
This commit is contained in:
parent
c15d054bad
commit
c696d66532
6 changed files with 258 additions and 147 deletions
|
@ -223,15 +223,14 @@ NTAPI
|
||||||
KiDeferredReadyThread(IN PKTHREAD Thread);
|
KiDeferredReadyThread(IN PKTHREAD Thread);
|
||||||
|
|
||||||
KAFFINITY
|
KAFFINITY
|
||||||
NTAPI
|
FASTCALL
|
||||||
KiSetAffinityThread(
|
KiSetAffinityThread(
|
||||||
IN PKTHREAD Thread,
|
IN PKTHREAD Thread,
|
||||||
IN KAFFINITY Affinity,
|
IN KAFFINITY Affinity
|
||||||
IN PBOOLEAN Released // hack
|
|
||||||
);
|
);
|
||||||
|
|
||||||
PKTHREAD
|
PKTHREAD
|
||||||
NTAPI
|
FASTCALL
|
||||||
KiSelectNextThread(
|
KiSelectNextThread(
|
||||||
IN PKPRCB Prcb
|
IN PKPRCB Prcb
|
||||||
);
|
);
|
||||||
|
|
|
@ -1259,12 +1259,12 @@ KiSelectReadyThread(IN KPRIORITY Priority,
|
||||||
{
|
{
|
||||||
LONG PriorityMask, PrioritySet, HighPriority;
|
LONG PriorityMask, PrioritySet, HighPriority;
|
||||||
PLIST_ENTRY ListEntry;
|
PLIST_ENTRY ListEntry;
|
||||||
PKTHREAD Thread;
|
PKTHREAD Thread = NULL;
|
||||||
|
|
||||||
/* Save the current mask and get the priority set for the CPU */
|
/* Save the current mask and get the priority set for the CPU */
|
||||||
PriorityMask = Priority;
|
PriorityMask = Priority;
|
||||||
PrioritySet = Prcb->ReadySummary >> (UCHAR)Priority;
|
PrioritySet = Prcb->ReadySummary >> (UCHAR)Priority;
|
||||||
if (!PrioritySet) return NULL;
|
if (!PrioritySet) goto Quickie;
|
||||||
|
|
||||||
/* Get the highest priority possible */
|
/* Get the highest priority possible */
|
||||||
BitScanReverse((PULONG)&HighPriority, PrioritySet);
|
BitScanReverse((PULONG)&HighPriority, PrioritySet);
|
||||||
|
@ -1275,7 +1275,7 @@ KiSelectReadyThread(IN KPRIORITY Priority,
|
||||||
ASSERT(IsListEmpty(&Prcb->DispatcherReadyListHead[HighPriority]) == FALSE);
|
ASSERT(IsListEmpty(&Prcb->DispatcherReadyListHead[HighPriority]) == FALSE);
|
||||||
|
|
||||||
/* Get the first thread on the list */
|
/* Get the first thread on the list */
|
||||||
ListEntry = &Prcb->DispatcherReadyListHead[HighPriority];
|
ListEntry = Prcb->DispatcherReadyListHead[HighPriority].Flink;
|
||||||
Thread = CONTAINING_RECORD(ListEntry, KTHREAD, WaitListEntry);
|
Thread = CONTAINING_RECORD(ListEntry, KTHREAD, WaitListEntry);
|
||||||
|
|
||||||
/* Make sure this thread is here for a reason */
|
/* Make sure this thread is here for a reason */
|
||||||
|
@ -1284,14 +1284,14 @@ KiSelectReadyThread(IN KPRIORITY Priority,
|
||||||
ASSERT(Thread->NextProcessor == Prcb->Number);
|
ASSERT(Thread->NextProcessor == Prcb->Number);
|
||||||
|
|
||||||
/* Remove it from the list */
|
/* Remove it from the list */
|
||||||
RemoveEntryList(&Thread->WaitListEntry);
|
if (RemoveEntryList(&Thread->WaitListEntry))
|
||||||
if (IsListEmpty(&Thread->WaitListEntry))
|
|
||||||
{
|
{
|
||||||
/* The list is empty now, reset the ready summary */
|
/* The list is empty now, reset the ready summary */
|
||||||
Prcb->ReadySummary ^= PRIORITY_MASK(HighPriority);
|
Prcb->ReadySummary ^= PRIORITY_MASK(HighPriority);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sanity check and return the thread */
|
/* Sanity check and return the thread */
|
||||||
|
Quickie:
|
||||||
ASSERT((Thread == NULL) ||
|
ASSERT((Thread == NULL) ||
|
||||||
(Thread->BasePriority == 0) ||
|
(Thread->BasePriority == 0) ||
|
||||||
(Thread->Priority != 0));
|
(Thread->Priority != 0));
|
||||||
|
|
|
@ -70,7 +70,22 @@ KiQuantumEnd(VOID)
|
||||||
/* Check if a new thread is scheduled */
|
/* Check if a new thread is scheduled */
|
||||||
if (!Prcb->NextThread)
|
if (!Prcb->NextThread)
|
||||||
{
|
{
|
||||||
/* FIXME: TODO. Add code from new scheduler */
|
#ifdef NEW_SCHEDULER
|
||||||
|
/* Get a new ready thread */
|
||||||
|
NextThread = KiSelectReadyThread(Thread->Priority, Prcb);
|
||||||
|
if (NextThread)
|
||||||
|
{
|
||||||
|
/* Found one, set it on standby */
|
||||||
|
NextThread->Standby;
|
||||||
|
Prcb->NextThread = NewThread;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* Just leave now */
|
||||||
|
KiReleasePrcbLock(Prcb);
|
||||||
|
KeLowerIrql(DISPATCH_LEVEL);
|
||||||
|
KiDispatchThread(Ready);
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -94,14 +109,9 @@ KiQuantumEnd(VOID)
|
||||||
/* Just leave now */
|
/* Just leave now */
|
||||||
KiReleasePrcbLock(Prcb);
|
KiReleasePrcbLock(Prcb);
|
||||||
KeLowerIrql(DISPATCH_LEVEL);
|
KeLowerIrql(DISPATCH_LEVEL);
|
||||||
KiDispatchThread(Ready); // FIXME: ROS
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This shouldn't happen on ROS yet */
|
|
||||||
DPRINT1("The impossible happened - Tell Alex\n");
|
|
||||||
ASSERT(FALSE);
|
|
||||||
|
|
||||||
/* Get the next thread now */
|
/* Get the next thread now */
|
||||||
NextThread = Prcb->NextThread;
|
NextThread = Prcb->NextThread;
|
||||||
|
|
||||||
|
@ -296,7 +306,7 @@ KeInsertQueueDpc(IN PKDPC Dpc,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if this is a threaded DPC and threaded DPCs are enabled */
|
/* Check if this is a threaded DPC and threaded DPCs are enabled */
|
||||||
if ((Dpc->Type = ThreadedDpcObject) && (Prcb->ThreadDpcEnable))
|
if ((Dpc->Type == ThreadedDpcObject) && (Prcb->ThreadDpcEnable))
|
||||||
{
|
{
|
||||||
/* Then use the threaded data */
|
/* Then use the threaded data */
|
||||||
DpcData = &Prcb->DpcData[DPC_THREADED];
|
DpcData = &Prcb->DpcData[DPC_THREADED];
|
||||||
|
|
|
@ -1252,7 +1252,6 @@ KeSetAffinityThread(IN PKTHREAD Thread,
|
||||||
{
|
{
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
KAFFINITY OldAffinity;
|
KAFFINITY OldAffinity;
|
||||||
BOOLEAN Released;
|
|
||||||
ASSERT_THREAD(Thread);
|
ASSERT_THREAD(Thread);
|
||||||
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
|
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
|
||||||
|
|
||||||
|
@ -1260,21 +1259,10 @@ KeSetAffinityThread(IN PKTHREAD Thread,
|
||||||
OldIrql = KiAcquireDispatcherLock();
|
OldIrql = KiAcquireDispatcherLock();
|
||||||
|
|
||||||
/* Call the internal function */
|
/* Call the internal function */
|
||||||
OldAffinity = KiSetAffinityThread(Thread, Affinity, &Released);
|
OldAffinity = KiSetAffinityThread(Thread, Affinity);
|
||||||
|
|
||||||
/* Check if lock was released */
|
/* Release the dispatcher database and return old affinity */
|
||||||
if (!Released)
|
KiReleaseDispatcherLock(OldIrql);
|
||||||
{
|
|
||||||
/* Release the dispatcher database */
|
|
||||||
KiReleaseDispatcherLock(OldIrql);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Lower IRQL only */
|
|
||||||
KeLowerIrql(OldIrql);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return old affinity */
|
|
||||||
return OldAffinity;
|
return OldAffinity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,17 +21,6 @@ ULONG KiIdleSMTSummary;
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
static
|
|
||||||
VOID
|
|
||||||
KiRequestReschedule(CCHAR Processor)
|
|
||||||
{
|
|
||||||
PKPCR Pcr;
|
|
||||||
|
|
||||||
Pcr = (PKPCR)(KPCR_BASE + Processor * PAGE_SIZE);
|
|
||||||
Pcr->Prcb->QuantumEnd = TRUE;
|
|
||||||
KiIpiSendRequest(1 << Processor, IPI_DPC);
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
static
|
||||||
VOID
|
VOID
|
||||||
KiInsertIntoThreadList(KPRIORITY Priority,
|
KiInsertIntoThreadList(KPRIORITY Priority,
|
||||||
|
@ -166,6 +155,40 @@ KiDispatchThreadNoLock(ULONG NewThreadStatus)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
KiDeferredReadyThread(IN PKTHREAD Thread)
|
||||||
|
{
|
||||||
|
/* FIXME: Not yet implemented */
|
||||||
|
KEBUGCHECK(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
PKTHREAD
|
||||||
|
FASTCALL
|
||||||
|
KiSelectNextThread(IN PKPRCB Prcb)
|
||||||
|
{
|
||||||
|
PKTHREAD Thread;
|
||||||
|
|
||||||
|
/* Select a ready thread */
|
||||||
|
Thread = KiSelectReadyThread(0, Prcb);
|
||||||
|
if (!Thread)
|
||||||
|
{
|
||||||
|
/* Didn't find any, get the current idle thread */
|
||||||
|
Thread = Prcb->IdleThread;
|
||||||
|
|
||||||
|
/* Enable idle scheduling */
|
||||||
|
InterlockedOr(&KiIdleSummary, Prcb->SetMember);
|
||||||
|
Prcb->IdleSchedule = TRUE;
|
||||||
|
|
||||||
|
/* FIXME: SMT support */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sanity checks and return the thread */
|
||||||
|
ASSERT(Thread != NULL);
|
||||||
|
ASSERT((Thread->BasePriority == 0) || (Thread->Priority != 0));
|
||||||
|
return Thread;
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
FASTCALL
|
FASTCALL
|
||||||
KiSwapThread(IN PKTHREAD CurrentThread,
|
KiSwapThread(IN PKTHREAD CurrentThread,
|
||||||
|
@ -174,8 +197,12 @@ KiSwapThread(IN PKTHREAD CurrentThread,
|
||||||
BOOLEAN ApcState;
|
BOOLEAN ApcState;
|
||||||
ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL);
|
ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL);
|
||||||
|
|
||||||
|
#ifdef NEW_SCHEDULER
|
||||||
|
|
||||||
|
#else
|
||||||
/* Find a new thread to run */
|
/* Find a new thread to run */
|
||||||
ApcState = KiDispatchThreadNoLock(Waiting);
|
ApcState = KiDispatchThreadNoLock(Waiting);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Check if we need to deliver APCs */
|
/* Check if we need to deliver APCs */
|
||||||
if (ApcState)
|
if (ApcState)
|
||||||
|
@ -238,7 +265,7 @@ KiReadyThread(IN PKTHREAD Thread)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Insert the thread on the deferred ready list */
|
/* Insert the thread on the deferred ready list */
|
||||||
#if 0
|
#ifdef NEW_SCHEDULER
|
||||||
KiInsertDeferredReadyList(Thread);
|
KiInsertDeferredReadyList(Thread);
|
||||||
#else
|
#else
|
||||||
/* Insert the thread into the thread list */
|
/* Insert the thread into the thread list */
|
||||||
|
@ -249,7 +276,7 @@ KiReadyThread(IN PKTHREAD Thread)
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
STDCALL
|
NTAPI
|
||||||
KiAdjustQuantumThread(IN PKTHREAD Thread)
|
KiAdjustQuantumThread(IN PKTHREAD Thread)
|
||||||
{
|
{
|
||||||
PKPRCB Prcb = KeGetCurrentPrcb();
|
PKPRCB Prcb = KeGetCurrentPrcb();
|
||||||
|
@ -275,10 +302,14 @@ KiAdjustQuantumThread(IN PKTHREAD Thread)
|
||||||
/* Check if there's no next thread scheduled */
|
/* Check if there's no next thread scheduled */
|
||||||
if (!Prcb->NextThread)
|
if (!Prcb->NextThread)
|
||||||
{
|
{
|
||||||
/* Select a new thread and set it on standby */
|
/* Select a ready thread and check if we found one */
|
||||||
NextThread = KiSelectNextThread(Prcb);
|
NextThread = KiSelectReadyThread(Thread->Priority, Prcb);
|
||||||
NextThread->State = Standby;
|
if (NextThread)
|
||||||
Prcb->NextThread = NextThread;
|
{
|
||||||
|
/* Set it on standby and switch to it */
|
||||||
|
NextThread->State = Standby;
|
||||||
|
Prcb->NextThread = NextThread;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -303,91 +334,213 @@ KiSetPriorityThread(IN PKTHREAD Thread,
|
||||||
IN KPRIORITY Priority,
|
IN KPRIORITY Priority,
|
||||||
OUT PBOOLEAN Released)
|
OUT PBOOLEAN Released)
|
||||||
{
|
{
|
||||||
KPRIORITY OldPriority = Thread->Priority;
|
PKPRCB Prcb;
|
||||||
ULONG Mask;
|
ULONG Processor;
|
||||||
ULONG i;
|
BOOLEAN RequestInterrupt = FALSE;
|
||||||
PKPCR Pcr;
|
KPRIORITY OldPriority;
|
||||||
|
PKTHREAD NewThread;
|
||||||
ASSERT((Priority >= 0) && (Priority <= HIGH_PRIORITY));
|
ASSERT((Priority >= 0) && (Priority <= HIGH_PRIORITY));
|
||||||
|
|
||||||
/* Check if priority changed */
|
/* Check if priority changed */
|
||||||
if (OldPriority != Priority)
|
if (Thread->Priority != Priority)
|
||||||
{
|
{
|
||||||
/* Set it */
|
/* Loop priority setting in case we need to start over */
|
||||||
Thread->Priority = (SCHAR)Priority;
|
for (;;)
|
||||||
|
|
||||||
/* Choose action based on thread's state */
|
|
||||||
if (Thread->State == Ready)
|
|
||||||
{
|
{
|
||||||
/* Remove it from the current queue */
|
/* Choose action based on thread's state */
|
||||||
KiRemoveFromThreadList(Thread);
|
if (Thread->State == Ready)
|
||||||
|
|
||||||
/* Re-insert it at its current priority */
|
|
||||||
KiInsertIntoThreadList(Priority, Thread);
|
|
||||||
|
|
||||||
/* Check if the old priority was lower */
|
|
||||||
if (KeGetCurrentThread()->Priority < Priority)
|
|
||||||
{
|
{
|
||||||
/* Dispatch it immediately */
|
/* Make sure we're not on the ready queue */
|
||||||
KiDispatchThreadNoLock(Ready);
|
if (Thread->ProcessReadyQueue)
|
||||||
*Released = TRUE;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (Thread->State == Running)
|
|
||||||
{
|
|
||||||
/* Check if the new priority is lower */
|
|
||||||
if (Priority < OldPriority)
|
|
||||||
{
|
|
||||||
/* Check for threads with a higher priority */
|
|
||||||
Mask = ~((1 << (Priority + 1)) - 1);
|
|
||||||
if (PriorityListMask & Mask)
|
|
||||||
{
|
{
|
||||||
/* Found a thread, is it us? */
|
/* Get the PRCB for the thread and lock it */
|
||||||
if (Thread == KeGetCurrentThread())
|
Processor = Thread->NextProcessor;
|
||||||
|
Prcb = KiProcessorBlock[Processor];
|
||||||
|
KiAcquirePrcbLock(Prcb);
|
||||||
|
|
||||||
|
/* Make sure the thread is still ready and on this CPU */
|
||||||
|
if ((Thread->State == Ready) &&
|
||||||
|
(Thread->NextProcessor == Prcb->Number))
|
||||||
{
|
{
|
||||||
/* Dispatch us */
|
/* Sanity check */
|
||||||
|
ASSERT((Prcb->ReadySummary &
|
||||||
|
PRIORITY_MASK(Thread->Priority)));
|
||||||
|
|
||||||
|
/* Remove it from the current queue */
|
||||||
|
#ifdef NEW_SCHEDULER
|
||||||
|
if (RemoveEntryList(&Thread->WaitListEntry))
|
||||||
|
{
|
||||||
|
/* Update the ready summary */
|
||||||
|
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);
|
KiDispatchThreadNoLock(Ready);
|
||||||
*Released = TRUE;
|
*Released = TRUE;
|
||||||
return;
|
#else
|
||||||
}
|
KiInsertDeferredReadyList(Thread);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Release the PRCB Lock */
|
||||||
|
KiReleasePrcbLock(Prcb);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Loop every CPU */
|
/* Release the lock and loop again */
|
||||||
for (i = 0; i < KeNumberProcessors; i++)
|
KEBUGCHECK(0);
|
||||||
{
|
KiReleasePrcbLock(Prcb);
|
||||||
/* Get the PCR for this CPU */
|
continue;
|
||||||
Pcr = (PKPCR)(KPCR_BASE + i * PAGE_SIZE);
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* It's already on the ready queue, just update priority */
|
||||||
|
Thread->Priority = (SCHAR)Priority;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (Thread->State == Standby)
|
||||||
|
{
|
||||||
|
/* Get the PRCB for the thread and lock it */
|
||||||
|
KEBUGCHECK(0);
|
||||||
|
Processor = Thread->NextProcessor;
|
||||||
|
Prcb = KiProcessorBlock[Processor];
|
||||||
|
KiAcquirePrcbLock(Prcb);
|
||||||
|
|
||||||
/* Reschedule if the new one is already on a CPU */
|
/* Check if we're still the next thread to run */
|
||||||
if (Pcr->Prcb->CurrentThread == Thread)
|
if (Thread == Prcb->NextThread)
|
||||||
|
{
|
||||||
|
/* Get the old priority and update ours */
|
||||||
|
OldPriority = Thread->Priority;
|
||||||
|
Thread->Priority = (SCHAR)Priority;
|
||||||
|
|
||||||
|
/* Check if there was a change */
|
||||||
|
if (Priority < OldPriority)
|
||||||
|
{
|
||||||
|
/* Find a new thread */
|
||||||
|
NewThread = KiSelectReadyThread(Priority + 1, Prcb);
|
||||||
|
if (NewThread)
|
||||||
|
{
|
||||||
|
/* Found a new one, set it on standby */
|
||||||
|
NewThread->State = Standby;
|
||||||
|
Prcb->NextThread = NewThread;
|
||||||
|
|
||||||
|
/* Dispatch our thread */
|
||||||
|
KiInsertDeferredReadyList(Thread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release the PRCB lock */
|
||||||
|
KiReleasePrcbLock(Prcb);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Release the lock and try again */
|
||||||
|
KiReleasePrcbLock(Prcb);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (Thread->State == Running)
|
||||||
|
{
|
||||||
|
/* Get the PRCB for the thread and lock it */
|
||||||
|
Processor = Thread->NextProcessor;
|
||||||
|
Prcb = KiProcessorBlock[Processor];
|
||||||
|
KiAcquirePrcbLock(Prcb);
|
||||||
|
|
||||||
|
/* Check if we're still the current thread running */
|
||||||
|
if (Thread == Prcb->CurrentThread)
|
||||||
|
{
|
||||||
|
/* Get the old priority and update ours */
|
||||||
|
OldPriority = Thread->Priority;
|
||||||
|
Thread->Priority = (SCHAR)Priority;
|
||||||
|
|
||||||
|
/* 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)
|
||||||
|
{
|
||||||
|
/* Found a new one, set it on standby */
|
||||||
|
NewThread->State = Standby;
|
||||||
|
Prcb->NextThread = NewThread;
|
||||||
|
|
||||||
|
/* Request an interrupt */
|
||||||
|
RequestInterrupt = TRUE;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* Check for threads with a higher priority */
|
||||||
|
if (PriorityListMask & ~((1 << (Priority + 1)) - 1))
|
||||||
|
{
|
||||||
|
/* Found a thread, is it us? */
|
||||||
|
if (Thread == KeGetCurrentThread())
|
||||||
{
|
{
|
||||||
KiReleaseDispatcherLockFromDpcLevel();
|
/* Dispatch us */
|
||||||
KiRequestReschedule(i);
|
KiDispatchThreadNoLock(Ready);
|
||||||
*Released = TRUE;
|
*Released = TRUE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release the lock and check if we need an interrupt */
|
||||||
|
KiReleasePrcbLock(Prcb);
|
||||||
|
if (RequestInterrupt)
|
||||||
|
{
|
||||||
|
/* Check if we're running on another CPU */
|
||||||
|
if (KeGetCurrentProcessorNumber() != Processor)
|
||||||
|
{
|
||||||
|
/* We are, send an IPI */
|
||||||
|
KiIpiSendRequest(AFFINITY_MASK(Processor), IPI_DPC);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Thread changed, release lock and restart */
|
||||||
|
KiReleasePrcbLock(Prcb);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else if (Thread->State == DeferredReady)
|
||||||
|
{
|
||||||
|
/* FIXME: TODO */
|
||||||
|
DPRINT1("Deferred state not yet supported\n");
|
||||||
|
KEBUGCHECK(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Any other state, just change priority */
|
||||||
|
Thread->Priority = (SCHAR)Priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we got here, then thread state was consistent, so bail out */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return to caller */
|
/* Return to caller */
|
||||||
*Released = FALSE;
|
*Released = FALSE;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
KAFFINITY
|
KAFFINITY
|
||||||
NTAPI
|
FASTCALL
|
||||||
KiSetAffinityThread(IN PKTHREAD Thread,
|
KiSetAffinityThread(IN PKTHREAD Thread,
|
||||||
IN KAFFINITY Affinity,
|
IN KAFFINITY Affinity)
|
||||||
PBOOLEAN Released)
|
|
||||||
{
|
{
|
||||||
KAFFINITY OldAffinity;
|
KAFFINITY OldAffinity;
|
||||||
ULONG ProcessorMask;
|
|
||||||
CCHAR i;
|
/* Get the current affinity */
|
||||||
PKPCR Pcr;
|
OldAffinity = Thread->UserAffinity;
|
||||||
|
|
||||||
/* Make sure that the affinity is valid */
|
/* Make sure that the affinity is valid */
|
||||||
if (((Affinity & Thread->ApcState.Process->Affinity) != (Affinity)) ||
|
if (((Affinity & Thread->ApcState.Process->Affinity) != (Affinity)) ||
|
||||||
|
@ -397,52 +550,17 @@ KiSetAffinityThread(IN PKTHREAD Thread,
|
||||||
KeBugCheck(INVALID_AFFINITY_SET);
|
KeBugCheck(INVALID_AFFINITY_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the old affinity */
|
/* Update the new affinity */
|
||||||
OldAffinity = Thread->UserAffinity;
|
|
||||||
|
|
||||||
Thread->UserAffinity = Affinity;
|
Thread->UserAffinity = Affinity;
|
||||||
|
|
||||||
if (Thread->SystemAffinityActive == FALSE) {
|
/* Check if system affinity is disabled */
|
||||||
|
if (!Thread->SystemAffinityActive)
|
||||||
Thread->Affinity = Affinity;
|
{
|
||||||
|
/* FIXME: TODO */
|
||||||
if (Thread->State == Running) {
|
DPRINT1("Affinity support disabled!\n");
|
||||||
|
|
||||||
ProcessorMask = 1 << KeGetCurrentProcessorNumber();
|
|
||||||
if (Thread == KeGetCurrentThread()) {
|
|
||||||
|
|
||||||
if (!(Affinity & ProcessorMask)) {
|
|
||||||
|
|
||||||
KiDispatchThreadNoLock(Ready);
|
|
||||||
*Released = TRUE;
|
|
||||||
return OldAffinity;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
for (i = 0; i < KeNumberProcessors; i++) {
|
|
||||||
|
|
||||||
Pcr = (PKPCR)(KPCR_BASE + i * PAGE_SIZE);
|
|
||||||
if (Pcr->Prcb->CurrentThread == Thread) {
|
|
||||||
|
|
||||||
if (!(Affinity & ProcessorMask)) {
|
|
||||||
|
|
||||||
KiReleaseDispatcherLockFromDpcLevel();
|
|
||||||
KiRequestReschedule(i);
|
|
||||||
*Released = TRUE;
|
|
||||||
return OldAffinity;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT (i < KeNumberProcessors);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*Released = FALSE;
|
/* Return the old affinity */
|
||||||
return OldAffinity;
|
return OldAffinity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -183,10 +183,6 @@ KiExitDispatcher(IN KIRQL OldIrql)
|
||||||
/* Make sure there's a new thread scheduled */
|
/* Make sure there's a new thread scheduled */
|
||||||
if (!Prcb->NextThread) goto Quickie;
|
if (!Prcb->NextThread) goto Quickie;
|
||||||
|
|
||||||
/* This shouldn't happen on ROS yet */
|
|
||||||
DPRINT1("The impossible happened - Tell Alex\n");
|
|
||||||
ASSERT(FALSE);
|
|
||||||
|
|
||||||
/* Lock the PRCB */
|
/* Lock the PRCB */
|
||||||
KiAcquirePrcbLock(Prcb);
|
KiAcquirePrcbLock(Prcb);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue