mirror of
https://github.com/reactos/reactos.git
synced 2024-10-06 17:35:07 +00:00
- Update KeRevertToUserAffinityThread, KeSetSystemAffinityThread to use new lock functions, and add code to support future scheduler.
- Update KeSetIdealProcessorThread to properly do Ideal CPU logic instead of blindgly setting it (most importantly, respect UserIdealProcessor and SystemAffinityActive seettings). svn path=/trunk/; revision=24033
This commit is contained in:
parent
d3a7b531f3
commit
678df444b7
|
@ -826,105 +826,177 @@ KeQueryPriorityThread(IN PKTHREAD Thread)
|
|||
return Thread->Priority;
|
||||
}
|
||||
|
||||
|
||||
// re-org
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
STDCALL
|
||||
NTAPI
|
||||
KeRevertToUserAffinityThread(VOID)
|
||||
{
|
||||
PKTHREAD CurrentThread = KeGetCurrentThread();
|
||||
KIRQL OldIrql;
|
||||
|
||||
PKPRCB Prcb;
|
||||
PKTHREAD NextThread, CurrentThread = KeGetCurrentThread();
|
||||
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
|
||||
ASSERT(CurrentThread->SystemAffinityActive != FALSE);
|
||||
|
||||
/* Lock the Dispatcher Database */
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock();
|
||||
OldIrql = KiAcquireDispatcherLock();
|
||||
|
||||
/* Return to User Affinity */
|
||||
/* Set the user affinity and processor and disable system affinity */
|
||||
CurrentThread->Affinity = CurrentThread->UserAffinity;
|
||||
|
||||
/* Disable System Affinity */
|
||||
CurrentThread->IdealProcessor = CurrentThread->UserIdealProcessor;
|
||||
CurrentThread->SystemAffinityActive = FALSE;
|
||||
|
||||
/* Check if we need to Dispatch a New thread */
|
||||
if (CurrentThread->Affinity & (1 << KeGetCurrentProcessorNumber())) {
|
||||
|
||||
/* No, just release */
|
||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||
|
||||
} else {
|
||||
/* Get the current PRCB and check if it doesn't match this affinity */
|
||||
Prcb = KeGetCurrentPrcb();
|
||||
if (!(Prcb->SetMember & CurrentThread->Affinity))
|
||||
{
|
||||
/* Lock the PRCB */
|
||||
KiAcquirePrcbLock(Prcb);
|
||||
|
||||
#ifdef NEW_SCHEDULER
|
||||
/* Check if there's no next thread scheduled */
|
||||
if (!Prcb->NextThread)
|
||||
{
|
||||
/* Select a new thread and set it on standby */
|
||||
NextThread = KiSelectNextThread(Prcb);
|
||||
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);
|
||||
}
|
||||
|
||||
/* Unlock dispatcher database */
|
||||
KiReleaseDispatcherLock(OldIrql);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
UCHAR
|
||||
STDCALL
|
||||
NTAPI
|
||||
KeSetIdealProcessorThread(IN PKTHREAD Thread,
|
||||
IN UCHAR Processor)
|
||||
{
|
||||
CCHAR PreviousIdealProcessor;
|
||||
CCHAR OldIdealProcessor;
|
||||
KIRQL OldIrql;
|
||||
ASSERT(Processor <= MAXIMUM_PROCESSORS);
|
||||
|
||||
/* Lock the Dispatcher Database */
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock();
|
||||
OldIrql = KiAcquireDispatcherLock();
|
||||
|
||||
/* Save Old Ideal Processor */
|
||||
PreviousIdealProcessor = Thread->IdealProcessor;
|
||||
OldIdealProcessor = Thread->UserIdealProcessor;
|
||||
|
||||
/* Set New Ideal Processor */
|
||||
Thread->IdealProcessor = Processor;
|
||||
/* Make sure a valid CPU was given */
|
||||
if (Processor < MAXIMUM_PROCESSORS)
|
||||
{
|
||||
/* Check if the user ideal CPU is in the affinity */
|
||||
if (Thread->UserIdealProcessor & AFFINITY_MASK(Processor))
|
||||
{
|
||||
/* Set the ideal processor */
|
||||
Thread->IdealProcessor = Processor;
|
||||
|
||||
/* Release Lock */
|
||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||
/* Check if system affinity is used */
|
||||
if (!Thread->SystemAffinityActive)
|
||||
{
|
||||
/* It's not, so update the user CPU too */
|
||||
Thread->UserIdealProcessor = Processor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Return Old Ideal Processor */
|
||||
return PreviousIdealProcessor;
|
||||
/* Release dispatcher lock and return the old ideal CPU */
|
||||
KiReleaseDispatcherLock(OldIrql);
|
||||
return OldIdealProcessor;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
STDCALL
|
||||
NTAPI
|
||||
KeSetSystemAffinityThread(IN KAFFINITY Affinity)
|
||||
{
|
||||
PKTHREAD CurrentThread = KeGetCurrentThread();
|
||||
KIRQL OldIrql;
|
||||
|
||||
ASSERT(Affinity & ((1 << KeNumberProcessors) - 1));
|
||||
PKPRCB Prcb;
|
||||
#ifdef CONFIG_SMP
|
||||
ULONG AffinitySet, NodeMask;
|
||||
#endif
|
||||
PKTHREAD NextThread, CurrentThread = KeGetCurrentThread();
|
||||
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
|
||||
ASSERT((Affinity & KeActiveProcessors) != 0);
|
||||
|
||||
/* Lock the Dispatcher Database */
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock();
|
||||
OldIrql = KiAcquireDispatcherLock();
|
||||
|
||||
/* Set the System Affinity Specified */
|
||||
/* Restore the affinity and enable system affinity */
|
||||
CurrentThread->Affinity = Affinity;
|
||||
|
||||
/* Enable System Affinity */
|
||||
CurrentThread->SystemAffinityActive = TRUE;
|
||||
|
||||
/* Check if we need to Dispatch a New thread */
|
||||
if (Affinity & (1 << KeGetCurrentProcessorNumber())) {
|
||||
/* Check if the ideal processor is part of the affinity */
|
||||
#ifdef CONFIG_SMP
|
||||
if (!(Affinity & AFFINITY_MASK(CurrentThread->IdealProcessor)))
|
||||
{
|
||||
/* It's not! Get the PRCB */
|
||||
Prcb = KiProcessorBlock[CurrentThread->IdealProcessor];
|
||||
|
||||
/* No, just release */
|
||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||
/* Calculate the affinity set */
|
||||
AffinitySet = KeActiveProcessors & Affinity;
|
||||
NodeMask = Prcb->ParentNode->ProcessorMask & AffinitySet;
|
||||
if (NodeMask)
|
||||
{
|
||||
/* Use the Node set instead */
|
||||
AffinitySet = NodeMask;
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Calculate the ideal CPU from the affinity set */
|
||||
BitScanReverse(&NodeMask, AffinitySet);
|
||||
CurrentThread->IdealProcessor = (UCHAR)NodeMask;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Get the current PRCB and check if it doesn't match this affinity */
|
||||
Prcb = KeGetCurrentPrcb();
|
||||
if (!(Prcb->SetMember & CurrentThread->Affinity))
|
||||
{
|
||||
/* Lock the PRCB */
|
||||
KiAcquirePrcbLock(Prcb);
|
||||
|
||||
#ifdef NEW_SCHEDULER
|
||||
/* Check if there's no next thread scheduled */
|
||||
if (!Prcb->NextThread)
|
||||
{
|
||||
/* Select a new thread and set it on standby */
|
||||
NextThread = KiSelectNextThread(Prcb);
|
||||
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);
|
||||
}
|
||||
|
||||
/* Unlock dispatcher database */
|
||||
KiReleaseDispatcherLock(OldIrql);
|
||||
}
|
||||
|
||||
LONG
|
||||
|
|
Loading…
Reference in a new issue