ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

balmgr.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.