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