mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 19:12:57 +00:00
[NTOS]: Switch to using an ARM3, much more correct MmZeroPageThread. Stub support for discarding sections and listening to the Power Manager Idle Timer.
[NTOS]: Use a synchronization (auto-reset) instead of notification event for the zero page thread, this way we don't have to reset it manually and query its state. Instead, a boolean MmZeroingPageThreadActive is checked instead. [NTOS]: Once we switch to colored lists, major improvements can be done for speed. svn path=/trunk/; revision=48922
This commit is contained in:
parent
6ef328578c
commit
05d3392da9
9 changed files with 115 additions and 86 deletions
|
@ -1951,5 +1951,5 @@ Phase1Initialization(IN PVOID Context)
|
||||||
Phase1InitializationDiscard(Context);
|
Phase1InitializationDiscard(Context);
|
||||||
|
|
||||||
/* Jump into zero page thread */
|
/* Jump into zero page thread */
|
||||||
MmZeroPageThreadMain(NULL);
|
MmZeroPageThread();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1164,10 +1164,10 @@ MmGetContinuousPages(
|
||||||
BOOLEAN ZeroPages
|
BOOLEAN ZeroPages
|
||||||
);
|
);
|
||||||
|
|
||||||
NTSTATUS
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
MmZeroPageThreadMain(
|
MmZeroPageThread(
|
||||||
PVOID Context
|
VOID
|
||||||
);
|
);
|
||||||
|
|
||||||
/* hypermap.c *****************************************************************/
|
/* hypermap.c *****************************************************************/
|
||||||
|
|
|
@ -145,8 +145,6 @@ MiComputeNonPagedPoolVa(IN ULONG FreePages)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern KEVENT ZeroPageThreadEvent;
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||||
|
@ -496,10 +494,7 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||||
|
|
||||||
/* Initialize the color tables */
|
/* Initialize the color tables */
|
||||||
MiInitializeColorTables();
|
MiInitializeColorTables();
|
||||||
|
|
||||||
/* ReactOS Stuff */
|
|
||||||
KeInitializeEvent(&ZeroPageThreadEvent, NotificationEvent, TRUE);
|
|
||||||
|
|
||||||
/* Build the PFN Database */
|
/* Build the PFN Database */
|
||||||
MiInitializePfnDatabase(LoaderBlock);
|
MiInitializePfnDatabase(LoaderBlock);
|
||||||
MmInitializeBalancer(MmAvailablePages, 0);
|
MmInitializeBalancer(MmAvailablePages, 0);
|
||||||
|
|
|
@ -439,6 +439,8 @@ extern PMMPDE MiHighestUserPde;
|
||||||
extern PFN_NUMBER MmSystemPageDirectory[PD_COUNT];
|
extern PFN_NUMBER MmSystemPageDirectory[PD_COUNT];
|
||||||
extern PMMPTE MmSharedUserDataPte;
|
extern PMMPTE MmSharedUserDataPte;
|
||||||
extern LIST_ENTRY MmProcessList;
|
extern LIST_ENTRY MmProcessList;
|
||||||
|
extern BOOLEAN MmZeroingPageThreadActive;
|
||||||
|
extern KEVENT MmZeroingPageEvent;
|
||||||
|
|
||||||
#define MI_PFN_TO_PFNENTRY(x) (&MmPfnDatabase[1][x])
|
#define MI_PFN_TO_PFNENTRY(x) (&MmPfnDatabase[1][x])
|
||||||
#define MI_PFNENTRY_TO_PFN(x) (x - MmPfnDatabase[1])
|
#define MI_PFNENTRY_TO_PFN(x) (x - MmPfnDatabase[1])
|
||||||
|
|
|
@ -1811,7 +1811,11 @@ MmArmInitSystem(IN ULONG Phase,
|
||||||
|
|
||||||
/* Initialize the Loader Lock */
|
/* Initialize the Loader Lock */
|
||||||
KeInitializeMutant(&MmSystemLoadLock, FALSE);
|
KeInitializeMutant(&MmSystemLoadLock, FALSE);
|
||||||
|
|
||||||
|
/* Set the zero page event */
|
||||||
|
KeInitializeEvent(&MmZeroingPageEvent, SynchronizationEvent, FALSE);
|
||||||
|
MmZeroingPageThreadActive = FALSE;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Count physical pages on the system
|
// Count physical pages on the system
|
||||||
//
|
//
|
||||||
|
|
|
@ -397,8 +397,6 @@ MiRemoveZeroPage(IN ULONG Color)
|
||||||
return PageIndex;
|
return PageIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern KEVENT ZeroPageThreadEvent;
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
|
MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
|
||||||
|
@ -507,10 +505,11 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Notify zero page thread if enough pages are on the free list now */
|
/* Notify zero page thread if enough pages are on the free list now */
|
||||||
if ((MmFreePageListHead.Total > 8) && !(KeReadStateEvent(&ZeroPageThreadEvent)))
|
if ((ListHead->Total >= 8) && !(MmZeroingPageThreadActive))
|
||||||
{
|
{
|
||||||
/* This is ReactOS-specific */
|
/* Set the event */
|
||||||
KeSetEvent(&ZeroPageThreadEvent, IO_NO_INCREMENT, FALSE);
|
MmZeroingPageThreadActive = TRUE;
|
||||||
|
KeSetEvent(&MmZeroingPageEvent, IO_NO_INCREMENT, FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
98
reactos/ntoskrnl/mm/ARM3/zeropage.c
Normal file
98
reactos/ntoskrnl/mm/ARM3/zeropage.c
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS Kernel
|
||||||
|
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
||||||
|
* FILE: ntoskrnl/mm/ARM3/zeropage.c
|
||||||
|
* PURPOSE: ARM Memory Manager Zero Page Thread Support
|
||||||
|
* PROGRAMMERS: ReactOS Portable Systems Group
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES *******************************************************************/
|
||||||
|
|
||||||
|
#include <ntoskrnl.h>
|
||||||
|
#define NDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
#line 15 "ARM³::ZEROPAGE"
|
||||||
|
#define MODULE_INVOLVED_IN_ARM3
|
||||||
|
#include "../ARM3/miarm.h"
|
||||||
|
|
||||||
|
/* GLOBALS ********************************************************************/
|
||||||
|
|
||||||
|
BOOLEAN MmZeroingPageThreadActive;
|
||||||
|
KEVENT MmZeroingPageEvent;
|
||||||
|
|
||||||
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
MmZeroPageThread(VOID)
|
||||||
|
{
|
||||||
|
PKTHREAD Thread = KeGetCurrentThread();
|
||||||
|
//PVOID StartAddress, EndAddress;
|
||||||
|
PVOID WaitObjects[2];
|
||||||
|
NTSTATUS Status;
|
||||||
|
KIRQL OldIrql;
|
||||||
|
PVOID ZeroAddress;
|
||||||
|
PFN_NUMBER PageIndex, FreePage;
|
||||||
|
PMMPFN Pfn1;
|
||||||
|
|
||||||
|
/* FIXME: Get the discardable sections to free them */
|
||||||
|
// MiFindInitializationCode(&StartAddress, &EndAddress);
|
||||||
|
// if (StartAddress) MiFreeInitializationCode(StartAddress, EndAddress);
|
||||||
|
|
||||||
|
/* Set our priority to 0 */
|
||||||
|
Thread->BasePriority = 0;
|
||||||
|
KeSetPriorityThread(Thread, 0);
|
||||||
|
|
||||||
|
/* Setup the wait objects */
|
||||||
|
WaitObjects[0] = &MmZeroingPageEvent;
|
||||||
|
// WaitObjects[1] = &PoSystemIdleTimer; FIXME: Implement idle timer
|
||||||
|
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
Status = KeWaitForMultipleObjects(1, // 2
|
||||||
|
WaitObjects,
|
||||||
|
WaitAny,
|
||||||
|
WrFreePage,
|
||||||
|
KernelMode,
|
||||||
|
FALSE,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
if (!MmFreePageListHead.Total)
|
||||||
|
{
|
||||||
|
MmZeroingPageThreadActive = FALSE;
|
||||||
|
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
PageIndex = MmFreePageListHead.Flink;
|
||||||
|
Pfn1 = MiGetPfnEntry(PageIndex);
|
||||||
|
FreePage = MiRemoveAnyPage(0); // FIXME: Use real color
|
||||||
|
if (FreePage != PageIndex)
|
||||||
|
{
|
||||||
|
KeBugCheckEx(PFN_LIST_CORRUPT,
|
||||||
|
0x8F,
|
||||||
|
FreePage,
|
||||||
|
PageIndex,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Pfn1->u1.Flink = LIST_HEAD;
|
||||||
|
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
|
||||||
|
|
||||||
|
ZeroAddress = MiMapPagesToZeroInHyperSpace(Pfn1, 1);
|
||||||
|
ASSERT(ZeroAddress);
|
||||||
|
RtlZeroMemory(ZeroAddress, PAGE_SIZE);
|
||||||
|
MiUnmapPagesInZeroSpace(ZeroAddress, 1);
|
||||||
|
|
||||||
|
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
|
||||||
|
|
||||||
|
MiInsertPageInList(&MmZeroedPageListHead, PageIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EOF */
|
|
@ -48,8 +48,6 @@ SIZE_T MmPagedPoolCommit;
|
||||||
SIZE_T MmPeakCommitment;
|
SIZE_T MmPeakCommitment;
|
||||||
SIZE_T MmtotalCommitLimitMaximum;
|
SIZE_T MmtotalCommitLimitMaximum;
|
||||||
|
|
||||||
KEVENT ZeroPageThreadEvent;
|
|
||||||
static BOOLEAN ZeroPageThreadShouldTerminate = FALSE;
|
|
||||||
static RTL_BITMAP MiUserPfnBitMap;
|
static RTL_BITMAP MiUserPfnBitMap;
|
||||||
|
|
||||||
/* FUNCTIONS *************************************************************/
|
/* FUNCTIONS *************************************************************/
|
||||||
|
@ -625,72 +623,4 @@ MmAllocPage(ULONG Type)
|
||||||
return PfnOffset;
|
return PfnOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
NTAPI
|
|
||||||
MmZeroPageThreadMain(PVOID Ignored)
|
|
||||||
{
|
|
||||||
NTSTATUS Status;
|
|
||||||
KIRQL oldIrql;
|
|
||||||
PMMPFN Pfn1;
|
|
||||||
PFN_NUMBER PageIndex, FreePage;
|
|
||||||
ULONG Count;
|
|
||||||
PVOID ZeroAddress;
|
|
||||||
|
|
||||||
/* Free initial kernel memory */
|
|
||||||
//MiFreeInitMemory();
|
|
||||||
|
|
||||||
/* Set our priority to 0 */
|
|
||||||
KeGetCurrentThread()->BasePriority = 0;
|
|
||||||
KeSetPriorityThread(KeGetCurrentThread(), 0);
|
|
||||||
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
Status = KeWaitForSingleObject(&ZeroPageThreadEvent,
|
|
||||||
0,
|
|
||||||
KernelMode,
|
|
||||||
FALSE,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (ZeroPageThreadShouldTerminate)
|
|
||||||
{
|
|
||||||
DPRINT1("ZeroPageThread: Terminating\n");
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
Count = 0;
|
|
||||||
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
|
|
||||||
while (MmFreePageListHead.Total)
|
|
||||||
{
|
|
||||||
PageIndex = MmFreePageListHead.Flink;
|
|
||||||
Pfn1 = MiGetPfnEntry(PageIndex);
|
|
||||||
FreePage = MiRemoveAnyPage(0); // FIXME: Use real color
|
|
||||||
if (FreePage != PageIndex)
|
|
||||||
{
|
|
||||||
KeBugCheckEx(PFN_LIST_CORRUPT,
|
|
||||||
0x8F,
|
|
||||||
FreePage,
|
|
||||||
PageIndex,
|
|
||||||
0);
|
|
||||||
}
|
|
||||||
|
|
||||||
Pfn1->u1.Flink = LIST_HEAD;
|
|
||||||
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
|
|
||||||
|
|
||||||
ZeroAddress = MiMapPagesToZeroInHyperSpace(Pfn1, 1);
|
|
||||||
ASSERT(ZeroAddress);
|
|
||||||
RtlZeroMemory(ZeroAddress, PAGE_SIZE);
|
|
||||||
MiUnmapPagesInZeroSpace(ZeroAddress, 1);
|
|
||||||
|
|
||||||
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
|
|
||||||
|
|
||||||
MiInsertPageInList(&MmZeroedPageListHead, PageIndex);
|
|
||||||
Count++;
|
|
||||||
}
|
|
||||||
DPRINT("Zeroed %d pages.\n", Count);
|
|
||||||
KeResetEvent(&ZeroPageThreadEvent);
|
|
||||||
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
|
|
||||||
}
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -463,6 +463,7 @@
|
||||||
<file>syspte.c</file>
|
<file>syspte.c</file>
|
||||||
<file>vadnode.c</file>
|
<file>vadnode.c</file>
|
||||||
<file>virtual.c</file>
|
<file>virtual.c</file>
|
||||||
|
<file>zeropage.c</file>
|
||||||
</directory>
|
</directory>
|
||||||
<file>anonmem.c</file>
|
<file>anonmem.c</file>
|
||||||
<file>balance.c</file>
|
<file>balance.c</file>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue