MiMinimumAvailablePages = 64;
if ((NrAvailablePages + NrSystemPages) >= 8192)
{
- MiMemoryConsumers[MC_CACHE].PagesTarget = NrAvailablePages / 4 * 3;
+ MiMemoryConsumers[MC_CACHE].PagesTarget = NrAvailablePages / 4 * 3;
}
else if ((NrAvailablePages + NrSystemPages) >= 4096)
{
}
else
{
- MiMemoryConsumers[MC_CACHE].PagesTarget = NrAvailablePages / 8;
+ MiMemoryConsumers[MC_CACHE].PagesTarget = NrAvailablePages / 8;
}
MiMemoryConsumers[MC_USER].PagesTarget = NrAvailablePages - MiMinimumAvailablePages;
}
else
{
KeReleaseSpinLock(&AllocationListLock, OldIrql);
- if(Consumer == MC_USER) MmRemoveLRUUserPage(Page);
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
MmDereferencePage(Page);
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
LONG Target;
ULONG NrFreedPages;
- Target = MiMemoryConsumers[Consumer].PagesUsed -
- MiMemoryConsumers[Consumer].PagesTarget;
- if (Target < 1)
- {
- Target = 1;
- }
+ Target = max(MiMinimumPagesPerRun,
+ MiMemoryConsumers[Consumer].PagesUsed -
+ MiMemoryConsumers[Consumer].PagesTarget);
if (MiMemoryConsumers[Consumer].Trim != NULL)
{
PFN_NUMBER CurrentPage;
PFN_NUMBER NextPage;
NTSTATUS Status;
-
+
(*NrFreedPages) = 0;
-
+
CurrentPage = MmGetLRUFirstUserPage();
while (CurrentPage != 0 && Target > 0)
{
- NextPage = MmGetLRUNextUserPage(CurrentPage);
-
Status = MmPageOutPhysicalAddress(CurrentPage);
if (NT_SUCCESS(Status))
{
Target--;
(*NrFreedPages)++;
}
-
+
+ NextPage = MmGetLRUNextUserPage(CurrentPage);
+ if (NextPage <= CurrentPage)
+ {
+ /* We wrapped around, so we're done */
+ break;
+ }
CurrentPage = NextPage;
}
- return(STATUS_SUCCESS);
+
+ return STATUS_SUCCESS;
}
VOID
ULONG NrFreedPages;
NTSTATUS Status;
- Target = (MiMinimumAvailablePages - MmAvailablePages) + MiPagesRequired;
+ Target = (ULONG)(MiMinimumAvailablePages - MmAvailablePages) + MiPagesRequired;
Target = max(Target, (LONG) MiMinimumPagesPerRun);
for (i = 0; i < MC_MAXIMUM && Target > 0; i++)
static BOOLEAN
MiIsBalancerThread(VOID)
{
- return MiBalancerThreadHandle != NULL &&
- PsGetCurrentThread() == MiBalancerThreadId.UniqueThread;
+ return (MiBalancerThreadHandle != NULL) &&
+ (PsGetCurrentThreadId() == MiBalancerThreadId.UniqueThread);
}
NTSTATUS
{
KeBugCheck(NO_PAGES_AVAILABLE);
}
+ if (Consumer == MC_USER) MmInsertLRULastUserPage(Page);
*AllocatedPage = Page;
if (MmAvailablePages <= MiMinimumAvailablePages &&
- MiBalancerThreadHandle != NULL)
+ MiBalancerThreadHandle != NULL &&
+ !MiIsBalancerThread())
{
KeSetEvent(&MiBalancerEvent, IO_NO_INCREMENT, FALSE);
}
{
KeBugCheck(NO_PAGES_AVAILABLE);
}
- /* Update the Consumer and make the page active */
+
if(Consumer == MC_USER) MmInsertLRULastUserPage(Page);
*AllocatedPage = Page;
(void)InterlockedDecrementUL(&MiPagesRequired);
+
+ if (MmAvailablePages <= MiMinimumAvailablePages &&
+ MiBalancerThreadHandle != NULL &&
+ !MiIsBalancerThread())
+ {
+ KeSetEvent(&MiBalancerEvent, IO_NO_INCREMENT, FALSE);
+ }
+
return(STATUS_SUCCESS);
}
}
if(Consumer == MC_USER) MmInsertLRULastUserPage(Page);
*AllocatedPage = Page;
+
+ if (MmAvailablePages <= MiMinimumAvailablePages &&
+ MiBalancerThreadHandle != NULL &&
+ !MiIsBalancerThread())
+ {
+ KeSetEvent(&MiBalancerEvent, IO_NO_INCREMENT, FALSE);
+ }
return(STATUS_SUCCESS);
}