[NTOS:MM] Use inline functions to acquire/release the PFN lock.
[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 #define MODULE_INVOLVED_IN_ARM3
16 #include <mm/ARM3/miarm.h>
17
18 /* GLOBALS ********************************************************************/
19
20 BOOLEAN MmZeroingPageThreadActive;
21 KEVENT MmZeroingPageEvent;
22
23 /* PRIVATE FUNCTIONS **********************************************************/
24
25 VOID
26 NTAPI
27 MiFindInitializationCode(OUT PVOID *StartVa,
28 OUT PVOID *EndVa);
29
30 VOID
31 NTAPI
32 MiFreeInitializationCode(IN PVOID StartVa,
33 IN PVOID EndVa);
34
35 VOID
36 NTAPI
37 MmZeroPageThread(VOID)
38 {
39 PKTHREAD Thread = KeGetCurrentThread();
40 PVOID StartAddress, EndAddress;
41 PVOID WaitObjects[2];
42 KIRQL OldIrql;
43 PVOID ZeroAddress;
44 PFN_NUMBER PageIndex, FreePage;
45 PMMPFN Pfn1;
46
47 /* Get the discardable sections to free them */
48 MiFindInitializationCode(&StartAddress, &EndAddress);
49 if (StartAddress) MiFreeInitializationCode(StartAddress, EndAddress);
50 DPRINT("Free non-cache pages: %lx\n", MmAvailablePages + MiMemoryConsumers[MC_CACHE].PagesUsed);
51
52 /* Set our priority to 0 */
53 Thread->BasePriority = 0;
54 KeSetPriorityThread(Thread, 0);
55
56 /* Setup the wait objects */
57 WaitObjects[0] = &MmZeroingPageEvent;
58 // WaitObjects[1] = &PoSystemIdleTimer; FIXME: Implement idle timer
59
60 while (TRUE)
61 {
62 KeWaitForMultipleObjects(1, // 2
63 WaitObjects,
64 WaitAny,
65 WrFreePage,
66 KernelMode,
67 FALSE,
68 NULL,
69 NULL);
70 OldIrql = MiAcquirePfnLock();
71 MmZeroingPageThreadActive = TRUE;
72
73 while (TRUE)
74 {
75 if (!MmFreePageListHead.Total)
76 {
77 MmZeroingPageThreadActive = FALSE;
78 MiReleasePfnLock(OldIrql);
79 break;
80 }
81
82 PageIndex = MmFreePageListHead.Flink;
83 ASSERT(PageIndex != LIST_HEAD);
84 Pfn1 = MiGetPfnEntry(PageIndex);
85 MI_SET_USAGE(MI_USAGE_ZERO_LOOP);
86 MI_SET_PROCESS2("Kernel 0 Loop");
87 FreePage = MiRemoveAnyPage(MI_GET_PAGE_COLOR(PageIndex));
88
89 /* The first global free page should also be the first on its own list */
90 if (FreePage != PageIndex)
91 {
92 KeBugCheckEx(PFN_LIST_CORRUPT,
93 0x8F,
94 FreePage,
95 PageIndex,
96 0);
97 }
98
99 Pfn1->u1.Flink = LIST_HEAD;
100 MiReleasePfnLock(OldIrql);
101
102 ZeroAddress = MiMapPagesInZeroSpace(Pfn1, 1);
103 ASSERT(ZeroAddress);
104 RtlZeroMemory(ZeroAddress, PAGE_SIZE);
105 MiUnmapPagesInZeroSpace(ZeroAddress, 1);
106
107 OldIrql = MiAcquirePfnLock();
108
109 MiInsertPageInList(&MmZeroedPageListHead, PageIndex);
110 }
111 }
112 }
113
114 /* EOF */