balmgr.c MS and ReactOS

-173 Removals
+97 Additions
NTOS KernelREACT OS
VOIDVOID
KiScanReadyQueues (NTAPI
IN PKDPC Dpc,KiScanReadyQueues(IN PKDPC Dpc,
IN PVOID DeferredContext, IN PVOID DeferredContext,
IN PVOID SystemArgument1, IN PVOID SystemArgument1,
IN PVOID SystemArgument2 IN PVOID SystemArgument2)
)
/*++
Routine Description:
This function scans a section of the ready queues and attempts to
boost the priority of threads that run at variable priority levels.
N.B. This function is executed as a DPC from the periodic timer that
drives the balance set manager.
Arguments:
Dpc - Supplies a pointer to a DPC object - not used.
DeferredContext - Supplies the DPC context - not used.
SystemArgument1 - Supplies the first system argument - note used.
SystemArgument2 - Supplies the second system argument - note used.
Return Value:
None.
--*/
{{
PULONG ScanLast = DeferredContext;
ULONG Count = 0; ULONG ScanIndex = *ScanLast;
PLIST_ENTRY Entry; ULONG Count = 10, Number = 16;
ULONG Index; PKPRCB Prcb = KiProcessorBlock[ScanIndex];
PLIST_ENTRY ListHead; ULONG Index = Prcb->QueueIndex;
ULONG Number = 0; ULONG WaitLimit = KeTickCount.LowPart - 300;
ULONG Summary;
KIRQL OldIrql; KIRQL OldIrql;
PKPRCB Prcb; PLIST_ENTRY ListHead, NextEntry;
ULONG ScanIndex;
PULONG ScanLast;
ULONG Summary;
PKTHREAD Thread; PKTHREAD Thread;
ULONG WaitLimit;
UNREFERENCED_PARAMETER(SystemArgument1); /* Lock the dispatcher and PRCB */
UNREFERENCED_PARAMETER(SystemArgument2); OldIrql = KiAcquireDispatcherLock();
//
// Get the address of the queue index variable.
//
// N.B. If a fault occurs accessing queue index value, then the exception
// handler is either executed or a bugcheck occurs.
//
ScanLast = (PULONG)DeferredContext;
#if defined(_AMD64_)
try {
ScanIndex = *ScanLast;
} except(KiKernelDpcFilter(Dpc, GetExceptionInformation())) {
return;
}
#else
UNREFERENCED_PARAMETER(Dpc);
ScanIndex = *ScanLast;
#endif
//
// Lock the dispatcher database, acquire the PRCB lock, and check if
// there are any ready threads queued at the scanable priority levels.
//
Count = THREAD_READY_COUNT;
Number = THREAD_SCAN_COUNT;
Prcb = KiProcessorBlock[ScanIndex];
Index = Prcb->QueueIndex;
WaitLimit = KiQueryLowTickCount() - READY_WITHOUT_RUNNING;
KiLockDispatcherDatabase(&OldIrql);
KiAcquirePrcbLock(Prcb); KiAcquirePrcbLock(Prcb);
/* Check if there's any thread that need help */
Summary = Prcb->ReadySummary & ((1 << THREAD_BOOST_PRIORITY) - 2); Summary = Prcb->ReadySummary & ((1 << THREAD_BOOST_PRIORITY) - 2);
if (Summary != 0) { if (Summary)
do { {
/* Start scan loop */
do
{
/* Normalize the index */
if (Index > (THREAD_BOOST_PRIORITY - 1)) Index = 1;
// /* Loop for ready threads */
// If the current ready queue index is beyond the end of the range if (Summary & PRIORITY_MASK(Index))
// of priorities that are scanned, then wrap back to the beginning {
// priority. /* Sanity check */
// ASSERT(!IsListEmpty(&Prcb->DispatcherReadyListHead[Index]));
if (Index > THREAD_SCAN_PRIORITY) {
Index = 1;
}
// /* Update summary and select list */
// If there are any ready threads queued at the current priority
// level, then attempt to boost the thread priority.
//
if (Summary & PRIORITY_MASK(Index)) {
ASSERT(IsListEmpty(&Prcb->DispatcherReadyListHead[Index]) == FALSE);
Summary ^= PRIORITY_MASK(Index); Summary ^= PRIORITY_MASK(Index);
ListHead = &Prcb->DispatcherReadyListHead[Index]; ListHead = &Prcb->DispatcherReadyListHead[Index];
Entry = ListHead->Flink; NextEntry = ListHead->Flink;
do { do
{
// /* Select a thread */
// If the thread has been waiting for an extended period, Thread = CONTAINING_RECORD(NextEntry,
// then boost the priority of the selected. KTHREAD,
// WaitListEntry);
ASSERT(Thread->Priority == Index);
Thread = CONTAINING_RECORD(Entry, KTHREAD, WaitListEntry);
ASSERT(Thread->Priority == (KPRIORITY)Index);
if (WaitLimit >= Thread->WaitTime) {
//
// Remove the thread from the respective ready queue.
//
Entry = Entry->Blink;
ASSERT((Prcb->ReadySummary & PRIORITY_MASK(Index)) != 0);
if (RemoveEntryList(Entry->Flink) != FALSE) { /* Check if the thread has been waiting too long */
if (WaitLimit >= Thread->WaitTime)
{
/* Remove the thread from the queue */
NextEntry = NextEntry->Blink;
ASSERT((Prcb->ReadySummary & PRIORITY_MASK(Index)));
if (RemoveEntryList(NextEntry->Flink))
{
/* The list is empty now */
Prcb->ReadySummary ^= PRIORITY_MASK(Index); Prcb->ReadySummary ^= PRIORITY_MASK(Index);
} }
// /* Verify priority decrement and set the new one */
// Compute the priority decrement value, set the new
// thread priority, set the thread quantum to a value
// appropriate for lock ownership, and insert the
// thread in the ready list.
//
ASSERT((Thread->PriorityDecrement >= 0) && ASSERT((Thread->PriorityDecrement >= 0) &&
(Thread->PriorityDecrement <= Thread->Priority)); (Thread->PriorityDecrement <=
Thread->Priority));
Thread->PriorityDecrement += Thread->PriorityDecrement += (THREAD_BOOST_PRIORITY -
(THREAD_BOOST_PRIORITY - Thread->Priority); Thread->Priority);
ASSERT((Thread->PriorityDecrement >= 0) && ASSERT((Thread->PriorityDecrement >= 0) &&
(Thread->PriorityDecrement <= THREAD_BOOST_PRIORITY)); (Thread->PriorityDecrement <=
THREAD_BOOST_PRIORITY));
/* Update priority and insert into ready list */
Thread->Priority = THREAD_BOOST_PRIORITY; Thread->Priority = THREAD_BOOST_PRIORITY;
Thread->Quantum = LOCK_OWNERSHIP_QUANTUM; Thread->Quantum = WAIT_QUANTUM_DECREMENT * 4;
KiInsertDeferredReadyList(Thread); KiInsertDeferredReadyList(Thread);
Count -= 1; Count --;
} }
Entry = Entry->Flink; /* Go to the next entry */
Number -= 1; NextEntry = NextEntry->Flink;
} while ((Entry != ListHead) && (Number != 0) && (Count != 0)); Number--;
} while((NextEntry != ListHead) && (Number) && (Count));
} }
Index += 1; /* Increase index */
} while ((Summary != 0) && (Number != 0) && (Count != 0)); Index++;
} while ((Summary) && (Number) && (Count));
} }
// /* Release the locks and dispatcher */
// Release the PRCB lock, unlock the dispatcher database, and save the
// last ready queue index for the next scan.
//
KiReleasePrcbLock(Prcb); KiReleasePrcbLock(Prcb);
KiUnlockDispatcherDatabase(OldIrql); KiReleaseDispatcherLock(OldIrql);
if ((Count != 0) && (Number != 0)) {
/* Update the queue index for next time */
if ((Count) && (Number))
{
/* Reset the queue at index 1 */
Prcb->QueueIndex = 1; Prcb->QueueIndex = 1;
}
} else { else
{
/* Set the index we're in now */
Prcb->QueueIndex = Index; Prcb->QueueIndex = Index;
} }
// /* Increment the CPU number for next time and normalize to CPU count */
// Increment the processor number. ScanIndex++;
// if (ScanIndex == KeNumberProcessors) ScanIndex = 0;
ScanIndex += 1;
if (ScanIndex == (ULONG)KeNumberProcessors) {
ScanIndex = 0;
}
/* Return the index */
*ScanLast = ScanIndex; *ScanLast = ScanIndex;
return;
}}
Editor
Original Text
Changed Text