mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 08:25:03 +00:00
[NTOSKRNL]
Implement MmAdjustWorkingSetSize svn path=/trunk/; revision=62275
This commit is contained in:
parent
feedae2fff
commit
9b07458c4d
1 changed files with 111 additions and 2 deletions
|
@ -15,6 +15,12 @@
|
|||
#define MODULE_INVOLVED_IN_ARM3
|
||||
#include "../ARM3/miarm.h"
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
|
||||
SIZE_T MmMinimumWorkingSetSize;
|
||||
SIZE_T MmMaximumWorkingSetSize;
|
||||
SIZE_T MmPagesAboveWsMinimum;
|
||||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
||||
/*
|
||||
|
@ -40,8 +46,111 @@ MmAdjustWorkingSetSize(IN SIZE_T WorkingSetMinimumInBytes,
|
|||
IN ULONG SystemCache,
|
||||
IN BOOLEAN IncreaseOkay)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
SIZE_T MinimumWorkingSetSize, MaximumWorkingSetSize;
|
||||
SSIZE_T Delta;
|
||||
PMMSUPPORT Ws;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Check for special case: empty the working set */
|
||||
if ((WorkingSetMinimumInBytes == -1) &&
|
||||
(WorkingSetMaximumInBytes == -1))
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* Assume success */
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
/* Get the working set and lock it */
|
||||
Ws = &PsGetCurrentProcess()->Vm;
|
||||
MiLockWorkingSet(PsGetCurrentThread(), Ws);
|
||||
|
||||
/* Calculate the actual minimum and maximum working set size to set */
|
||||
MinimumWorkingSetSize = (WorkingSetMinimumInBytes != 0) ?
|
||||
(WorkingSetMinimumInBytes / PAGE_SIZE) : Ws->MinimumWorkingSetSize;
|
||||
MaximumWorkingSetSize = (WorkingSetMaximumInBytes != 0) ?
|
||||
(WorkingSetMaximumInBytes / PAGE_SIZE) : Ws->MaximumWorkingSetSize;
|
||||
|
||||
/* Check if the new maximum exceeds the global maximum */
|
||||
if (MaximumWorkingSetSize > MmMaximumWorkingSetSize)
|
||||
{
|
||||
MaximumWorkingSetSize = MmMaximumWorkingSetSize;
|
||||
Status = STATUS_WORKING_SET_LIMIT_RANGE;
|
||||
}
|
||||
|
||||
/* Check if the new minimum is below the global minimum */
|
||||
if (MinimumWorkingSetSize < MmMinimumWorkingSetSize)
|
||||
{
|
||||
MinimumWorkingSetSize = MmMinimumWorkingSetSize;
|
||||
Status = STATUS_WORKING_SET_LIMIT_RANGE;
|
||||
}
|
||||
|
||||
/* Check if the new minimum exceeds the new maximum */
|
||||
if (MinimumWorkingSetSize > MaximumWorkingSetSize)
|
||||
{
|
||||
DPRINT1("MinimumWorkingSetSize > MaximumWorkingSetSize\n");
|
||||
Status = STATUS_BAD_WORKING_SET_LIMIT;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
/* Calculate the minimum WS size adjustment and check if we increase */
|
||||
Delta = MinimumWorkingSetSize - Ws->MinimumWorkingSetSize;
|
||||
if (Delta > 0)
|
||||
{
|
||||
/* Is increasing ok? */
|
||||
if (!IncreaseOkay)
|
||||
{
|
||||
DPRINT1("Privilege for WS size increase not held\n");
|
||||
Status = STATUS_PRIVILEGE_NOT_HELD;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
/* Check if the number of available pages is large enough */
|
||||
if (((SIZE_T)Delta / 1024) > (MmAvailablePages - 128))
|
||||
{
|
||||
DPRINT1("Not enough available pages\n");
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
/* Check if there are enough resident available pages */
|
||||
if ((SIZE_T)Delta >
|
||||
(MmResidentAvailablePages - MmSystemLockPagesCount - 256))
|
||||
{
|
||||
DPRINT1("Not enough resident pages\n");
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto Cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update resident available pages */
|
||||
if (Delta != 0)
|
||||
{
|
||||
InterlockedExchangeAddSizeT(&MmResidentAvailablePages, -Delta);
|
||||
}
|
||||
|
||||
/* Calculate new pages above minimum WS size */
|
||||
Delta += max((SSIZE_T)Ws->WorkingSetSize - MinimumWorkingSetSize, 0);
|
||||
|
||||
/* Subtract old pages above minimum WS size */
|
||||
Delta -= max((SSIZE_T)Ws->WorkingSetSize - Ws->MinimumWorkingSetSize, 0);
|
||||
|
||||
/* If it changed, add it to the global variable */
|
||||
if (Delta != 0)
|
||||
{
|
||||
InterlockedExchangeAddSizeT(&MmPagesAboveWsMinimum, Delta);
|
||||
}
|
||||
|
||||
/* Set the new working set size */
|
||||
Ws->MinimumWorkingSetSize = MinimumWorkingSetSize;
|
||||
Ws->MaximumWorkingSetSize = MaximumWorkingSetSize;
|
||||
|
||||
Cleanup:
|
||||
|
||||
/* Unlock the working set and return the status */
|
||||
MiUnlockWorkingSet(PsGetCurrentThread(), Ws);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue