update for HEAD-2003091401
[reactos.git] / ntoskrnl / mm / pager.c
index ff1348e..e4ab652 100644 (file)
@@ -25,31 +25,62 @@ static HANDLE PagerThreadHandle;
 static CLIENT_ID PagerThreadId;
 static KEVENT PagerThreadEvent;
 static BOOLEAN PagerThreadShouldTerminate;
+static ULONG PagerThreadWorkCount;
 
 /* FUNCTIONS *****************************************************************/
 
+BOOLEAN
+MiIsPagerThread(VOID)
+{
+  return(PsGetCurrentThreadId() == PagerThreadId.UniqueThread);
+}
+
+VOID
+MiStartPagerThread(VOID)
+{
+  ULONG WasWorking;
+
+  WasWorking = InterlockedIncrement(&PagerThreadWorkCount);
+  if (WasWorking == 1)
+    {
+      KeSetEvent(&PagerThreadEvent, IO_NO_INCREMENT, FALSE);
+    }
+}
+
+VOID
+MiStopPagerThread(VOID)
+{
+  (VOID)InterlockedDecrement(&PagerThreadWorkCount);
+}
+
 static NTSTATUS STDCALL
 MmPagerThreadMain(PVOID Ignored)
 {
    NTSTATUS Status;
-      
+
    for(;;)
      {
-       Status = KeWaitForSingleObject(&PagerThreadEvent,
-                                      0,
-                                      KernelMode,
-                                      FALSE,
-                                      NULL);
-       if (!NT_SUCCESS(Status))
-         {
-            DbgPrint("PagerThread: Wait failed\n");
-            KeBugCheck(0);
-         }
-       if (PagerThreadShouldTerminate)
-         {
-            DbgPrint("PagerThread: Terminating\n");
-            return(STATUS_SUCCESS);
-         }
+       /* Wake for a low memory situation or a terminate request. */
+       Status = KeWaitForSingleObject(&PagerThreadEvent,
+                                     0,
+                                     KernelMode,
+                                     FALSE,
+                                     NULL);
+       if (!NT_SUCCESS(Status))
+        {
+          DbgPrint("PagerThread: Wait failed\n");
+          KEBUGCHECK(0);
+        }
+       if (PagerThreadShouldTerminate)
+        {
+          DbgPrint("PagerThread: Terminating\n");
+          return(STATUS_SUCCESS);
+        }
+       do
+        {
+          /* Try and make some memory available to the system. */
+          MmRebalanceMemoryConsumers();
+        } while(PagerThreadWorkCount > 0);
      }
 }
 
@@ -58,6 +89,7 @@ NTSTATUS MmInitPagerThread(VOID)
    NTSTATUS Status;
    
    PagerThreadShouldTerminate = FALSE;
+   PagerThreadWorkCount = 0;
    KeInitializeEvent(&PagerThreadEvent,
                     SynchronizationEvent,
                     FALSE);
@@ -67,7 +99,7 @@ NTSTATUS MmInitPagerThread(VOID)
                                 NULL,
                                 NULL,
                                 &PagerThreadId,
-                                MmPagerThreadMain,
+                                (PKSTART_ROUTINE) MmPagerThreadMain,
                                 NULL);
    if (!NT_SUCCESS(Status))
      {