balmgr.c MS and ReactOS

Created Diff never expires
178 Entfernungen
Zeilen
Gesamt
Entfernt
Wörter
Gesamt
Entfernt
Um diese Funktion weiterhin zu nutzen, aktualisieren Sie auf
Diffchecker logo
Diffchecker Pro
189 Zeilen
89 Hinzufügungen
Zeilen
Gesamt
Hinzugefügt
Wörter
Gesamt
Hinzugefügt
Um diese Funktion weiterhin zu nutzen, aktualisieren Sie auf
Diffchecker logo
Diffchecker Pro
114 Zeilen
NTOS Kernel
REACT OS


VOID
VOID
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;
KIRQL OldIrql;
PKPRCB Prcb;
ULONG ScanIndex;
PULONG ScanLast;
ULONG Summary;
ULONG Summary;
KIRQL OldIrql;
PLIST_ENTRY ListHead, NextEntry;
PKTHREAD Thread;
PKTHREAD Thread;
ULONG WaitLimit;

UNREFERENCED_PARAMETER(SystemArgument1);
UNREFERENCED_PARAMETER(SystemArgument2);

//
// 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;
/* Lock the dispatcher and PRCB */
Number = THREAD_SCAN_COUNT;
OldIrql = KiAcquireDispatcherLock();
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
// If the current ready queue index is beyond the end of the range
{
// of priorities that are scanned, then wrap back to the beginning
/* Normalize the index */
// priority.
if (Index > (THREAD_BOOST_PRIORITY - 1)) Index = 1;
//

if (Index > THREAD_SCAN_PRIORITY) {
Index = 1;
}

//
// 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);
/* 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);
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;
}
}