Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenbalmgr.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS Kernel 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: ntoskrnl/ke/balmgr.c 00005 * PURPOSE: Balance Set Manager 00006 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) 00007 */ 00008 00009 /* INCLUDES ******************************************************************/ 00010 00011 #include <ntoskrnl.h> 00012 #define NDEBUG 00013 #include <debug.h> 00014 00015 /* GLOBALS *******************************************************************/ 00016 00017 #define THREAD_BOOST_PRIORITY (LOW_REALTIME_PRIORITY - 1) 00018 ULONG KiReadyScanLast; 00019 00020 /* PRIVATE FUNCTIONS *********************************************************/ 00021 00022 VOID 00023 NTAPI 00024 KiScanReadyQueues(IN PKDPC Dpc, 00025 IN PVOID DeferredContext, 00026 IN PVOID SystemArgument1, 00027 IN PVOID SystemArgument2) 00028 { 00029 PULONG ScanLast = DeferredContext; 00030 ULONG ScanIndex = *ScanLast; 00031 ULONG Count = 10, Number = 16; 00032 PKPRCB Prcb = KiProcessorBlock[ScanIndex]; 00033 ULONG Index = Prcb->QueueIndex; 00034 ULONG WaitLimit = KeTickCount.LowPart - 300; 00035 ULONG Summary; 00036 KIRQL OldIrql; 00037 PLIST_ENTRY ListHead, NextEntry; 00038 PKTHREAD Thread; 00039 00040 /* Lock the dispatcher and PRCB */ 00041 OldIrql = KiAcquireDispatcherLock(); 00042 KiAcquirePrcbLock(Prcb); 00043 /* Check if there's any thread that need help */ 00044 Summary = Prcb->ReadySummary & ((1 << THREAD_BOOST_PRIORITY) - 2); 00045 if (Summary) 00046 { 00047 /* Start scan loop */ 00048 do 00049 { 00050 /* Normalize the index */ 00051 if (Index > (THREAD_BOOST_PRIORITY - 1)) Index = 1; 00052 00053 /* Loop for ready threads */ 00054 if (Summary & PRIORITY_MASK(Index)) 00055 { 00056 /* Sanity check */ 00057 ASSERT(!IsListEmpty(&Prcb->DispatcherReadyListHead[Index])); 00058 00059 /* Update summary and select list */ 00060 Summary ^= PRIORITY_MASK(Index); 00061 ListHead = &Prcb->DispatcherReadyListHead[Index]; 00062 NextEntry = ListHead->Flink; 00063 do 00064 { 00065 /* Select a thread */ 00066 Thread = CONTAINING_RECORD(NextEntry, 00067 KTHREAD, 00068 WaitListEntry); 00069 ASSERT(Thread->Priority == Index); 00070 00071 /* Check if the thread has been waiting too long */ 00072 if (WaitLimit >= Thread->WaitTime) 00073 { 00074 /* Remove the thread from the queue */ 00075 NextEntry = NextEntry->Blink; 00076 ASSERT((Prcb->ReadySummary & PRIORITY_MASK(Index))); 00077 if (RemoveEntryList(NextEntry->Flink)) 00078 { 00079 /* The list is empty now */ 00080 Prcb->ReadySummary ^= PRIORITY_MASK(Index); 00081 } 00082 00083 /* Verify priority decrement and set the new one */ 00084 ASSERT((Thread->PriorityDecrement >= 0) && 00085 (Thread->PriorityDecrement <= 00086 Thread->Priority)); 00087 Thread->PriorityDecrement += (THREAD_BOOST_PRIORITY - 00088 Thread->Priority); 00089 ASSERT((Thread->PriorityDecrement >= 0) && 00090 (Thread->PriorityDecrement <= 00091 THREAD_BOOST_PRIORITY)); 00092 00093 /* Update priority and insert into ready list */ 00094 Thread->Priority = THREAD_BOOST_PRIORITY; 00095 Thread->Quantum = WAIT_QUANTUM_DECREMENT * 4; 00096 KiInsertDeferredReadyList(Thread); 00097 Count --; 00098 } 00099 00100 /* Go to the next entry */ 00101 NextEntry = NextEntry->Flink; 00102 Number--; 00103 } while((NextEntry != ListHead) && (Number) && (Count)); 00104 } 00105 00106 /* Increase index */ 00107 Index++; 00108 } while ((Summary) && (Number) && (Count)); 00109 } 00110 00111 /* Release the locks and dispatcher */ 00112 KiReleasePrcbLock(Prcb); 00113 KiReleaseDispatcherLock(OldIrql); 00114 00115 /* Update the queue index for next time */ 00116 if ((Count) && (Number)) 00117 { 00118 /* Reset the queue at index 1 */ 00119 Prcb->QueueIndex = 1; 00120 } 00121 else 00122 { 00123 /* Set the index we're in now */ 00124 Prcb->QueueIndex = Index; 00125 } 00126 00127 /* Increment the CPU number for next time and normalize to CPU count */ 00128 ScanIndex++; 00129 if (ScanIndex == KeNumberProcessors) ScanIndex = 0; 00130 00131 /* Return the index */ 00132 *ScanLast = ScanIndex; 00133 } 00134 00135 VOID 00136 NTAPI 00137 KeBalanceSetManager(IN PVOID Context) 00138 { 00139 KDPC ScanDpc; 00140 KTIMER PeriodTimer; 00141 LARGE_INTEGER DueTime; 00142 KWAIT_BLOCK WaitBlockArray[1]; 00143 PVOID WaitObjects[1]; 00144 NTSTATUS Status; 00145 00146 /* Set us at a low real-time priority level */ 00147 KeSetPriorityThread(KeGetCurrentThread(), LOW_REALTIME_PRIORITY); 00148 00149 /* Setup the timer and scanner DPC */ 00150 KeInitializeTimerEx(&PeriodTimer, SynchronizationTimer); 00151 KeInitializeDpc(&ScanDpc, KiScanReadyQueues, &KiReadyScanLast); 00152 00153 /* Setup the periodic timer */ 00154 DueTime.QuadPart = -1 * 10 * 1000 * 1000; 00155 KeSetTimerEx(&PeriodTimer, DueTime, 1000, &ScanDpc); 00156 00157 /* Setup the wait objects */ 00158 WaitObjects[0] = &PeriodTimer; 00159 //WaitObjects[1] = MmWorkingSetManagerEvent; // NO WS Management Yet! 00160 00161 /* Start wait loop */ 00162 do 00163 { 00164 /* Wait on our objects */ 00165 Status = KeWaitForMultipleObjects(1, 00166 WaitObjects, 00167 WaitAny, 00168 Executive, 00169 KernelMode, 00170 FALSE, 00171 NULL, 00172 WaitBlockArray); 00173 switch (Status) 00174 { 00175 /* Check if our timer expired */ 00176 case STATUS_WAIT_0: 00177 00178 /* Adjust lookaside lists */ 00179 //ExAdjustLookasideDepth(); 00180 00181 /* Call the working set manager */ 00182 //MmWorkingSetManager(); 00183 00184 /* FIXME: Outswap stacks */ 00185 00186 /* Done */ 00187 break; 00188 00189 /* Check if the working set manager notified us */ 00190 case STATUS_WAIT_1: 00191 00192 /* Call the working set manager */ 00193 //MmWorkingSetManager(); 00194 break; 00195 00196 /* Anything else */ 00197 default: 00198 DPRINT1("BALMGR: Illegal wait status, %lx =\n", Status); 00199 break; 00200 } 00201 } while (TRUE); 00202 } Generated on Sun May 27 2012 04:37:31 for ReactOS by
1.7.6.1
|