Skip to content

Commit 05d3392

Browse files
author
Sir Richard
committed
[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
1 parent 6ef3285 commit 05d3392

File tree

9 files changed

+115
-86
lines changed

9 files changed

+115
-86
lines changed

reactos/ntoskrnl/ex/init.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1951,5 +1951,5 @@ Phase1Initialization(IN PVOID Context)
19511951
Phase1InitializationDiscard(Context);
19521952

19531953
/* Jump into zero page thread */
1954-
MmZeroPageThreadMain(NULL);
1954+
MmZeroPageThread();
19551955
}

reactos/ntoskrnl/include/internal/mm.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,10 +1164,10 @@ MmGetContinuousPages(
11641164
BOOLEAN ZeroPages
11651165
);
11661166

1167-
NTSTATUS
1167+
VOID
11681168
NTAPI
1169-
MmZeroPageThreadMain(
1170-
PVOID Context
1169+
MmZeroPageThread(
1170+
VOID
11711171
);
11721172

11731173
/* hypermap.c *****************************************************************/

reactos/ntoskrnl/mm/ARM3/i386/init.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,6 @@ MiComputeNonPagedPoolVa(IN ULONG FreePages)
145145
}
146146
}
147147

148-
extern KEVENT ZeroPageThreadEvent;
149-
150148
NTSTATUS
151149
NTAPI
152150
MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
@@ -496,10 +494,7 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
496494

497495
/* Initialize the color tables */
498496
MiInitializeColorTables();
499-
500-
/* ReactOS Stuff */
501-
KeInitializeEvent(&ZeroPageThreadEvent, NotificationEvent, TRUE);
502-
497+
503498
/* Build the PFN Database */
504499
MiInitializePfnDatabase(LoaderBlock);
505500
MmInitializeBalancer(MmAvailablePages, 0);

reactos/ntoskrnl/mm/ARM3/miarm.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,8 @@ extern PMMPDE MiHighestUserPde;
439439
extern PFN_NUMBER MmSystemPageDirectory[PD_COUNT];
440440
extern PMMPTE MmSharedUserDataPte;
441441
extern LIST_ENTRY MmProcessList;
442+
extern BOOLEAN MmZeroingPageThreadActive;
443+
extern KEVENT MmZeroingPageEvent;
442444

443445
#define MI_PFN_TO_PFNENTRY(x) (&MmPfnDatabase[1][x])
444446
#define MI_PFNENTRY_TO_PFN(x) (x - MmPfnDatabase[1])

reactos/ntoskrnl/mm/ARM3/mminit.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1811,7 +1811,11 @@ MmArmInitSystem(IN ULONG Phase,
18111811

18121812
/* Initialize the Loader Lock */
18131813
KeInitializeMutant(&MmSystemLoadLock, FALSE);
1814-
1814+
1815+
/* Set the zero page event */
1816+
KeInitializeEvent(&MmZeroingPageEvent, SynchronizationEvent, FALSE);
1817+
MmZeroingPageThreadActive = FALSE;
1818+
18151819
//
18161820
// Count physical pages on the system
18171821
//

reactos/ntoskrnl/mm/ARM3/pfnlist.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -397,8 +397,6 @@ MiRemoveZeroPage(IN ULONG Color)
397397
return PageIndex;
398398
}
399399

400-
extern KEVENT ZeroPageThreadEvent;
401-
402400
VOID
403401
NTAPI
404402
MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
@@ -507,10 +505,11 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
507505
#endif
508506

509507
/* Notify zero page thread if enough pages are on the free list now */
510-
if ((MmFreePageListHead.Total > 8) && !(KeReadStateEvent(&ZeroPageThreadEvent)))
508+
if ((ListHead->Total >= 8) && !(MmZeroingPageThreadActive))
511509
{
512-
/* This is ReactOS-specific */
513-
KeSetEvent(&ZeroPageThreadEvent, IO_NO_INCREMENT, FALSE);
510+
/* Set the event */
511+
MmZeroingPageThreadActive = TRUE;
512+
KeSetEvent(&MmZeroingPageEvent, IO_NO_INCREMENT, FALSE);
514513
}
515514
}
516515

reactos/ntoskrnl/mm/ARM3/zeropage.c

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
* PROJECT: ReactOS Kernel
3+
* LICENSE: BSD - See COPYING.ARM in the top level directory
4+
* FILE: ntoskrnl/mm/ARM3/zeropage.c
5+
* PURPOSE: ARM Memory Manager Zero Page Thread Support
6+
* PROGRAMMERS: ReactOS Portable Systems Group
7+
*/
8+
9+
/* INCLUDES *******************************************************************/
10+
11+
#include <ntoskrnl.h>
12+
#define NDEBUG
13+
#include <debug.h>
14+
15+
#line 15 "ARM³::ZEROPAGE"
16+
#define MODULE_INVOLVED_IN_ARM3
17+
#include "../ARM3/miarm.h"
18+
19+
/* GLOBALS ********************************************************************/
20+
21+
BOOLEAN MmZeroingPageThreadActive;
22+
KEVENT MmZeroingPageEvent;
23+
24+
/* PRIVATE FUNCTIONS **********************************************************/
25+
26+
VOID
27+
NTAPI
28+
MmZeroPageThread(VOID)
29+
{
30+
PKTHREAD Thread = KeGetCurrentThread();
31+
//PVOID StartAddress, EndAddress;
32+
PVOID WaitObjects[2];
33+
NTSTATUS Status;
34+
KIRQL OldIrql;
35+
PVOID ZeroAddress;
36+
PFN_NUMBER PageIndex, FreePage;
37+
PMMPFN Pfn1;
38+
39+
/* FIXME: Get the discardable sections to free them */
40+
// MiFindInitializationCode(&StartAddress, &EndAddress);
41+
// if (StartAddress) MiFreeInitializationCode(StartAddress, EndAddress);
42+
43+
/* Set our priority to 0 */
44+
Thread->BasePriority = 0;
45+
KeSetPriorityThread(Thread, 0);
46+
47+
/* Setup the wait objects */
48+
WaitObjects[0] = &MmZeroingPageEvent;
49+
// WaitObjects[1] = &PoSystemIdleTimer; FIXME: Implement idle timer
50+
51+
while (TRUE)
52+
{
53+
Status = KeWaitForMultipleObjects(1, // 2
54+
WaitObjects,
55+
WaitAny,
56+
WrFreePage,
57+
KernelMode,
58+
FALSE,
59+
NULL,
60+
NULL);
61+
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
62+
while (TRUE)
63+
{
64+
if (!MmFreePageListHead.Total)
65+
{
66+
MmZeroingPageThreadActive = FALSE;
67+
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
68+
break;
69+
}
70+
71+
PageIndex = MmFreePageListHead.Flink;
72+
Pfn1 = MiGetPfnEntry(PageIndex);
73+
FreePage = MiRemoveAnyPage(0); // FIXME: Use real color
74+
if (FreePage != PageIndex)
75+
{
76+
KeBugCheckEx(PFN_LIST_CORRUPT,
77+
0x8F,
78+
FreePage,
79+
PageIndex,
80+
0);
81+
}
82+
83+
Pfn1->u1.Flink = LIST_HEAD;
84+
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
85+
86+
ZeroAddress = MiMapPagesToZeroInHyperSpace(Pfn1, 1);
87+
ASSERT(ZeroAddress);
88+
RtlZeroMemory(ZeroAddress, PAGE_SIZE);
89+
MiUnmapPagesInZeroSpace(ZeroAddress, 1);
90+
91+
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
92+
93+
MiInsertPageInList(&MmZeroedPageListHead, PageIndex);
94+
}
95+
}
96+
}
97+
98+
/* EOF */

reactos/ntoskrnl/mm/freelist.c

Lines changed: 0 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,6 @@ SIZE_T MmPagedPoolCommit;
4848
SIZE_T MmPeakCommitment;
4949
SIZE_T MmtotalCommitLimitMaximum;
5050

51-
KEVENT ZeroPageThreadEvent;
52-
static BOOLEAN ZeroPageThreadShouldTerminate = FALSE;
5351
static RTL_BITMAP MiUserPfnBitMap;
5452

5553
/* FUNCTIONS *************************************************************/
@@ -625,72 +623,4 @@ MmAllocPage(ULONG Type)
625623
return PfnOffset;
626624
}
627625

628-
NTSTATUS
629-
NTAPI
630-
MmZeroPageThreadMain(PVOID Ignored)
631-
{
632-
NTSTATUS Status;
633-
KIRQL oldIrql;
634-
PMMPFN Pfn1;
635-
PFN_NUMBER PageIndex, FreePage;
636-
ULONG Count;
637-
PVOID ZeroAddress;
638-
639-
/* Free initial kernel memory */
640-
//MiFreeInitMemory();
641-
642-
/* Set our priority to 0 */
643-
KeGetCurrentThread()->BasePriority = 0;
644-
KeSetPriorityThread(KeGetCurrentThread(), 0);
645-
646-
while(1)
647-
{
648-
Status = KeWaitForSingleObject(&ZeroPageThreadEvent,
649-
0,
650-
KernelMode,
651-
FALSE,
652-
NULL);
653-
654-
if (ZeroPageThreadShouldTerminate)
655-
{
656-
DPRINT1("ZeroPageThread: Terminating\n");
657-
return STATUS_SUCCESS;
658-
}
659-
Count = 0;
660-
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
661-
while (MmFreePageListHead.Total)
662-
{
663-
PageIndex = MmFreePageListHead.Flink;
664-
Pfn1 = MiGetPfnEntry(PageIndex);
665-
FreePage = MiRemoveAnyPage(0); // FIXME: Use real color
666-
if (FreePage != PageIndex)
667-
{
668-
KeBugCheckEx(PFN_LIST_CORRUPT,
669-
0x8F,
670-
FreePage,
671-
PageIndex,
672-
0);
673-
}
674-
675-
Pfn1->u1.Flink = LIST_HEAD;
676-
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
677-
678-
ZeroAddress = MiMapPagesToZeroInHyperSpace(Pfn1, 1);
679-
ASSERT(ZeroAddress);
680-
RtlZeroMemory(ZeroAddress, PAGE_SIZE);
681-
MiUnmapPagesInZeroSpace(ZeroAddress, 1);
682-
683-
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
684-
685-
MiInsertPageInList(&MmZeroedPageListHead, PageIndex);
686-
Count++;
687-
}
688-
DPRINT("Zeroed %d pages.\n", Count);
689-
KeResetEvent(&ZeroPageThreadEvent);
690-
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
691-
}
692-
693-
return STATUS_SUCCESS;
694-
}
695-
696626
/* EOF */

reactos/ntoskrnl/ntoskrnl-generic.rbuild

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,7 @@
463463
<file>syspte.c</file>
464464
<file>vadnode.c</file>
465465
<file>virtual.c</file>
466+
<file>zeropage.c</file>
466467
</directory>
467468
<file>anonmem.c</file>
468469
<file>balance.c</file>

0 commit comments

Comments
 (0)