{
PULONG ScanLast = DeferredContext;
ULONG ScanIndex = *ScanLast;
ULONGCount = 10, Number = 16;
PKPRCB Prcb = KiProcessorBlock[ScanIndex];
ULONGIndex = Prcb->QueueIndex;
ULONG WaitLimit = KeTickCount.LowPart - 300;
ULONG Summary;
KIRQLOldIrql;
PLIST_ENTRY ListHead, NextEntry;
PKTHREADThread;
/* Lock the dispatcher and PRCB */
OldIrql = KiAcquireDispatcherLock();
KiAcquirePrcbLock(Prcb);
/* Check if there's any thread that need help */
Summary = Prcb->ReadySummary & ((1 << THREAD_BOOST_PRIORITY) - 2);
if (Summary)
{
/* Start scan loop */do
{
/* Normalize the index */if (Index > (THREAD_BOOST_PRIORITY - 1)) Index = 1;
/* Loop for ready threads */if (Summary & PRIORITY_MASK(Index))
{
/* Sanity check */ASSERT(!IsListEmpty(&Prcb->DispatcherReadyListHead[Index]));
/* Update summary and select list */
Summary ^= PRIORITY_MASK(Index);
ListHead = &Prcb->DispatcherReadyListHead[Index];
NextEntry = ListHead->Flink;
do
{
/* Select a thread */
Thread = CONTAINING_RECORD(NextEntry,
KTHREAD,
WaitListEntry);
ASSERT(Thread->Priority == Index);
/* 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);
}
/* Verify priority decrement and set the new one */ASSERT((Thread->PriorityDecrement >= 0) &&
(Thread->PriorityDecrement <=
Thread->Priority));
Thread->PriorityDecrement += (THREAD_BOOST_PRIORITY -
Thread->Priority);
ASSERT((Thread->PriorityDecrement >= 0) &&
(Thread->PriorityDecrement <=
THREAD_BOOST_PRIORITY));
/* Update priority and insert into ready list */
Thread->Priority = THREAD_BOOST_PRIORITY;
Thread->Quantum = WAIT_QUANTUM_DECREMENT * 4;
KiInsertDeferredReadyList(Thread);
Count --;
}
/* Go to the next entry */
NextEntry = NextEntry->Flink;
Number--;
} while((NextEntry != ListHead) && (Number) && (Count));
}
/* Increase index */
Index++;
} while ((Summary) && (Number) && (Count));
}
/* Release the locks and dispatcher */KiReleasePrcbLock(Prcb);
KiReleaseDispatcherLock(OldIrql);
/* Update the queue index for next time */if ((Count) && (Number))
{
/* Reset the queue at index 1 */
Prcb->QueueIndex = 1;
}
else
{
/* Set the index we're in now */
Prcb->QueueIndex = Index;
}
/* Increment the CPU number for next time and normalize to CPU count */
ScanIndex++;
if (ScanIndex == KeNumberProcessors) ScanIndex = 0;
/* Return the index */
*ScanLast = ScanIndex;
}
Generated on Sun May 27 2012 06:07:52 for ReactOS by
1.7.6.1
ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.