[FREELDR]
[reactos.git] / ntoskrnl / mm / ARM3 / zeropage.c
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 ASSERT(PageIndex != LIST_HEAD);
73 Pfn1 = MiGetPfnEntry(PageIndex);
74 FreePage = MiRemoveAnyPage(MI_GET_PAGE_COLOR(PageIndex));
75
76 /* The first global free page should also be the first on its own list */
77 if (FreePage != PageIndex)
78 {
79 KeBugCheckEx(PFN_LIST_CORRUPT,
80 0x8F,
81 FreePage,
82 PageIndex,
83 0);
84 }
85
86 Pfn1->u1.Flink = LIST_HEAD;
87 KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
88
89 ZeroAddress = MiMapPagesToZeroInHyperSpace(Pfn1, 1);
90 ASSERT(ZeroAddress);
91 RtlZeroMemory(ZeroAddress, PAGE_SIZE);
92 MiUnmapPagesInZeroSpace(ZeroAddress, 1);
93
94 OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
95
96 MiInsertPageInList(&MmZeroedPageListHead, PageIndex);
97 }
98 }
99 }
100
101 /* EOF */