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 */ 115