test: zeropage.c File Reference

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

# zeropage.c File Reference

`#include "mi.h"`

Go to the source code of this file.

## Defines

#define | MM_ZERO_PAGE_OBJECT 0
#define | PO_SYS_IDLE_OBJECT 1
#define | NUMBER_WAIT_OBJECTS 2

## Functions

VOID | MmZeroPageThread (VOID)

## Define Documentation

#define MM_ZERO_PAGE_OBJECT 0

| Definition at line 23 of file zeropage.c. Referenced by MmZeroPageThread().

#define NUMBER_WAIT_OBJECTS 2

| Definition at line 25 of file zeropage.c. Referenced by MmZeroPageThread().

#define PO_SYS_IDLE_OBJECT 1

| Definition at line 24 of file zeropage.c. Referenced by MmZeroPageThread().

## Function Documentation

VOID MmZeroPageThread | ( | VOID |  | ) |

Definition at line 29 of file zeropage.c.

References ASSERT, _KTHREAD::BasePriority, FALSE, _MMPFNLIST::Flink, KeBugCheckEx(), KeGetCurrentThread, KernelMode, KeSetPriorityThread(), KeWaitForMultipleObjects(), KeZeroPageFromIdleThread, LOCK_PFN_WITH_TRY, MI_GET_SECONDARY_COLOR, MI_PFN_ELEMENT, MiFindInitializationCode(), MiFreeInitializationCode(), MiInsertPageInList(), MiMapPageToZeroInHyperSpace(), MiRemoveAnyPage(), MM_EMPTY_LIST, MM_ZERO_PAGE_OBJECT, MmFreePageListHead, MmPageLocationList, MmZeroingPageEvent, MmZeroingPageThreadActive, NTSTATUS(), NULL, NUMBER_WAIT_OBJECTS, PAGE_SHIFT, PAGE_SIZE, PO_SYS_IDLE_OBJECT, PoSystemIdleTimer, PoSystemIdleWorker(), Status, _MMPFNLIST::Total, TRUE, _MMPFN::u3, UNLOCK_PFN, WrFreePage, and ZeroedPageList.

    00035                    :
    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 }
    }