Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

zeropage.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1989 Microsoft Corporation 00004 00005 Module Name: 00006 00007 zeropage.c 00008 00009 Abstract: 00010 00011 This module contains the zero page thread for memory management. 00012 00013 Author: 00014 00015 Lou Perazzoli (loup) 6-Apr-1991 00016 00017 Revision History: 00018 00019 --*/ 00020 00021 #include "mi.h" 00022 00023 #define MM_ZERO_PAGE_OBJECT 0 00024 #define PO_SYS_IDLE_OBJECT 1 00025 #define NUMBER_WAIT_OBJECTS 2 00026 00027 00028 VOID 00029 MmZeroPageThread ( 00030 VOID 00031 ) 00032 00033 /*++ 00034 00035 Routine Description: 00036 00037 Implements the NT zeroing page thread. This thread runs 00038 at priority zero and removes a page from the free list, 00039 zeroes it, and places it on the zeroed page list. 00040 00041 Arguments: 00042 00043 StartContext - not used. 00044 00045 Return Value: 00046 00047 None. 00048 00049 Environment: 00050 00051 Kernel mode. 00052 00053 --*/ 00054 00055 { 00056 PVOID EndVa; 00057 KIRQL OldIrql; 00058 PFN_NUMBER PageFrame; 00059 PMMPFN Pfn1; 00060 PVOID StartVa; 00061 PKTHREAD Thread; 00062 PVOID ZeroBase; 00063 PFN_NUMBER NewPage; 00064 PVOID WaitObjects[NUMBER_WAIT_OBJECTS]; 00065 NTSTATUS Status; 00066 00067 // 00068 // Before this becomes the zero page thread, free the kernel 00069 // initialization code. 00070 // 00071 00072 #if !defined(_IA64_) 00073 MiFindInitializationCode (&StartVa, &EndVa); 00074 if (StartVa != NULL) { 00075 MiFreeInitializationCode (StartVa, EndVa); 00076 } 00077 #endif 00078 00079 // 00080 // The following code sets the current thread's base priority to zero 00081 // and then sets its current priority to zero. This ensures that the 00082 // thread always runs at a priority of zero. 00083 // 00084 00085 Thread = KeGetCurrentThread(); 00086 Thread->BasePriority = 0; 00087 KeSetPriorityThread (Thread, 0); 00088 00089 // 00090 // Initialize wait object array for multiple wait 00091 // 00092 00093 WaitObjects[MM_ZERO_PAGE_OBJECT] = &MmZeroingPageEvent; 00094 WaitObjects[PO_SYS_IDLE_OBJECT] = &PoSystemIdleTimer; 00095 00096 // 00097 // Loop forever zeroing pages. 00098 // 00099 00100 do { 00101 00102 // 00103 // Wait until there are at least MmZeroPageMinimum pages 00104 // on the free list. 00105 // 00106 00107 Status = KeWaitForMultipleObjects (NUMBER_WAIT_OBJECTS, 00108 WaitObjects, 00109 WaitAny, 00110 WrFreePage, 00111 KernelMode, 00112 FALSE, 00113 (PLARGE_INTEGER) NULL, 00114 (PKWAIT_BLOCK) NULL 00115 ); 00116 00117 if (Status == PO_SYS_IDLE_OBJECT) { 00118 PoSystemIdleWorker (TRUE); 00119 continue; 00120 } 00121 00122 LOCK_PFN_WITH_TRY (OldIrql); 00123 do { 00124 if ((volatile)MmFreePageListHead.Total == 0) { 00125 00126 // 00127 // No pages on the free list at this time, wait for 00128 // some more. 00129 // 00130 00131 MmZeroingPageThreadActive = FALSE; 00132 UNLOCK_PFN (OldIrql); 00133 break; 00134 00135 } else { 00136 00137 PageFrame = MmFreePageListHead.Flink; 00138 Pfn1 = MI_PFN_ELEMENT(PageFrame); 00139 00140 ASSERT (PageFrame != MM_EMPTY_LIST); 00141 Pfn1 = MI_PFN_ELEMENT(PageFrame); 00142 00143 NewPage = MiRemoveAnyPage (MI_GET_SECONDARY_COLOR (PageFrame, Pfn1)); 00144 if (NewPage != PageFrame) { 00145 00146 // 00147 // Someone has removed a page from the colored lists chain 00148 // without updating the freelist chain. 00149 // 00150 00151 KeBugCheckEx (PFN_LIST_CORRUPT, 00152 0x8F, 00153 NewPage, 00154 PageFrame, 00155 0); 00156 } 00157 00158 // 00159 // Zero the page using the last color used to map the page. 00160 // 00161 00162 #if defined(_AXP64_) || defined(_X86_) || defined(_IA64_) 00163 00164 ZeroBase = MiMapPageToZeroInHyperSpace (PageFrame); 00165 UNLOCK_PFN (OldIrql); 00166 00167 #if defined(_X86_) 00168 00169 KeZeroPageFromIdleThread(ZeroBase); 00170 00171 #else //X86 00172 00173 RtlZeroMemory (ZeroBase, PAGE_SIZE); 00174 00175 #endif //X86 00176 00177 #else //AXP64||X86||IA64 00178 00179 ZeroBase = (PVOID)(Pfn1->u3.e1.PageColor << PAGE_SHIFT); 00180 UNLOCK_PFN (OldIrql); 00181 HalZeroPage(ZeroBase, ZeroBase, PageFrame); 00182 00183 #endif //AXP64||X86||IA64 00184 00185 LOCK_PFN_WITH_TRY (OldIrql); 00186 MiInsertPageInList (MmPageLocationList[ZeroedPageList], 00187 PageFrame); 00188 } 00189 } while(TRUE); 00190 } while (TRUE); 00191 }

Generated on Sat May 15 19:42:33 2004 for test by doxygen 1.3.7