[RSHELL]
[reactos.git] / ntoskrnl / mm / balance.c
index 2c77690..804c674 100644 (file)
@@ -14,6 +14,8 @@
 #define NDEBUG
 #include <debug.h>
 
+#include "ARM3/miarm.h"
+
 #if defined (ALLOC_PRAGMA)
 #pragma alloc_text(INIT, MmInitializeBalancer)
 #pragma alloc_text(INIT, MmInitializeMemoryConsumer)
@@ -136,7 +138,7 @@ ULONG
 NTAPI
 MiTrimMemoryConsumer(ULONG Consumer, ULONG InitialTarget)
 {
-    LONG Target = InitialTarget;
+    ULONG Target = InitialTarget;
     ULONG NrFreedPages = 0;
     NTSTATUS Status;
 
@@ -155,7 +157,7 @@ MiTrimMemoryConsumer(ULONG Consumer, ULONG InitialTarget)
     if (MmAvailablePages < MiMinimumAvailablePages)
     {
         /* Global page limit exceeded */
-        Target = max(Target, MiMinimumAvailablePages - MmAvailablePages);
+        Target = (ULONG)max(Target, MiMinimumAvailablePages - MmAvailablePages);
     }
 
     if (Target)
@@ -170,7 +172,7 @@ MiTrimMemoryConsumer(ULONG Consumer, ULONG InitialTarget)
         /* Now swap the pages out */
         Status = MiMemoryConsumers[Consumer].Trim(Target, 0, &NrFreedPages);
 
-        DPRINT("Trimming consumer %d: Freed %d pages with a target of %d pages\n", Consumer, NrFreedPages, Target);
+        DPRINT("Trimming consumer %lu: Freed %lu pages with a target of %lu pages\n", Consumer, NrFreedPages, Target);
 
         if (!NT_SUCCESS(Status))
         {
@@ -232,6 +234,13 @@ MiIsBalancerThread(VOID)
           (PsGetCurrentThreadId() == MiBalancerThreadId.UniqueThread);
 }
 
+VOID
+NTAPI
+MiDeletePte(IN PMMPTE PointerPte,
+            IN PVOID VirtualAddress,
+            IN PEPROCESS CurrentProcess,
+            IN PMMPTE PrototypePte);
+
 VOID
 NTAPI
 MmRebalanceMemoryConsumers(VOID)
@@ -369,8 +378,34 @@ MiBalancerThread(PVOID Unused)
 
       if (Status == STATUS_WAIT_0 || Status == STATUS_WAIT_1)
       {
-          ULONG InitialTarget = 0;
+        ULONG InitialTarget = 0;
 
+#if (_MI_PAGING_LEVELS == 2)
+        if (!MiIsBalancerThread())
+        {
+            /* Clean up the unused PDEs */
+            ULONG_PTR Address;
+            PEPROCESS Process = PsGetCurrentProcess();
+
+            /* Acquire PFN lock */
+            KIRQL OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
+            PMMPDE pointerPde;
+            for (Address = (ULONG_PTR)MI_LOWEST_VAD_ADDRESS;
+                 Address < (ULONG_PTR)MM_HIGHEST_VAD_ADDRESS;
+                 Address += (PAGE_SIZE * PTE_COUNT))
+            {
+                if (MiQueryPageTableReferences((PVOID)Address) == 0)
+                {
+                    pointerPde = MiAddressToPde(Address);
+                    if (pointerPde->u.Hard.Valid)
+                        MiDeletePte(pointerPde, MiPdeToPte(pointerPde), Process, NULL);
+                    ASSERT(pointerPde->u.Hard.Valid == 0);
+                }
+            }
+            /* Release lock */
+            KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
+        }
+#endif
           do
           {
               ULONG OldTarget = InitialTarget;
@@ -429,7 +464,7 @@ MiInitBalancerThread(VOID)
                                  NULL,
                                  NULL,
                                  &MiBalancerThreadId,
-                                 (PKSTART_ROUTINE) MiBalancerThread,
+                                 MiBalancerThread,
                                  NULL);
    if (!NT_SUCCESS(Status))
    {