Author: ekohl
Date: Sun Feb 21 00:10:53 2010
New Revision: 45640
URL: http://svn.reactos.org/svn/reactos?rev=45640&view=rev
Log:
Partially revert patches 45626 and 45633.
Several services do not report their status to the service manager properly. Therefore we must not use any code that relies on service status information as part of the setup and boot processes as long as these issues have not been fixed. The service manager still needs to provide fake information about the service status.
Modified:
trunk/reactos/base/system/services/database.c
trunk/reactos/dll/win32/syssetup/install.c
Modified: trunk/reactos/base/system/services/database.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/services/datab…
==============================================================================
--- trunk/reactos/base/system/services/database.c [iso-8859-1] (original)
+++ trunk/reactos/base/system/services/database.c [iso-8859-1] Sun Feb 21 00:10:53 2010
@@ -1054,7 +1054,7 @@
{
Group->ServicesRunning = TRUE;
}
- Service->Status.dwCurrentState = SERVICE_START_PENDING;
+ Service->Status.dwCurrentState = SERVICE_RUNNING;
}
#if 0
else
Modified: trunk/reactos/dll/win32/syssetup/install.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/syssetup/install…
==============================================================================
--- trunk/reactos/dll/win32/syssetup/install.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/syssetup/install.c [iso-8859-1] Sun Feb 21 00:10:53 2010
@@ -473,34 +473,17 @@
static BOOL
EnableUserModePnpManager(VOID)
{
- SERVICE_STATUS_PROCESS ServiceStatus;
SC_HANDLE hSCManager = NULL;
SC_HANDLE hService = NULL;
- DWORD dwStartTickCount;
- DWORD dwOldCheckPoint;
- DWORD BytesNeeded = 0;
- DWORD dwWaitTime;
- DWORD dwMaxWait;
- HANDLE hEvent;
BOOL ret = FALSE;
- hEvent = OpenEventW(EVENT_ALL_ACCESS,
- FALSE,
- L"SC_AutoStartComplete");
- if (hEvent == NULL)
- goto cleanup;
-
- WaitForSingleObject(hEvent, INFINITE);
-
- hSCManager = OpenSCManager(NULL,
- NULL,
- SC_MANAGER_CONNECT);
+ hSCManager = OpenSCManager(NULL, NULL, 0);
if (hSCManager == NULL)
goto cleanup;
hService = OpenServiceW(hSCManager,
L"PlugPlay",
- SERVICE_CHANGE_CONFIG | SERVICE_START | SERVICE_QUERY_STATUS);
+ SERVICE_CHANGE_CONFIG | SERVICE_START);
if (hService == NULL)
goto cleanup;
@@ -515,69 +498,9 @@
ret = StartServiceW(hService, 0, NULL);
if (!ret)
- {
- /* If the service is already running, just return TRUE */
- ret = GetLastError() == ERROR_SERVICE_ALREADY_RUNNING;
goto cleanup;
- }
-
- ret = QueryServiceStatusEx(hService,
- SC_STATUS_PROCESS_INFO,
- (LPBYTE)&ServiceStatus,
- sizeof(SERVICE_STATUS_PROCESS),
- &BytesNeeded);
- if (!ret)
- goto cleanup;
-
- /* We don't want to wait for more than 30 seconds */
- dwMaxWait = 30000;
- dwStartTickCount = GetTickCount();
-
- /* Loop until it's running */
- while (ServiceStatus.dwCurrentState != SERVICE_RUNNING)
- {
- dwOldCheckPoint = ServiceStatus.dwCheckPoint;
- dwWaitTime = ServiceStatus.dwWaitHint / 10;
-
- /* Get the latest status info */
- if (!QueryServiceStatusEx(hService,
- SC_STATUS_PROCESS_INFO,
- (LPBYTE)&ServiceStatus,
- sizeof(SERVICE_STATUS_PROCESS),
- &BytesNeeded))
- {
- /* Something went wrong... */
- break;
- }
-
- /* Is the service making progress? */
- if (ServiceStatus.dwCheckPoint > dwOldCheckPoint)
- {
- /* It is, get the latest tickcount to reset the max wait time */
- dwStartTickCount = GetTickCount();
- dwOldCheckPoint = ServiceStatus.dwCheckPoint;
- }
- else
- {
- /* It's not, make sure we haven't exceeded our wait time */
- if (GetTickCount() >= dwStartTickCount + dwMaxWait)
- {
- /* We have, give up */
- break;
- }
- }
-
- /* Adjust the wait hint times */
- if (dwWaitTime < 200)
- dwWaitTime = 200;
- else if (dwWaitTime > 10000)
- dwWaitTime = 10000;
-
- /* Wait before trying again */
- Sleep(dwWaitTime);
- }
-
- ret = ServiceStatus.dwCurrentState == SERVICE_RUNNING;
+
+ ret = TRUE;
cleanup:
if (hSCManager != NULL)
Author: sir_richard
Date: Sat Feb 20 22:48:36 2010
New Revision: 45638
URL: http://svn.reactos.org/svn/reactos?rev=45638&view=rev
Log:
[NTOS]: Make MM init read MmProductType to determine what SKU of ReactOS this is, instead of assuming Server. If you want to go back to the old behavior, you need to change "WinNT" to "ServerNT" in the hivesys under Product Type.
[NTOS]: Configure the MmSystemSize variable properly based on SKU and RAM. Previously, ReactOS told all drivers and applications you were running on a system with < 13MB RAM.
[NTOS]: Initialize thresholds for low and high memory (in pages), low and high paged pool memory, and low and high nonpaged pool memory. These are described in the source.
[NTOS]: Initialize events for each of those thresholds, and populate the \KernelObject\xxxCondition events that are documented in MSDN for driver and app developers.
[NTOS]: Define some internal thresholds to use later, representing the minimum number of free pages under we go berserk, and the minimum number of free pages that we consider "plenty".
[NTOS]: Rename MiRemoveFromList to MiUnlinkFreeOrZeroedPage (Windows name). Make the function handle MmAvailablePages decrement, instead of having the caller do it.
[NTOS]: Remove run-time initialization of the PFN lists, just initialize them statically (also fixes the fact we forgot to initialize their names).
[NTOS]: Move some more initialization code to ARM3 instead of mm.
[NTOS]: Read ProductType from registry into MmProductType instead of dummy value. Remove duplicate "Mirroring" variable read.
Modified:
trunk/reactos/ntoskrnl/config/cmdata.c
trunk/reactos/ntoskrnl/mm/ARM3/i386/init.c
trunk/reactos/ntoskrnl/mm/ARM3/miarm.h
trunk/reactos/ntoskrnl/mm/ARM3/mminit.c
trunk/reactos/ntoskrnl/mm/ARM3/mmsup.c
trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c
trunk/reactos/ntoskrnl/mm/ARM3/pool.c
trunk/reactos/ntoskrnl/mm/freelist.c
trunk/reactos/ntoskrnl/mm/mminit.c
Modified: trunk/reactos/ntoskrnl/config/cmdata.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmdata.c?r…
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmdata.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/config/cmdata.c [iso-8859-1] Sat Feb 20 22:48:36 2010
@@ -11,11 +11,12 @@
#include "ntoskrnl.h"
#define NDEBUG
#include "debug.h"
-
+
/* GLOBALS *******************************************************************/
ULONG DummyData;
ULONG CmNtGlobalFlag;
+extern ULONG MmProductType;
WCHAR CmDefaultLanguageId[12];
ULONG CmDefaultLanguageIdLength = sizeof(CmDefaultLanguageId);
@@ -266,14 +267,6 @@
{
L"Session Manager\\Memory Management",
- L"Mirroring",
- &DummyData,
- NULL,
- NULL
- },
-
- {
- L"Session Manager\\Memory Management",
L"SystemViewSize",
&DummyData,
NULL,
@@ -667,7 +660,7 @@
{
L"ProductOptions",
L"ProductType",
- &DummyData,
+ &MmProductType,
NULL,
NULL
},
Modified: trunk/reactos/ntoskrnl/mm/ARM3/i386/init.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/i386/init…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/i386/init.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/i386/init.c [iso-8859-1] Sat Feb 20 22:48:36 2010
@@ -404,6 +404,9 @@
DPRINT("PFN DB PA PFN begins at: %lx\n", PageFrameIndex);
DPRINT("NP PA PFN begins at: %lx\n", PageFrameIndex + MxPfnAllocation);
+ /* Convert nonpaged pool size from bytes to pages */
+ MmMaximumNonPagedPoolInPages = MmMaximumNonPagedPoolInBytes >> PAGE_SHIFT;
+
//
// Now we need some pages to create the page tables for the NP system VA
// which includes system PTEs and expansion NP
@@ -496,10 +499,9 @@
ASSERT(MiAddressToPte(MmNonPagedSystemStart) <
MiAddressToPte(MmNonPagedPoolExpansionStart));
- //
- // Now go ahead and initialize the ARM³ nonpaged pool
- //
- MiInitializeArmPool();
+ /* Now go ahead and initialize the nonpaged pool */
+ MiInitializeNonPagedPool();
+ MiInitializeNonPagedPoolThresholds();
/* Map the PFN database pages */
MiMapPfnDatabase(LoaderBlock);
Modified: trunk/reactos/ntoskrnl/mm/ARM3/miarm.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/miarm.h?r…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] Sat Feb 20 22:48:36 2010
@@ -168,6 +168,8 @@
extern ULONG MmSizeOfNonPagedPoolInBytes;
extern ULONG MmMaximumNonPagedPoolInBytes;
+extern PFN_NUMBER MmMaximumNonPagedPoolInPages;
+extern PFN_NUMBER MmSizeOfPagedPoolInPages;
extern PVOID MmNonPagedSystemStart;
extern PVOID MmNonPagedPoolStart;
extern PVOID MmNonPagedPoolExpansionStart;
@@ -217,6 +219,22 @@
extern ULONG MmMaximumNonPagedPoolPercent;
extern ULONG MmLargeStackSize;
extern PMMCOLOR_TABLES MmFreePagesByColor[FreePageList + 1];
+extern ULONG MmProductType;
+extern MM_SYSTEMSIZE MmSystemSize;
+extern PKEVENT MiLowMemoryEvent;
+extern PKEVENT MiHighMemoryEvent;
+extern PKEVENT MiLowPagedPoolEvent;
+extern PKEVENT MiHighPagedPoolEvent;
+extern PKEVENT MiLowNonPagedPoolEvent;
+extern PKEVENT MiHighNonPagedPoolEvent;
+extern PFN_NUMBER MmLowMemoryThreshold;
+extern PFN_NUMBER MmHighMemoryThreshold;
+extern PFN_NUMBER MiLowPagedPoolThreshold;
+extern PFN_NUMBER MiHighPagedPoolThreshold;
+extern PFN_NUMBER MiLowNonPagedPoolThreshold;
+extern PFN_NUMBER MiHighNonPagedPoolThreshold;
+extern PFN_NUMBER MmMinimumFreePages;
+extern PFN_NUMBER MmPlentyFreePages;
#define MI_PFN_TO_PFNENTRY(x) (&MmPfnDatabase[1][x])
#define MI_PFNENTRY_TO_PFN(x) (x - MmPfnDatabase[1])
@@ -258,6 +276,12 @@
IN PLOADER_PARAMETER_BLOCK LoaderBlock
);
+BOOLEAN
+NTAPI
+MiInitializeMemoryEvents(
+ VOID
+);
+
PFN_NUMBER
NTAPI
MxGetNextPage(
@@ -296,7 +320,19 @@
VOID
NTAPI
-MiInitializeArmPool(
+MiInitializeNonPagedPool(
+ VOID
+);
+
+VOID
+NTAPI
+MiInitializeNonPagedPoolThresholds(
+ VOID
+);
+
+VOID
+NTAPI
+MiInitializePoolEvents(
VOID
);
@@ -389,7 +425,7 @@
VOID
NTAPI
-MiRemoveFromList(
+MiUnlinkFreeOrZeroedPage(
IN PMMPFN Entry
);
Modified: trunk/reactos/ntoskrnl/mm/ARM3/mminit.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/mminit.c?…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/mminit.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/mminit.c [iso-8859-1] Sat Feb 20 22:48:36 2010
@@ -25,6 +25,9 @@
ULONG MmMaximumNonPagedPoolPercent;
ULONG MmSizeOfNonPagedPoolInBytes;
ULONG MmMaximumNonPagedPoolInBytes;
+
+/* Some of the same values, in pages */
+PFN_NUMBER MmMaximumNonPagedPoolInPages;
//
// These numbers describe the discrete equation components of the nonpaged
@@ -257,6 +260,46 @@
*/
C_ASSERT(FreePageList == 1);
PMMCOLOR_TABLES MmFreePagesByColor[FreePageList + 1];
+
+/* An event used in Phase 0 before the rest of the system is ready to go */
+KEVENT MiTempEvent;
+
+/* All the events used for memory threshold notifications */
+PKEVENT MiLowMemoryEvent;
+PKEVENT MiHighMemoryEvent;
+PKEVENT MiLowPagedPoolEvent;
+PKEVENT MiHighPagedPoolEvent;
+PKEVENT MiLowNonPagedPoolEvent;
+PKEVENT MiHighNonPagedPoolEvent;
+
+/* The actual thresholds themselves, in page numbers */
+PFN_NUMBER MmLowMemoryThreshold;
+PFN_NUMBER MmHighMemoryThreshold;
+PFN_NUMBER MiLowPagedPoolThreshold;
+PFN_NUMBER MiHighPagedPoolThreshold;
+PFN_NUMBER MiLowNonPagedPoolThreshold;
+PFN_NUMBER MiHighNonPagedPoolThreshold;
+
+/*
+ * This number determines how many free pages must exist, at minimum, until we
+ * start trimming working sets and flushing modified pages to obtain more free
+ * pages.
+ *
+ * This number changes if the system detects that this is a server product
+ */
+PFN_NUMBER MmMinimumFreePages = 26;
+
+/*
+ * This number indicates how many pages we consider to be a low limit of having
+ * "plenty" of free memory.
+ *
+ * It is doubled on systems that have more than 63MB of memory
+ */
+PFN_NUMBER MmPlentyFreePages = 400;
+
+/* These values store the type of system this is (small, med, large) and if server */
+ULONG MmProductType;
+MM_SYSTEMSIZE MmSystemSize;
/* PRIVATE FUNCTIONS **********************************************************/
@@ -907,6 +950,217 @@
VOID
NTAPI
+MiAdjustWorkingSetManagerParameters(IN BOOLEAN Client)
+{
+ /* This function needs to do more work, for now, we tune page minimums */
+
+ /* Check for a system with around 64MB RAM or more */
+ if (MmNumberOfPhysicalPages >= (63 * _1MB) / PAGE_SIZE)
+ {
+ /* Double the minimum amount of pages we consider for a "plenty free" scenario */
+ MmPlentyFreePages *= 2;
+ }
+}
+
+VOID
+NTAPI
+MiNotifyMemoryEvents(VOID)
+{
+ /* Are we in a low-memory situation? */
+ if (MmAvailablePages < MmLowMemoryThreshold)
+ {
+ /* Clear high, set low */
+ if (KeReadStateEvent(MiHighMemoryEvent)) KeClearEvent(MiHighMemoryEvent);
+ if (!KeReadStateEvent(MiLowMemoryEvent)) KeSetEvent(MiLowMemoryEvent, 0, FALSE);
+ }
+ else if (MmAvailablePages < MmHighMemoryThreshold)
+ {
+ /* We are in between, clear both */
+ if (KeReadStateEvent(MiHighMemoryEvent)) KeClearEvent(MiHighMemoryEvent);
+ if (KeReadStateEvent(MiLowMemoryEvent)) KeClearEvent(MiLowMemoryEvent);
+ }
+ else
+ {
+ /* Clear low, set high */
+ if (KeReadStateEvent(MiLowMemoryEvent)) KeClearEvent(MiLowMemoryEvent);
+ if (!KeReadStateEvent(MiHighMemoryEvent)) KeSetEvent(MiHighMemoryEvent, 0, FALSE);
+ }
+}
+
+NTSTATUS
+NTAPI
+MiCreateMemoryEvent(IN PUNICODE_STRING Name,
+ OUT PKEVENT *Event)
+{
+ PACL Dacl;
+ HANDLE EventHandle;
+ ULONG DaclLength;
+ NTSTATUS Status;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ SECURITY_DESCRIPTOR SecurityDescriptor;
+
+ /* Create the SD */
+ Status = RtlCreateSecurityDescriptor(&SecurityDescriptor,
+ SECURITY_DESCRIPTOR_REVISION);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* One ACL with 3 ACEs, containing each one SID */
+ DaclLength = sizeof(ACL) +
+ 3 * sizeof(ACCESS_ALLOWED_ACE) +
+ RtlLengthSid(SeLocalSystemSid) +
+ RtlLengthSid(SeAliasAdminsSid) +
+ RtlLengthSid(SeWorldSid);
+
+ /* Allocate space for the DACL */
+ Dacl = ExAllocatePoolWithTag(PagedPool, DaclLength, 'lcaD');
+ if (!Dacl) return STATUS_INSUFFICIENT_RESOURCES;
+
+ /* Setup the ACL inside it */
+ Status = RtlCreateAcl(Dacl, DaclLength, ACL_REVISION);
+ if (!NT_SUCCESS(Status)) goto CleanUp;
+
+ /* Add query rights for everyone */
+ Status = RtlAddAccessAllowedAce(Dacl,
+ ACL_REVISION,
+ SYNCHRONIZE | EVENT_QUERY_STATE | READ_CONTROL,
+ SeWorldSid);
+ if (!NT_SUCCESS(Status)) goto CleanUp;
+
+ /* Full rights for the admin */
+ Status = RtlAddAccessAllowedAce(Dacl,
+ ACL_REVISION,
+ EVENT_ALL_ACCESS,
+ SeAliasAdminsSid);
+ if (!NT_SUCCESS(Status)) goto CleanUp;
+
+ /* As well as full rights for the system */
+ Status = RtlAddAccessAllowedAce(Dacl,
+ ACL_REVISION,
+ EVENT_ALL_ACCESS,
+ SeLocalSystemSid);
+ if (!NT_SUCCESS(Status)) goto CleanUp;
+
+ /* Set this DACL inside the SD */
+ Status = RtlSetDaclSecurityDescriptor(&SecurityDescriptor,
+ TRUE,
+ Dacl,
+ FALSE);
+ if (!NT_SUCCESS(Status)) goto CleanUp;
+
+ /* Setup the event attributes, making sure it's a permanent one */
+ InitializeObjectAttributes(&ObjectAttributes,
+ Name,
+ OBJ_KERNEL_HANDLE | OBJ_PERMANENT,
+ NULL,
+ &SecurityDescriptor);
+
+ /* Create the event */
+ Status = ZwCreateEvent(&EventHandle,
+ EVENT_ALL_ACCESS,
+ &ObjectAttributes,
+ NotificationEvent,
+ FALSE);
+CleanUp:
+ /* Free the DACL */
+ ExFreePool(Dacl);
+
+ /* Check if this is the success path */
+ if (NT_SUCCESS(Status))
+ {
+ /* Add a reference to the object, then close the handle we had */
+ Status = ObReferenceObjectByHandle(EventHandle,
+ EVENT_MODIFY_STATE,
+ ExEventObjectType,
+ KernelMode,
+ (PVOID*)Event,
+ NULL);
+ ZwClose (EventHandle);
+ }
+
+ /* Return status */
+ return Status;
+}
+
+BOOLEAN
+NTAPI
+MiInitializeMemoryEvents(VOID)
+{
+ UNICODE_STRING LowString = RTL_CONSTANT_STRING(L"\\KernelObjects\\LowMemoryCondition");
+ UNICODE_STRING HighString = RTL_CONSTANT_STRING(L"\\KernelObjects\\HighMemoryCondition");
+ UNICODE_STRING LowPagedPoolString = RTL_CONSTANT_STRING(L"\\KernelObjects\\LowPagedPoolCondition");
+ UNICODE_STRING HighPagedPoolString = RTL_CONSTANT_STRING(L"\\KernelObjects\\HighPagedPoolCondition");
+ UNICODE_STRING LowNonPagedPoolString = RTL_CONSTANT_STRING(L"\\KernelObjects\\LowNonPagedPoolCondition");
+ UNICODE_STRING HighNonPagedPoolString = RTL_CONSTANT_STRING(L"\\KernelObjects\\HighNonPagedPoolCondition");
+ NTSTATUS Status;
+
+ /* Check if we have a registry setting */
+ if (MmLowMemoryThreshold)
+ {
+ /* Convert it to pages */
+ MmLowMemoryThreshold *= (_1MB / PAGE_SIZE);
+ }
+ else
+ {
+ /* The low memory threshold is hit when we don't consider that we have "plenty" of free pages anymore */
+ MmLowMemoryThreshold = MmPlentyFreePages;
+
+ /* More than one GB of memory? */
+ if (MmNumberOfPhysicalPages > 0x40000)
+ {
+ /* Start at 32MB, and add another 16MB for each GB */
+ MmLowMemoryThreshold = (32 * _1MB) / PAGE_SIZE;
+ MmLowMemoryThreshold += ((MmNumberOfPhysicalPages - 0x40000) >> 7);
+ }
+ else if (MmNumberOfPhysicalPages > 0x8000)
+ {
+ /* For systems with > 128MB RAM, add another 4MB for each 128MB */
+ MmLowMemoryThreshold += ((MmNumberOfPhysicalPages - 0x8000) >> 5);
+ }
+
+ /* Don't let the minimum threshold go past 64MB */
+ MmLowMemoryThreshold = min(MmLowMemoryThreshold, (64 * _1MB) / PAGE_SIZE);
+ }
+
+ /* Check if we have a registry setting */
+ if (MmHighMemoryThreshold)
+ {
+ /* Convert it into pages */
+ MmHighMemoryThreshold *= (_1MB / PAGE_SIZE);
+ }
+ else
+ {
+ /* Otherwise, the default is three times the low memory threshold */
+ MmHighMemoryThreshold = 3 * MmLowMemoryThreshold;
+ ASSERT(MmHighMemoryThreshold > MmLowMemoryThreshold);
+ }
+
+ /* Make sure high threshold is actually higher than the low */
+ MmHighMemoryThreshold = max(MmHighMemoryThreshold, MmLowMemoryThreshold);
+
+ /* Create the memory events for all the thresholds */
+ Status = MiCreateMemoryEvent(&LowString, &MiLowMemoryEvent);
+ if (!NT_SUCCESS(Status)) return FALSE;
+ Status = MiCreateMemoryEvent(&HighString, &MiHighMemoryEvent);
+ if (!NT_SUCCESS(Status)) return FALSE;
+ Status = MiCreateMemoryEvent(&LowPagedPoolString, &MiLowPagedPoolEvent);
+ if (!NT_SUCCESS(Status)) return FALSE;
+ Status = MiCreateMemoryEvent(&HighPagedPoolString, &MiHighPagedPoolEvent);
+ if (!NT_SUCCESS(Status)) return FALSE;
+ Status = MiCreateMemoryEvent(&LowNonPagedPoolString, &MiLowNonPagedPoolEvent);
+ if (!NT_SUCCESS(Status)) return FALSE;
+ Status = MiCreateMemoryEvent(&HighNonPagedPoolString, &MiHighNonPagedPoolEvent);
+ if (!NT_SUCCESS(Status)) return FALSE;
+
+ /* Now setup the pool events */
+ MiInitializePoolEvents();
+
+ /* Set the initial event state */
+ MiNotifyMemoryEvents();
+ return TRUE;
+}
+
+VOID
+NTAPI
MmDumpArmPfnDatabase(VOID)
{
ULONG i;
@@ -1324,10 +1578,14 @@
//
InitializePool(PagedPool, 0);
- //
- // Initialize the paged pool mutex
- //
- KeInitializeGuardedMutex(&MmPagedPoolMutex);
+ /* Default low threshold of 30MB or one fifth of paged pool */
+ MiLowPagedPoolThreshold = (30 * _1MB) >> PAGE_SHIFT;
+ MiLowPagedPoolThreshold = min(MiLowPagedPoolThreshold, Size / 5);
+
+ /* Default high threshold of 60MB or 25% */
+ MiHighPagedPoolThreshold = (60 * _1MB) >> PAGE_SHIFT;
+ MiHighPagedPoolThreshold = min(MiHighPagedPoolThreshold, (Size * 2) / 5);
+ ASSERT(MiLowPagedPoolThreshold < MiHighPagedPoolThreshold);
}
NTSTATUS
@@ -1353,6 +1611,17 @@
IncludeType[LoaderBBTMemory] = FALSE;
if (Phase == 0)
{
+ /* Initialize the phase 0 temporary event */
+ KeInitializeEvent(&MiTempEvent, NotificationEvent, FALSE);
+
+ /* Set all the events to use the temporary event for now */
+ MiLowMemoryEvent = &MiTempEvent;
+ MiHighMemoryEvent = &MiTempEvent;
+ MiLowPagedPoolEvent = &MiTempEvent;
+ MiHighPagedPoolEvent = &MiTempEvent;
+ MiLowNonPagedPoolEvent = &MiTempEvent;
+ MiHighNonPagedPoolEvent = &MiTempEvent;
+
//
// Define the basic user vs. kernel address space separation
//
@@ -1432,6 +1701,16 @@
//
MiSystemViewStart = (PVOID)((ULONG_PTR)MmSessionBase -
MmSystemViewSize);
+
+
+ /* Initialize the user mode image list */
+ InitializeListHead(&MmLoadedUserImageList);
+
+ /* Initialize the paged pool mutex */
+ KeInitializeGuardedMutex(&MmPagedPoolMutex);
+
+ /* Initialize the Loader Lock */
+ KeInitializeMutant(&MmSystemLoadLock, FALSE);
//
// Count physical pages on the system
@@ -1538,6 +1817,77 @@
// Size up paged pool and build the shadow system page directory
//
MiBuildPagedPool();
+
+ /* Check how many pages the system has */
+ if (MmNumberOfPhysicalPages <= (13 * _1MB))
+ {
+ /* Set small system */
+ MmSystemSize = MmSmallSystem;
+ }
+ else if (MmNumberOfPhysicalPages <= (19 * _1MB))
+ {
+ /* Set small system */
+ MmSystemSize = MmSmallSystem;
+ }
+ else
+ {
+ /* Set medium system */
+ MmSystemSize = MmMediumSystem;
+ }
+
+ /* Check for more than 32MB */
+ if (MmNumberOfPhysicalPages >= ((32 * _1MB) / PAGE_SIZE))
+ {
+ /* Check for product type being "Wi" for WinNT */
+ if (MmProductType == '\0i\0W')
+ {
+ /* Then this is a large system */
+ MmSystemSize = MmLargeSystem;
+ }
+ else
+ {
+ /* For servers, we need 64MB to consider this as being large */
+ if (MmNumberOfPhysicalPages >= ((64 * _1MB) / PAGE_SIZE))
+ {
+ /* Set it as large */
+ MmSystemSize = MmLargeSystem;
+ }
+ }
+ }
+
+ /* Now setup the shared user data fields */
+ ASSERT(SharedUserData->NumberOfPhysicalPages == 0);
+ SharedUserData->NumberOfPhysicalPages = MmNumberOfPhysicalPages;
+ SharedUserData->LargePageMinimum = 0;
+
+ /* Check for workstation (Wi for WinNT) */
+ if (MmProductType == '\0i\0W')
+ {
+ /* Set Windows NT Workstation product type */
+ SharedUserData->NtProductType = NtProductWinNt;
+ MmProductType = 0;
+ }
+ else
+ {
+ /* Check for LanMan server */
+ if (MmProductType == '\0a\0L')
+ {
+ /* This is a domain controller */
+ SharedUserData->NtProductType = NtProductLanManNt;
+ }
+ else
+ {
+ /* Otherwise it must be a normal server */
+ SharedUserData->NtProductType = NtProductServer;
+ }
+
+ /* Set the product type, and make the system more aggressive with low memory */
+ MmProductType = 1;
+ MmMinimumFreePages = 81;
+ }
+
+ /* Update working set tuning parameters */
+ MiAdjustWorkingSetManagerParameters(!MmProductType);
}
//
Modified: trunk/reactos/ntoskrnl/mm/ARM3/mmsup.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/mmsup.c?r…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/mmsup.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/mmsup.c [iso-8859-1] Sat Feb 20 22:48:36 2010
@@ -15,11 +15,6 @@
#line 15 "ARM³::MMSUP"
#define MODULE_INVOLVED_IN_ARM3
#include "../ARM3/miarm.h"
-
-/* GLOBALS ********************************************************************/
-
-BOOLEAN IsThisAnNtAsSystem = FALSE;
-MM_SYSTEMSIZE MmSystemSize = MmSmallSystem;
/* PUBLIC FUNCTIONS ***********************************************************/
@@ -137,10 +132,8 @@
NTAPI
MmIsThisAnNtAsSystem(VOID)
{
- //
- // Return if this is a server system
- //
- return IsThisAnNtAsSystem;
+ /* Return if this is a server system */
+ return MmProductType;
}
/*
@@ -150,9 +143,7 @@
NTAPI
MmQuerySystemSize(VOID)
{
- //
- // Return the low, medium or high memory system type
- //
+ /* Return the low, medium or high memory system type */
return MmSystemSize;
}
Modified: trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c [iso-8859-1] Sat Feb 20 22:48:36 2010
@@ -18,12 +18,25 @@
/* GLOBALS ********************************************************************/
-MMPFNLIST MmZeroedPageListHead;
-MMPFNLIST MmFreePageListHead;
-MMPFNLIST MmStandbyPageListHead;
-MMPFNLIST MmModifiedPageListHead;
-MMPFNLIST MmModifiedNoWritePageListHead;
-
+MMPFNLIST MmZeroedPageListHead = {0, ZeroedPageList, LIST_HEAD, LIST_HEAD};
+MMPFNLIST MmFreePageListHead = {0, FreePageList, LIST_HEAD, LIST_HEAD};
+MMPFNLIST MmStandbyPageListHead = {0, StandbyPageList, LIST_HEAD, LIST_HEAD};
+MMPFNLIST MmModifiedPageListHead = {0, ModifiedPageList, LIST_HEAD, LIST_HEAD};
+MMPFNLIST MmModifiedNoWritePageListHead = {0, ModifiedNoWritePageList, LIST_HEAD, LIST_HEAD};
+MMPFNLIST MmBadPageListHead = {0, BadPageList, LIST_HEAD, LIST_HEAD};
+MMPFNLIST MmRomPageListHead = {0, StandbyPageList, LIST_HEAD, LIST_HEAD};
+
+PMMPFNLIST MmPageLocationList[] =
+{
+ &MmZeroedPageListHead,
+ &MmFreePageListHead,
+ &MmStandbyPageListHead,
+ &MmModifiedPageListHead,
+ &MmModifiedNoWritePageListHead,
+ &MmBadPageListHead,
+ NULL,
+ NULL
+};
/* FUNCTIONS ******************************************************************/
VOID
@@ -57,25 +70,28 @@
VOID
NTAPI
-MiRemoveFromList(IN PMMPFN Entry)
+MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry)
{
PFN_NUMBER OldFlink, OldBlink;
PMMPFNLIST ListHead;
-
- /* Find the list for this */
- if (Entry->u3.e1.PageLocation == ZeroedPageList)
- {
- ListHead = &MmZeroedPageListHead;
- }
- else if (Entry->u3.e1.PageLocation == FreePageList)
- {
- ListHead = &MmFreePageListHead;
- }
- else
- {
- ListHead = NULL;
- ASSERT(ListHead != NULL);
- }
+ MMLISTS ListName;
+
+ /* Make sure the PFN lock is held */
+ ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
+
+ /* Make sure the PFN entry isn't in-use */
+ ASSERT(Entry->u3.e1.WriteInProgress == 0);
+ ASSERT(Entry->u3.e1.ReadInProgress == 0);
+
+ /* Find the list for this entry, make sure it's the free or zero list */
+ ListHead = MmPageLocationList[Entry->u3.e1.PageLocation];
+ ListName = ListHead->ListName;
+ ASSERT(ListHead != NULL);
+ ASSERT(ListName <= FreePageList);
+
+ /* Remove one count */
+ ASSERT(ListHead->Total != 0);
+ ListHead->Total--;
/* Get the forward and back pointers */
OldFlink = Entry->u1.Flink;
@@ -106,8 +122,27 @@
}
/* We are not on a list anymore */
- ListHead->Total--;
Entry->u1.Flink = Entry->u2.Blink = 0;
+
+ /* FIXME: Deal with color list */
+
+ /* See if we hit any thresholds */
+ if (MmAvailablePages == MmHighMemoryThreshold)
+ {
+ /* Clear the high memory event */
+ KeClearEvent(MiHighMemoryEvent);
+ }
+ else if (MmAvailablePages == MmLowMemoryThreshold)
+ {
+ /* Signal the low memory event */
+ KeSetEvent(MiLowMemoryEvent, 0, FALSE);
+ }
+
+ /* One less page */
+ if (--MmAvailablePages < MmMinimumFreePages)
+ {
+ /* FIXME: Should wake up the MPW and working set manager, if we had one */
+ }
}
PMMPFN
Modified: trunk/reactos/ntoskrnl/mm/ARM3/pool.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/pool.c?re…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/pool.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/pool.c [iso-8859-1] Sat Feb 20 22:48:36 2010
@@ -31,7 +31,97 @@
VOID
NTAPI
-MiInitializeArmPool(VOID)
+MiInitializeNonPagedPoolThresholds(VOID)
+{
+ PFN_NUMBER Size = MmMaximumNonPagedPoolInPages;
+
+ /* Default low threshold of 8MB or one third of nonpaged pool */
+ MiLowNonPagedPoolThreshold = (8 * _1MB) >> PAGE_SHIFT;
+ MiLowNonPagedPoolThreshold = min(MiLowNonPagedPoolThreshold, Size / 3);
+
+ /* Default high threshold of 20MB or 50% */
+ MiHighNonPagedPoolThreshold = (20 * _1MB) >> PAGE_SHIFT;
+ MiHighNonPagedPoolThreshold = min(MiHighNonPagedPoolThreshold, Size / 2);
+ ASSERT(MiLowNonPagedPoolThreshold < MiHighNonPagedPoolThreshold);
+}
+
+VOID
+NTAPI
+MiInitializePoolEvents(VOID)
+{
+ KIRQL OldIrql;
+ PFN_NUMBER FreePoolInPages;
+
+ /* Lock paged pool */
+ KeAcquireGuardedMutex(&MmPagedPoolMutex);
+
+ /* Total size of the paged pool minus the allocated size, is free */
+ FreePoolInPages = MmSizeOfPagedPoolInPages - MmPagedPoolInfo.AllocatedPagedPool;
+
+ /* Check the initial state high state */
+ if (FreePoolInPages >= MiHighPagedPoolThreshold)
+ {
+ /* We have plenty of pool */
+ KeSetEvent(MiHighPagedPoolEvent, 0, FALSE);
+ }
+ else
+ {
+ /* We don't */
+ KeClearEvent(MiHighPagedPoolEvent);
+ }
+
+ /* Check the initial low state */
+ if (FreePoolInPages <= MiLowPagedPoolThreshold)
+ {
+ /* We're very low in free pool memory */
+ KeSetEvent(MiLowPagedPoolEvent, 0, FALSE);
+ }
+ else
+ {
+ /* We're not */
+ KeClearEvent(MiLowPagedPoolEvent);
+ }
+
+ /* Release the paged pool lock */
+ KeReleaseGuardedMutex(&MmPagedPoolMutex);
+
+ /* Now it's time for the nonpaged pool lock */
+ OldIrql = KeAcquireQueuedSpinLock(LockQueueMmNonPagedPoolLock);
+
+ /* Free pages are the maximum minus what's been allocated */
+ FreePoolInPages = MmMaximumNonPagedPoolInPages - MmAllocatedNonPagedPool;
+
+ /* Check if we have plenty */
+ if (FreePoolInPages >= MiHighNonPagedPoolThreshold)
+ {
+ /* We do, set the event */
+ KeSetEvent(MiHighNonPagedPoolEvent, 0, FALSE);
+ }
+ else
+ {
+ /* We don't, clear the event */
+ KeClearEvent(MiHighNonPagedPoolEvent);
+ }
+
+ /* Check if we have very little */
+ if (FreePoolInPages <= MiLowNonPagedPoolThreshold)
+ {
+ /* We do, set the event */
+ KeSetEvent(MiLowNonPagedPoolEvent, 0, FALSE);
+ }
+ else
+ {
+ /* We don't, clear it */
+ KeClearEvent(MiLowNonPagedPoolEvent);
+ }
+
+ /* We're done, release the nonpaged pool lock */
+ KeReleaseQueuedSpinLock(LockQueueMmNonPagedPoolLock, OldIrql);
+}
+
+VOID
+NTAPI
+MiInitializeNonPagedPool(VOID)
{
ULONG i;
PFN_NUMBER PoolPages;
Modified: trunk/reactos/ntoskrnl/mm/freelist.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/freelist.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/freelist.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/freelist.c [iso-8859-1] Sat Feb 20 22:48:36 2010
@@ -245,14 +245,9 @@
do
{
//
- // One less free page
- //
- MmAvailablePages--;
-
- //
// This PFN is now a used page, set it up
//
- MiRemoveFromList(Pfn1);
+ MiUnlinkFreeOrZeroedPage(Pfn1);
Pfn1->u3.e2.ReferenceCount = 1;
//
@@ -638,12 +633,6 @@
PMEMORY_ALLOCATION_DESCRIPTOR Md;
PLIST_ENTRY NextEntry;
ULONG NrSystemPages = 0;
-
- /* Initialize the page lists */
- MmFreePageListHead.Flink = MmFreePageListHead.Blink = LIST_HEAD;
- MmZeroedPageListHead.Flink = MmZeroedPageListHead.Blink = LIST_HEAD;
- MmZeroedPageListHead.Total = 0;
- MmFreePageListHead.Total = 0;
/* This is what a used page looks like */
RtlZeroMemory(&UsedPage, sizeof(UsedPage));
Modified: trunk/reactos/ntoskrnl/mm/mminit.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/mminit.c?rev=4…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/mminit.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/mminit.c [iso-8859-1] Sat Feb 20 22:48:36 2010
@@ -402,25 +402,11 @@
MiInitializeUserPfnBitmap();
MmInitializeMemoryConsumer(MC_USER, MmTrimUserMemory);
- /* Initialize the user mode image list */
- InitializeListHead(&MmLoadedUserImageList);
-
- /* Initialize the Loader Lock */
- KeInitializeMutant(&MmSystemLoadLock, FALSE);
-
/* Reload boot drivers */
MiReloadBootLoadedDrivers(LoaderBlock);
/* Initialize the loaded module list */
MiInitializeLoadedModuleList(LoaderBlock);
-
- /* Setup shared user data settings that NT does as well */
- ASSERT(SharedUserData->NumberOfPhysicalPages == 0);
- SharedUserData->NumberOfPhysicalPages = MmNumberOfPhysicalPages;
- SharedUserData->LargePageMinimum = 0;
-
- /* For now, we assume that we're always Server */
- SharedUserData->NtProductType = NtProductServer;
}
else if (Phase == 1)
{
@@ -454,6 +440,9 @@
TempPte.u.Hard.PageFrameNumber = PageFrameNumber;
*MmSharedUserDataPte = TempPte;
+ /* Setup the memory threshold events */
+ if (!MiInitializeMemoryEvents()) return FALSE;
+
/*
* Unmap low memory
*/
Author: sir_richard
Date: Sat Feb 20 15:40:21 2010
New Revision: 45634
URL: http://svn.reactos.org/svn/reactos?rev=45634&view=rev
Log:
[NTOS]: Manage the PFN lists using the correct Flink/Blink semantics of the MMPFN structure, instead of typecasting a LIST_ENTRY on top of Flink and PteAddress. This allows PteAddress to be used now, and minimizes the number of differences between MMPFN and the ReactOS PHYSICAL_PAGE.
[NTOS]: Zero pages starting at the head of the free list, insert them at the back.
[NTOS]: Add MiInsertPageInFreeList to build the colored lists (not yet used) in the ARM3 PFN database.
[NTOS]: Rename the ReactOS PFN lists for free/zero to their real names as used in Windows.
Added:
trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c (with props)
Modified:
trunk/reactos/ntoskrnl/mm/ARM3/miarm.h
trunk/reactos/ntoskrnl/mm/freelist.c
trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild
Modified: trunk/reactos/ntoskrnl/mm/ARM3/miarm.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/miarm.h?r…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] Sat Feb 20 15:40:21 2010
@@ -58,6 +58,11 @@
#else
#error Define these please!
#endif
+
+//
+// PFN List Sentinel
+//
+#define LIST_HEAD 0xFFFFFFFF
//
// FIXFIX: These should go in ex.h after the pool merge
@@ -211,6 +216,7 @@
extern ULONG MmNumberOfSystemPtes;
extern ULONG MmMaximumNonPagedPoolPercent;
extern ULONG MmLargeStackSize;
+extern PMMCOLOR_TABLES MmFreePagesByColor[FreePageList + 1];
#define MI_PFN_TO_PFNENTRY(x) (&MmPfnDatabase[1][x])
#define MI_PFNENTRY_TO_PFN(x) (x - MmPfnDatabase[1])
@@ -374,4 +380,30 @@
IN PMDL Mdl
);
+VOID
+NTAPI
+MiInsertInListTail(
+ IN PMMPFNLIST ListHead,
+ IN PMMPFN Entry
+);
+
+VOID
+NTAPI
+MiRemoveFromList(
+ IN PMMPFN Entry
+);
+
+PMMPFN
+NTAPI
+MiRemoveHeadList(
+ IN PMMPFNLIST ListHead
+);
+
+
+VOID
+NTAPI
+MiInsertPageInFreeList(
+ IN PFN_NUMBER PageFrameIndex
+);
+
/* EOF */
Added: trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c (added)
+++ trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c [iso-8859-1] Sat Feb 20 15:40:21 2010
@@ -1,0 +1,240 @@
+/*
+ * PROJECT: ReactOS Kernel
+ * LICENSE: BSD - See COPYING.ARM in the top level directory
+ * FILE: ntoskrnl/mm/ARM3/pfnlist.c
+ * PURPOSE: ARM Memory Manager PFN List Manipulation
+ * PROGRAMMERS: ReactOS Portable Systems Group
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <debug.h>
+
+#line 15 "ARM³::PFNLIST"
+#define MODULE_INVOLVED_IN_ARM3
+#include "../ARM3/miarm.h"
+
+/* GLOBALS ********************************************************************/
+
+MMPFNLIST MmZeroedPageListHead;
+MMPFNLIST MmFreePageListHead;
+MMPFNLIST MmStandbyPageListHead;
+MMPFNLIST MmModifiedPageListHead;
+MMPFNLIST MmModifiedNoWritePageListHead;
+
+/* FUNCTIONS ******************************************************************/
+
+VOID
+NTAPI
+MiInsertInListTail(IN PMMPFNLIST ListHead,
+ IN PMMPFN Entry)
+{
+ PFN_NUMBER OldBlink, EntryIndex = MiGetPfnEntryIndex(Entry);
+
+ /* Get the back link */
+ OldBlink = ListHead->Blink;
+ if (OldBlink != LIST_HEAD)
+ {
+ /* Set the back pointer to point to us now */
+ MiGetPfnEntry(OldBlink)->u1.Flink = EntryIndex;
+ }
+ else
+ {
+ /* Set the list to point to us */
+ ListHead->Flink = EntryIndex;
+ }
+
+ /* Set the entry to point to the list head forwards, and the old page backwards */
+ Entry->u1.Flink = LIST_HEAD;
+ Entry->u2.Blink = OldBlink;
+
+ /* And now the head points back to us, since we are last */
+ ListHead->Blink = EntryIndex;
+ ListHead->Total++;
+}
+
+VOID
+NTAPI
+MiRemoveFromList(IN PMMPFN Entry)
+{
+ PFN_NUMBER OldFlink, OldBlink;
+ PMMPFNLIST ListHead;
+
+ /* Find the list for this */
+ if (Entry->u3.e1.PageLocation == ZeroedPageList)
+ {
+ ListHead = &MmZeroedPageListHead;
+ }
+ else if (Entry->u3.e1.PageLocation == FreePageList)
+ {
+ ListHead = &MmFreePageListHead;
+ }
+ else
+ {
+ ListHead = NULL;
+ ASSERT(ListHead != NULL);
+ }
+
+ /* Get the forward and back pointers */
+ OldFlink = Entry->u1.Flink;
+ OldBlink = Entry->u2.Blink;
+
+ /* Check if the next entry is the list head */
+ if (OldFlink != LIST_HEAD)
+ {
+ /* It is not, so set the backlink of the actual entry, to our backlink */
+ MiGetPfnEntry(OldFlink)->u2.Blink = OldBlink;
+ }
+ else
+ {
+ /* Set the list head's backlink instead */
+ ListHead->Blink = OldFlink;
+ }
+
+ /* Check if the back entry is the list head */
+ if (OldBlink != LIST_HEAD)
+ {
+ /* It is not, so set the backlink of the actual entry, to our backlink */
+ MiGetPfnEntry(OldBlink)->u1.Flink = OldFlink;
+ }
+ else
+ {
+ /* Set the list head's backlink instead */
+ ListHead->Flink = OldFlink;
+ }
+
+ /* We are not on a list anymore */
+ ListHead->Total--;
+ Entry->u1.Flink = Entry->u2.Blink = 0;
+}
+
+PMMPFN
+NTAPI
+MiRemoveHeadList(IN PMMPFNLIST ListHead)
+{
+ PFN_NUMBER Entry, Flink;
+ PMMPFN Pfn1;
+
+ /* Get the entry that's currently first on the list */
+ Entry = ListHead->Flink;
+ Pfn1 = MiGetPfnEntry(Entry);
+
+ /* Make the list point to the entry following the first one */
+ Flink = Pfn1->u1.Flink;
+ ListHead->Flink = Flink;
+
+ /* Check if the next entry is actually the list head */
+ if (ListHead->Flink != LIST_HEAD)
+ {
+ /* It isn't, so therefore whoever is coming next points back to the head */
+ MiGetPfnEntry(Flink)->u2.Blink = LIST_HEAD;
+ }
+ else
+ {
+ /* Then the list is empty, so the backlink should point back to us */
+ ListHead->Blink = LIST_HEAD;
+ }
+
+ /* We are not on a list anymore */
+ Pfn1->u1.Flink = Pfn1->u2.Blink = 0;
+ ListHead->Total--;
+
+ /* Return the head element */
+ return Pfn1;
+}
+
+VOID
+NTAPI
+MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
+{
+ MMLISTS ListName;
+ PMMPFNLIST ListHead;
+ PFN_NUMBER LastPage;
+ PMMPFN Pfn1, Blink;
+ ULONG Color;
+ PMMCOLOR_TABLES ColorHead;
+
+ /* Make sure the page index is valid */
+ ASSERT((PageFrameIndex != 0) &&
+ (PageFrameIndex <= MmHighestPhysicalPage) &&
+ (PageFrameIndex >= MmLowestPhysicalPage));
+
+ /* Get the PFN entry */
+ Pfn1 = MI_PFN_TO_PFNENTRY(PageFrameIndex);
+
+ /* Sanity checks that a right kind of page is being inserted here */
+ ASSERT(Pfn1->u4.MustBeCached == 0);
+ ASSERT(Pfn1->u3.e1.Rom != 1);
+ ASSERT(Pfn1->u3.e1.RemovalRequested == 0);
+ ASSERT(Pfn1->u4.VerifierAllocation == 0);
+ ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
+
+ /* Get the free page list and increment its count */
+ ListHead = &MmFreePageListHead;
+ ListName = FreePageList;
+ ListHead->Total++;
+
+ /* Get the last page on the list */
+ LastPage = ListHead->Blink;
+ if (LastPage != -1)
+ {
+ /* Link us with the previous page, so we're at the end now */
+ MI_PFN_TO_PFNENTRY(LastPage)->u1.Flink = PageFrameIndex;
+ }
+ else
+ {
+ /* The list is empty, so we are the first page */
+ ListHead->Flink = PageFrameIndex;
+ }
+
+ /* Now make the list head point back to us (since we go at the end) */
+ ListHead->Blink = PageFrameIndex;
+
+ /* And initialize our own list pointers */
+ Pfn1->u1.Flink = -1;
+ Pfn1->u2.Blink = LastPage;
+
+ /* Set the list name and default priority */
+ Pfn1->u3.e1.PageLocation = ListName;
+ Pfn1->u4.Priority = 3;
+
+ /* Clear some status fields */
+ Pfn1->u4.InPageError = 0;
+ Pfn1->u4.AweAllocation = 0;
+
+ /* FIXME: More work to be done regarding page accounting */
+
+ /* Get the page color */
+ Color = PageFrameIndex & MmSecondaryColorMask;
+
+ /* Get the first page on the color list */
+ ColorHead = &MmFreePagesByColor[ListName][Color];
+ if (ColorHead->Flink == -1)
+ {
+ /* The list is empty, so we are the first page */
+ Pfn1->u4.PteFrame = -1;
+ ColorHead->Flink = PageFrameIndex;
+ }
+ else
+ {
+ /* Get the previous page */
+ Blink = (PMMPFN)ColorHead->Blink;
+
+ /* Make it link to us */
+ Pfn1->u4.PteFrame = MI_PFNENTRY_TO_PFN(Blink);
+ Blink->OriginalPte.u.Long = PageFrameIndex;
+ }
+
+ /* Now initialize our own list pointers */
+ ColorHead->Blink = Pfn1;
+ Pfn1->OriginalPte.u.Long = -1;
+
+ /* And increase the count in the colored list */
+ ColorHead->Count++;
+
+ /* FIXME: Notify zero page thread if enough pages are on the free list now */
+}
+
+/* EOF */
Propchange: trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/ntoskrnl/mm/freelist.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/freelist.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/freelist.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/freelist.c [iso-8859-1] Sat Feb 20 15:40:21 2010
@@ -31,9 +31,6 @@
//
#define RmapListHead AweReferenceCount
#define SavedSwapEntry u4.EntireFrame
-#define RemoveEntryList(x) RemoveEntryList((PLIST_ENTRY)x)
-#define InsertTailList(x, y) InsertTailList(x, (PLIST_ENTRY)y)
-#define ListEntry u1
#define PHYSICAL_PAGE MMPFN
#define PPHYSICAL_PAGE PMMPFN
@@ -52,25 +49,8 @@
SIZE_T MmPeakCommitment;
SIZE_T MmtotalCommitLimitMaximum;
-MMPFNLIST MmZeroedPageListHead;
-MMPFNLIST MmFreePageListHead;
-MMPFNLIST MmStandbyPageListHead;
-MMPFNLIST MmModifiedPageListHead;
-MMPFNLIST MmModifiedNoWritePageListHead;
-
-/* List of pages zeroed by the ZPW (MmZeroPageThreadMain) */
-static LIST_ENTRY FreeZeroedPageListHead;
-/* List of free pages, filled by MmGetReferenceCountPage and
- * and MmInitializePageList */
-static LIST_ENTRY FreeUnzeroedPageListHead;
-
static KEVENT ZeroPageThreadEvent;
static BOOLEAN ZeroPageThreadShouldTerminate = FALSE;
-
-static ULONG UnzeroedPageCount = 0;
-
-/* FUNCTIONS *************************************************************/
-
static RTL_BITMAP MiUserPfnBitMap;
/* FUNCTIONS *************************************************************/
@@ -153,7 +133,7 @@
MiIsPfnInUse(IN PMMPFN Pfn1)
{
return ((Pfn1->u3.e1.PageLocation != FreePageList) &&
- (Pfn1->u3.e1.PageLocation != ZeroedPageList));
+ (Pfn1->u3.e1.PageLocation != ZeroedPageList));
}
PFN_NUMBER
@@ -266,11 +246,6 @@
do
{
//
- // If this was an unzeroed page, there are now less
- //
- if (Pfn1->u3.e1.PageLocation == ZeroedPageList) UnzeroedPageCount--;
-
- //
// One less free page
//
MmAvailablePages--;
@@ -278,7 +253,7 @@
//
// This PFN is now a used page, set it up
//
- RemoveEntryList(&Pfn1->ListEntry);
+ MiRemoveFromList(Pfn1);
Pfn1->u3.e2.ReferenceCount = 1;
Pfn1->SavedSwapEntry = 0;
@@ -368,7 +343,6 @@
PFN_NUMBER PageCount, LowPage, HighPage, SkipPages, PagesFound = 0, Page;
PPFN_NUMBER MdlPage, LastMdlPage;
KIRQL OldIrql;
- PLIST_ENTRY ListEntry;
PPHYSICAL_PAGE Pfn1;
INT LookForZeroedPages;
ASSERT (KeGetCurrentIrql() <= APC_LEVEL);
@@ -439,20 +413,19 @@
//
// Do we have zeroed pages?
//
- if (!IsListEmpty(&FreeZeroedPageListHead))
+ if (MmZeroedPageListHead.Total)
{
//
// Grab a zero page
//
- ListEntry = RemoveTailList(&FreeZeroedPageListHead);
+ Pfn1 = MiRemoveHeadList(&MmZeroedPageListHead);
}
- else if (!IsListEmpty(&FreeUnzeroedPageListHead))
+ else if (MmFreePageListHead.Total)
{
//
// Nope, grab an unzeroed page
//
- ListEntry = RemoveTailList(&FreeUnzeroedPageListHead);
- UnzeroedPageCount--;
+ Pfn1 = MiRemoveHeadList(&MmFreePageListHead);
}
else
{
@@ -462,11 +435,6 @@
ASSERT(PagesFound);
break;
}
-
- //
- // Get the PFN entry for this page
- //
- Pfn1 = CONTAINING_RECORD(ListEntry, PHYSICAL_PAGE, ListEntry);
//
// Make sure it's really free
@@ -530,12 +498,7 @@
Pfn1->u3.e1.StartOfAllocation = 1;
Pfn1->u3.e1.EndOfAllocation = 1;
Pfn1->SavedSwapEntry = 0;
-
- //
- // If this page was unzeroed, we've consumed such a page
- //
- if (Pfn1->u3.e1.PageLocation != ZeroedPageList) UnzeroedPageCount--;
-
+
//
// Decrease available pages
//
@@ -681,8 +644,10 @@
ULONG NrSystemPages = 0;
/* Initialize the page lists */
- InitializeListHead(&FreeUnzeroedPageListHead);
- InitializeListHead(&FreeZeroedPageListHead);
+ MmFreePageListHead.Flink = MmFreePageListHead.Blink = LIST_HEAD;
+ MmZeroedPageListHead.Flink = MmZeroedPageListHead.Blink = LIST_HEAD;
+ MmZeroedPageListHead.Total = 0;
+ MmFreePageListHead.Total = 0;
/* This is what a used page looks like */
RtlZeroMemory(&UsedPage, sizeof(UsedPage));
@@ -694,12 +659,10 @@
NextEntry != &KeLoaderBlock->MemoryDescriptorListHead;
NextEntry = NextEntry->Flink)
{
-#undef ListEntry
/* Get the descriptor */
Md = CONTAINING_RECORD(NextEntry,
MEMORY_ALLOCATION_DESCRIPTOR,
ListEntry);
-#define ListEntry u1
/* Skip bad memory */
if ((Md->MemoryType == LoaderFirmwarePermanent) ||
@@ -722,9 +685,8 @@
{
/* Mark it as a free page */
MmPfnDatabase[0][Md->BasePage + i].u3.e1.PageLocation = FreePageList;
- InsertTailList(&FreeUnzeroedPageListHead,
- &MmPfnDatabase[0][Md->BasePage + i].ListEntry);
- UnzeroedPageCount++;
+ MiInsertInListTail(&MmFreePageListHead,
+ &MmPfnDatabase[0][Md->BasePage + i]);
MmAvailablePages++;
}
}
@@ -873,10 +835,8 @@
{
MmAvailablePages++;
Page->u3.e1.PageLocation = FreePageList;
- InsertTailList(&FreeUnzeroedPageListHead,
- &Page->ListEntry);
- UnzeroedPageCount++;
- if (UnzeroedPageCount > 8 && 0 == KeReadStateEvent(&ZeroPageThreadEvent))
+ MiInsertInListTail(&MmFreePageListHead, Page);
+ if (MmFreePageListHead.Total > 8 && 0 == KeReadStateEvent(&ZeroPageThreadEvent))
{
KeSetEvent(&ZeroPageThreadEvent, IO_NO_INCREMENT, FALSE);
}
@@ -888,16 +848,15 @@
MmAllocPage(ULONG Type, SWAPENTRY SwapEntry)
{
PFN_TYPE PfnOffset;
- PLIST_ENTRY ListEntry;
PPHYSICAL_PAGE PageDescriptor;
BOOLEAN NeedClear = FALSE;
DPRINT("MmAllocPage()\n");
- if (IsListEmpty(&FreeZeroedPageListHead))
+ if (MmZeroedPageListHead.Total == 0)
{
- if (IsListEmpty(&FreeUnzeroedPageListHead))
- {
+ if (MmFreePageListHead.Total == 0)
+ {
/* Check if this allocation is for the PFN DB itself */
if (MmNumberOfPhysicalPages == 0)
{
@@ -907,18 +866,13 @@
DPRINT1("MmAllocPage(): Out of memory\n");
return 0;
}
- ListEntry = RemoveTailList(&FreeUnzeroedPageListHead);
- UnzeroedPageCount--;
-
- PageDescriptor = CONTAINING_RECORD(ListEntry, PHYSICAL_PAGE, ListEntry);
+ PageDescriptor = MiRemoveHeadList(&MmFreePageListHead);
NeedClear = TRUE;
}
else
{
- ListEntry = RemoveTailList(&FreeZeroedPageListHead);
-
- PageDescriptor = CONTAINING_RECORD(ListEntry, PHYSICAL_PAGE, ListEntry);
+ PageDescriptor = MiRemoveHeadList(&MmZeroedPageListHead);
}
PageDescriptor->u3.e2.ReferenceCount = 1;
@@ -931,7 +885,7 @@
{
MiZeroPage(PfnOffset);
}
-
+
PageDescriptor->u3.e1.PageLocation = ActiveAndValid;
return PfnOffset;
}
@@ -961,7 +915,6 @@
{
NTSTATUS Status;
KIRQL oldIrql;
- PLIST_ENTRY ListEntry;
PPHYSICAL_PAGE PageDescriptor;
PFN_TYPE Pfn;
ULONG Count;
@@ -988,11 +941,9 @@
}
Count = 0;
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
- while (!IsListEmpty(&FreeUnzeroedPageListHead))
+ while (MmFreePageListHead.Total)
{
- ListEntry = RemoveTailList(&FreeUnzeroedPageListHead);
- UnzeroedPageCount--;
- PageDescriptor = CONTAINING_RECORD(ListEntry, PHYSICAL_PAGE, ListEntry);
+ PageDescriptor = MiRemoveHeadList(&MmFreePageListHead);
/* We set the page to used, because MmCreateVirtualMapping failed with unused pages */
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
Pfn = PageDescriptor - MmPfnDatabase[0];
@@ -1001,15 +952,14 @@
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
if (NT_SUCCESS(Status))
{
- InsertHeadList(&FreeZeroedPageListHead, ListEntry);
+ MiInsertInListTail(&MmZeroedPageListHead, PageDescriptor);
PageDescriptor->u3.e1.PageLocation = ZeroedPageList;
Count++;
}
else
{
- InsertHeadList(&FreeUnzeroedPageListHead, ListEntry);
+ MiInsertInListTail(&MmFreePageListHead, PageDescriptor);
PageDescriptor->u3.e1.PageLocation = FreePageList;
- UnzeroedPageCount++;
}
}
Modified: trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ntoskrnl-generic.…
==============================================================================
--- trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ntoskrnl-generic.rbuild [iso-8859-1] Sat Feb 20 15:40:21 2010
@@ -394,6 +394,7 @@
<file>mmsup.c</file>
<file>ncache.c</file>
<file>pagfault.c</file>
+ <file>pfnlist.c</file>
<file>pool.c</file>
<file>procsup.c</file>
<file>syspte.c</file>