NT4/private/ntos/mm/zeropage.c
2020-09-30 17:12:29 +02:00

159 lines
3.5 KiB
C

/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
zeropage.c
Abstract:
This module contains the zero page thread for memory management.
Author:
Lou Perazzoli (loup) 6-Apr-1991
Revision History:
--*/
#include "mi.h"
VOID
MmZeroPageThread (
VOID
)
/*++
Routine Description:
Implements the NT zeroing page thread. This thread runs
at priority zero and removes a page from the free list,
zeroes it, and places it on the zeroed page list.
Arguments:
StartContext - not used.
Return Value:
None.
Environment:
Kernel mode.
--*/
{
PVOID EndVa;
KIRQL OldIrql;
ULONG PageFrame;
PMMPFN Pfn1;
PVOID StartVa;
PKTHREAD Thread;
PVOID ZeroBase;
ULONG i;
//
// Before this becomes the zero page thread, free the kernel
// initialization code.
//
MiFindInitializationCode (&StartVa, &EndVa);
if (StartVa != NULL) {
MiFreeInitializationCode (StartVa, EndVa);
}
//
// The following code sets the current thread's base priority to zero
// and then sets its current priority to zero. This ensures that the
// thread always runs at a priority of zero.
//
Thread = KeGetCurrentThread();
Thread->BasePriority = 0;
KeSetPriorityThread (Thread, 0);
//
// Loop forever zeroing pages.
//
do {
//
// Wait until there are at least MmZeroPageMinimum pages
// on the free list.
//
KeWaitForSingleObject (&MmZeroingPageEvent,
WrFreePage,
KernelMode,
FALSE,
(PLARGE_INTEGER)NULL);
LOCK_PFN_WITH_TRY (OldIrql);
do {
if ((volatile)MmFreePageListHead.Total == 0) {
//
// No pages on the free list at this time, wait for
// some more.
//
MmZeroingPageThreadActive = FALSE;
UNLOCK_PFN (OldIrql);
break;
} else {
#if MM_MAXIMUM_NUMBER_OF_COLORS > 1
for (i = 0; i < MM_MAXIMUM_NUMBER_OF_COLORS; i++) {
PageFrame = MmFreePagesByPrimaryColor[FreePageList][i].Flink;
if (PageFrame != MM_EMPTY_LIST) {
break;
}
}
#else //MM_MAXIMUM_NUMBER_OF_COLORS > 1
PageFrame = MmFreePageListHead.Flink;
#endif //MM_MAXIMUM_NUMBER_OF_COLORS > 1
Pfn1 = MI_PFN_ELEMENT(PageFrame);
ASSERT (PageFrame != MM_EMPTY_LIST);
Pfn1 = MI_PFN_ELEMENT(PageFrame);
MiRemoveAnyPage (MI_GET_SECONDARY_COLOR (PageFrame, Pfn1));
//
// Zero the page using the last color used to map the page.
//
#if defined(_X86_)
ZeroBase = MiMapPageToZeroInHyperSpace (PageFrame);
UNLOCK_PFN (OldIrql);
RtlZeroMemory (ZeroBase, PAGE_SIZE);
#elif defined(_PPC_)
UNLOCK_PFN (OldIrql);
KeZeroPage(PageFrame);
#else
ZeroBase = (PVOID)(Pfn1->u3.e1.PageColor << PAGE_SHIFT);
UNLOCK_PFN (OldIrql);
HalZeroPage(ZeroBase, ZeroBase, PageFrame);
#endif //X86
LOCK_PFN_WITH_TRY (OldIrql);
MiInsertPageInList (MmPageLocationList[ZeroedPageList],
PageFrame);
}
} while(TRUE);
} while (TRUE);
}