- Update to trunk
[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 DPRINT1("Free non-cache pages: %lx\n", MmAvailablePages + MiMemoryConsumers[MC_CACHE].PagesUsed);
43
44 /* Set our priority to 0 */
45 Thread->BasePriority = 0;
46 KeSetPriorityThread(Thread, 0);
47
48 /* Setup the wait objects */
49 WaitObjects[0] = &MmZeroingPageEvent;
50 // WaitObjects[1] = &PoSystemIdleTimer; FIXME: Implement idle timer
51
52 while (TRUE)
53 {
54 Status = KeWaitForMultipleObjects(1, // 2
55 WaitObjects,
56 WaitAny,
57 WrFreePage,
58 KernelMode,
59 FALSE,
60 NULL,
61 NULL);
62 OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
63 while (TRUE)
64 {
65 if (!MmFreePageListHead.Total)
66 {
67 MmZeroingPageThreadActive = FALSE;
68 KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
69 break;
70 }
71
72 PageIndex = MmFreePageListHead.Flink;
73 ASSERT(PageIndex != LIST_HEAD);
74 Pfn1 = MiGetPfnEntry(PageIndex);
75 MI_SET_USAGE(MI_USAGE_ZERO_LOOP);
76 MI_SET_PROCESS2("Kernel 0 Loop");
77 FreePage = MiRemoveAnyPage(MI_GET_PAGE_COLOR(PageIndex));
78
79 /* The first global free page should also be the first on its own list */
80 if (FreePage != PageIndex)
81 {
82 KeBugCheckEx(PFN_LIST_CORRUPT,
83 0x8F,
84 FreePage,
85 PageIndex,
86 0);
87 }
88
89 Pfn1->u1.Flink = LIST_HEAD;
90 KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
91
92 ZeroAddress = MiMapPagesToZeroInHyperSpace(Pfn1, 1);
93 ASSERT(ZeroAddress);
94 RtlZeroMemory(ZeroAddress, PAGE_SIZE);
95 MiUnmapPagesInZeroSpace(ZeroAddress, 1);
96
97 OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
98
99 MiInsertPageInList(&MmZeroedPageListHead, PageIndex);
100 }
101 }
102 }
103
104 /* EOF */