mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
Corrected bug where user32.a wasn't being cleaned
Corrected bugs in paging implementation Began work on MPW thread svn path=/trunk/; revision=1251
This commit is contained in:
parent
0ea1d03808
commit
8689a5cfe9
18 changed files with 432 additions and 180 deletions
|
@ -1,6 +1,6 @@
|
|||
#ifndef _INCLUDE_DDK_IOFUNCS_H
|
||||
#define _INCLUDE_DDK_IOFUNCS_H
|
||||
/* $Id: iofuncs.h,v 1.17 2000/07/04 08:52:34 dwelch Exp $ */
|
||||
/* $Id: iofuncs.h,v 1.18 2000/07/07 10:30:54 dwelch Exp $ */
|
||||
|
||||
/* --- EXPORTED BY NTOSKRNL --- */
|
||||
|
||||
|
@ -777,14 +777,6 @@ IoOpenDeviceInstanceKey (
|
|||
);
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
IoPageRead (
|
||||
PFILE_OBJECT FileObject,
|
||||
PMDL Mdl,
|
||||
PLARGE_INTEGER Offset,
|
||||
PIO_STATUS_BLOCK StatusBlock
|
||||
);
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
IoQueryDeviceDescription (
|
||||
PINTERFACE_TYPE BusType,
|
||||
PULONG BusNumber,
|
||||
|
|
|
@ -1,10 +1,18 @@
|
|||
/* $Id: mmtypes.h,v 1.8 2000/07/04 08:52:34 dwelch Exp $ */
|
||||
/* $Id: mmtypes.h,v 1.9 2000/07/07 10:30:54 dwelch Exp $ */
|
||||
|
||||
#ifndef _INCLUDE_DDK_MMTYPES_H
|
||||
#define _INCLUDE_DDK_MMTYPES_H
|
||||
|
||||
#include <ntos/mm.h>
|
||||
|
||||
#ifdef __NTOSKRNL__
|
||||
PVOID EXPORTED MmUserProbeAddress;
|
||||
PVOID EXPORTED MmHighestUserAddress;
|
||||
#else
|
||||
PVOID IMPORTED MmUserProbeAddress;
|
||||
PVOID IMPORTED MmHighestUserAddress;
|
||||
#endif
|
||||
|
||||
#ifdef __NTOSKRNL__
|
||||
extern POBJECT_TYPE EXPORTED MmSectionObjectType;
|
||||
#else
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $Id: makefile,v 1.11 2000/06/16 07:34:15 jfilby Exp $
|
||||
# $Id: makefile,v 1.12 2000/07/07 10:30:54 dwelch Exp $
|
||||
#
|
||||
# Makefile for ReactOS gdi32.dll
|
||||
#
|
||||
|
@ -67,9 +67,9 @@ $(TARGET).dll: $(DLLMAIN) $(OBJECTS) $(TARGET).def
|
|||
$(NM) --numeric-sort $(TARGET).dll > $(TARGET).sym
|
||||
|
||||
ifeq ($(DOSCLI),yes)
|
||||
CLEAN_FILES = *.o *.coff *.sym *.tmp *.dll main\*.o misc\*.o
|
||||
CLEAN_FILES = *.a *.o *.coff *.sym *.tmp *.dll main\*.o misc\*.o
|
||||
else
|
||||
CLEAN_FILES = *.o *.coff *.sym *.tmp *.dll main/*.o misc/*.o
|
||||
CLEAN_FILES = *.a *.o *.coff *.sym *.tmp *.dll main/*.o misc/*.o
|
||||
endif
|
||||
|
||||
clean: $(CLEAN_FILES:%=%_clean)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: io.h,v 1.2 2000/07/07 02:09:51 ekohl Exp $
|
||||
/* $Id: io.h,v 1.3 2000/07/07 10:30:55 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -60,5 +60,13 @@ PIRP IoBuildSynchronousFsdRequestWithMdl(ULONG MajorFunction,
|
|||
PKEVENT Event,
|
||||
PIO_STATUS_BLOCK IoStatusBlock);
|
||||
VOID IoShutdownIoManager(VOID);
|
||||
NTSTATUS STDCALL IoPageRead (PFILE_OBJECT FileObject,
|
||||
PMDL Mdl,
|
||||
PLARGE_INTEGER Offset,
|
||||
PIO_STATUS_BLOCK StatusBlock);
|
||||
NTSTATUS STDCALL IoPageWrite (PFILE_OBJECT FileObject,
|
||||
PMDL Mdl,
|
||||
PLARGE_INTEGER Offset,
|
||||
PIO_STATUS_BLOCK StatusBlock);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -253,4 +253,37 @@ PVOID MmMustAllocPage(SWAPENTRY SavedSwapEntry);
|
|||
PVOID MmAllocPageMaybeSwap(SWAPENTRY SavedSwapEntry);
|
||||
NTSTATUS MmCreatePageTable(PVOID PAddress);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ULONG NrTotalPages;
|
||||
ULONG NrSystemPages;
|
||||
ULONG NrReservedPages;
|
||||
ULONG NrUserPages;
|
||||
ULONG NrFreePages;
|
||||
ULONG NrDirtyPages;
|
||||
ULONG PagingRequestsInLastMinute;
|
||||
ULONG PagingRequestsInLastFiveMinutes;
|
||||
ULONG PagingRequestsInLastFifteenMinutes;
|
||||
} MM_STATS;
|
||||
|
||||
extern MM_STATS MmStats;
|
||||
|
||||
NTSTATUS MmWritePageSectionView(PMADDRESS_SPACE AddressSpace,
|
||||
PMEMORY_AREA MArea,
|
||||
PVOID Address);
|
||||
NTSTATUS MmWritePageVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||
PMEMORY_AREA MArea,
|
||||
PVOID Address);
|
||||
PVOID MmGetDirtyPagesFromWorkingSet(struct _EPROCESS* Process);
|
||||
NTSTATUS MmWriteToSwapPage(SWAPENTRY SwapEntry, PMDL Mdl);
|
||||
NTSTATUS MmReadFromSwapPage(SWAPENTRY SwapEntry, PMDL Mdl);
|
||||
VOID MmSetFlagsPage(PVOID PhysicalAddress, ULONG Flags);
|
||||
ULONG MmGetFlagsPage(PVOID PhysicalAddress);
|
||||
VOID MmSetSavedSwapEntryPage(PVOID PhysicalAddress,
|
||||
SWAPENTRY SavedSwapEntry);
|
||||
SWAPENTRY MmGetSavedSwapEntryPage(PVOID PhysicalAddress);
|
||||
VOID MmSetCleanPage(struct _EPROCESS* Process, PVOID Address);
|
||||
|
||||
#define MM_PHYSICAL_PAGE_MPW_PENDING (0x8)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: page.c,v 1.8 2000/04/07 02:23:59 dwelch Exp $
|
||||
/* $Id: page.c,v 1.9 2000/07/07 10:30:55 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -19,6 +19,54 @@
|
|||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
NTSTATUS STDCALL IoPageWrite(PFILE_OBJECT FileObject,
|
||||
PMDL Mdl,
|
||||
PLARGE_INTEGER Offset,
|
||||
PIO_STATUS_BLOCK StatusBlock)
|
||||
{
|
||||
PIRP Irp;
|
||||
KEVENT Event;
|
||||
PIO_STACK_LOCATION StackPtr;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("IoPageWrite(FileObject %x, Mdl %x)\n",
|
||||
FileObject, Mdl);
|
||||
|
||||
ObReferenceObjectByPointer(FileObject,
|
||||
STANDARD_RIGHTS_REQUIRED,
|
||||
IoFileObjectType,
|
||||
UserMode);
|
||||
|
||||
KeInitializeEvent(&Event,NotificationEvent,FALSE);
|
||||
Irp = IoBuildSynchronousFsdRequestWithMdl(IRP_MJ_WRITE,
|
||||
FileObject->DeviceObject,
|
||||
Mdl,
|
||||
Offset,
|
||||
&Event,
|
||||
StatusBlock);
|
||||
StackPtr = IoGetNextIrpStackLocation(Irp);
|
||||
StackPtr->FileObject = FileObject;
|
||||
DPRINT("Before IoCallDriver\n");
|
||||
Status = IoCallDriver(FileObject->DeviceObject,Irp);
|
||||
DPRINT("Status %d STATUS_PENDING %d\n",Status,STATUS_PENDING);
|
||||
if (Status==STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO))
|
||||
{
|
||||
DPRINT("Waiting for io operation\n");
|
||||
if (FileObject->Flags & FO_ALERTABLE_IO)
|
||||
{
|
||||
KeWaitForSingleObject(&Event,Executive,KernelMode,TRUE,NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("Non-alertable wait\n");
|
||||
KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL);
|
||||
}
|
||||
Status = StatusBlock->Status;
|
||||
}
|
||||
return(Status);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS STDCALL IoPageRead(PFILE_OBJECT FileObject,
|
||||
PMDL Mdl,
|
||||
PLARGE_INTEGER Offset,
|
||||
|
|
|
@ -114,6 +114,7 @@ VOID KiSideEffectsBeforeWake(DISPATCHER_HEADER* hdr,
|
|||
KMUTEX,
|
||||
Header);
|
||||
hdr->SignalState--;
|
||||
assert(hdr->SignalState <= 1);
|
||||
Mutex->OwnerThread = Thread;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $Id: makefile_rex,v 1.80 2000/07/04 08:52:35 dwelch Exp $
|
||||
# $Id: makefile_rex,v 1.81 2000/07/07 10:30:54 dwelch Exp $
|
||||
#
|
||||
# ReactOS Operating System
|
||||
#
|
||||
|
@ -111,7 +111,8 @@ OBJECTS_MM = \
|
|||
mm/pager.o \
|
||||
mm/wset.o \
|
||||
mm/mminit.o \
|
||||
mm/kmap.o
|
||||
mm/kmap.o \
|
||||
mm/mpw.o
|
||||
|
||||
OBJECTS_MM_I386 = \
|
||||
mm/i386/memsafe.o \
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
#define PHYSICAL_PAGE_FREE (0x1)
|
||||
#define PHYSICAL_PAGE_INUSE (0x2)
|
||||
#define PHYSICAL_PAGE_BIOS (0x4)
|
||||
#define PHYSICAL_PAGE_BIOS (0x3)
|
||||
|
||||
typedef struct _PHYSICAL_PAGE
|
||||
{
|
||||
|
@ -216,6 +216,42 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
|
|||
return((PVOID)LastKernelAddress);
|
||||
}
|
||||
|
||||
VOID MmSetFlagsPage(PVOID PhysicalAddress,
|
||||
ULONG Flags)
|
||||
{
|
||||
ULONG Start = (ULONG)PhysicalAddress / PAGESIZE;
|
||||
KIRQL oldIrql;
|
||||
|
||||
KeAcquireSpinLock(&PageListLock, &oldIrql);
|
||||
MmPageArray[Start].Flags = Flags;
|
||||
KeReleaseSpinLock(&PageListLock, oldIrql);
|
||||
}
|
||||
|
||||
ULONG MmGetFlagsPage(PVOID PhysicalAddress)
|
||||
{
|
||||
ULONG Start = (ULONG)PhysicalAddress / PAGESIZE;
|
||||
KIRQL oldIrql;
|
||||
ULONG Flags;
|
||||
|
||||
KeAcquireSpinLock(&PageListLock, &oldIrql);
|
||||
Flags = MmPageArray[Start].Flags;
|
||||
KeReleaseSpinLock(&PageListLock, oldIrql);
|
||||
|
||||
return(Flags);
|
||||
}
|
||||
|
||||
|
||||
VOID MmSetSavedSwapEntryPage(PVOID PhysicalAddress,
|
||||
SWAPENTRY SavedSwapEntry)
|
||||
{
|
||||
ULONG Start = (ULONG)PhysicalAddress / PAGESIZE;
|
||||
KIRQL oldIrql;
|
||||
|
||||
KeAcquireSpinLock(&PageListLock, &oldIrql);
|
||||
MmPageArray[Start].SavedSwapEntry = SavedSwapEntry;
|
||||
KeReleaseSpinLock(&PageListLock, oldIrql);
|
||||
}
|
||||
|
||||
SWAPENTRY MmGetSavedSwapEntryPage(PVOID PhysicalAddress)
|
||||
{
|
||||
ULONG Start = (ULONG)PhysicalAddress / PAGESIZE;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: page.c,v 1.11 2000/07/06 14:34:51 dwelch Exp $
|
||||
/* $Id: page.c,v 1.12 2000/07/07 10:30:57 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -301,6 +301,24 @@ BOOLEAN MmIsPageDirty(PEPROCESS Process, PVOID Address)
|
|||
return((MmGetPageEntryForProcess(Process, Address)) & PA_DIRTY);
|
||||
}
|
||||
|
||||
VOID MmSetCleanPage(PEPROCESS Process, PVOID Address)
|
||||
{
|
||||
PULONG PageEntry;
|
||||
PEPROCESS CurrentProcess = PsGetCurrentProcess();
|
||||
|
||||
if (Process != CurrentProcess)
|
||||
{
|
||||
KeAttachProcess(Process);
|
||||
}
|
||||
PageEntry = MmGetPageEntry(Address);
|
||||
(*PageEntry) = (*PageEntry) & (~PA_DIRTY);
|
||||
FLUSH_TLB;
|
||||
if (Process != CurrentProcess)
|
||||
{
|
||||
KeDetachProcess();
|
||||
}
|
||||
}
|
||||
|
||||
BOOLEAN MmIsPagePresent(PEPROCESS Process, PVOID Address)
|
||||
{
|
||||
return((MmGetPageEntryForProcess1(Process, Address)) & PA_PRESENT);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: mdl.c,v 1.22 2000/07/06 14:34:51 dwelch Exp $
|
||||
/* $Id: mdl.c,v 1.23 2000/07/07 10:30:56 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -100,7 +100,7 @@ VOID STDCALL MmUnmapLockedPages(PVOID BaseAddress, PMDL Mdl)
|
|||
{
|
||||
DPRINT("MmUnmapLockedPages(BaseAddress %x, Mdl %x)\n", Mdl, BaseAddress);
|
||||
(void)MmFreeMemoryArea(MmGetKernelAddressSpace(),
|
||||
BaseAddress-Mdl->ByteOffset,
|
||||
BaseAddress - Mdl->ByteOffset,
|
||||
Mdl->ByteCount,
|
||||
FALSE);
|
||||
Mdl->MdlFlags = Mdl->MdlFlags & ~MDL_MAPPED_TO_SYSTEM_VA;
|
||||
|
@ -188,12 +188,8 @@ VOID STDCALL MmProbeAndLockPages (PMDL Mdl,
|
|||
}
|
||||
|
||||
|
||||
ULONG
|
||||
STDCALL
|
||||
MmSizeOfMdl (
|
||||
PVOID Base,
|
||||
ULONG Length
|
||||
)
|
||||
ULONG STDCALL MmSizeOfMdl (PVOID Base,
|
||||
ULONG Length)
|
||||
/*
|
||||
* FUNCTION: Returns the number of bytes to allocate for an MDL describing
|
||||
* the given address range
|
||||
|
@ -209,11 +205,7 @@ MmSizeOfMdl (
|
|||
}
|
||||
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
MmBuildMdlForNonPagedPool (
|
||||
PMDL Mdl
|
||||
)
|
||||
VOID STDCALL MmBuildMdlForNonPagedPool (PMDL Mdl)
|
||||
/*
|
||||
* FUNCTION: Fills in the corresponding physical page array of a given
|
||||
* MDL for a buffer in nonpaged system space
|
||||
|
@ -233,13 +225,9 @@ MmBuildMdlForNonPagedPool (
|
|||
}
|
||||
|
||||
|
||||
PMDL
|
||||
STDCALL
|
||||
MmCreateMdl (
|
||||
PMDL MemoryDescriptorList,
|
||||
PVOID Base,
|
||||
ULONG Length
|
||||
)
|
||||
PMDL STDCALL MmCreateMdl (PMDL MemoryDescriptorList,
|
||||
PVOID Base,
|
||||
ULONG Length)
|
||||
/*
|
||||
* FUNCTION: Allocates and initalizes an MDL
|
||||
* ARGUMENTS:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: mm.c,v 1.33 2000/07/04 08:52:42 dwelch Exp $
|
||||
/* $Id: mm.c,v 1.34 2000/07/07 10:30:56 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -30,8 +30,9 @@
|
|||
|
||||
/* GLOBALS *****************************************************************/
|
||||
|
||||
ULONG EXPORTED MmUserProbeAddress [PAGESIZE] = {0,}; /* FIXME */
|
||||
PVOID EXPORTED MmHighestUserAddress = NULL; /* FIXME */
|
||||
PVOID EXPORTED MmUserProbeAddress = NULL;
|
||||
PVOID EXPORTED MmHighestUserAddress = NULL;
|
||||
MM_STATS MmStats;
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: mminit.c,v 1.2 2000/07/04 11:11:04 dwelch Exp $
|
||||
/* $Id: mminit.c,v 1.3 2000/07/07 10:30:56 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -156,7 +156,13 @@ VOID MmInit1(PLOADER_PARAMETER_BLOCK bp, ULONG LastKernelAddress)
|
|||
|
||||
DPRINT("MmInit1(bp %x, LastKernelAddress %x)\n", bp,
|
||||
LastKernelAddress);
|
||||
|
||||
|
||||
/*
|
||||
* FIXME: Set this based on the system command line
|
||||
*/
|
||||
MmUserProbeAddress = (PVOID)0x7fff0000;
|
||||
MmHighestUserAddress = (PVOID)0x7ffeffff;
|
||||
|
||||
MmInitializeKernelAddressSpace();
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/* $Id: mpw.c,v 1.1 2000/07/04 08:52:42 dwelch Exp $
|
||||
/* $Id: mpw.c,v 1.2 2000/07/07 10:30:56 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/mm/pager.c
|
||||
* FILE: ntoskrnl/mm/mpw.c
|
||||
* PURPOSE: Writes data that has been modified in memory but not on
|
||||
* the disk
|
||||
* PROGRAMMER: David Welch (welch@cwcom.net)
|
||||
|
@ -29,75 +29,122 @@ static CLIENT_ID MpwThreadId;
|
|||
static KEVENT MpwThreadEvent;
|
||||
static PEPROCESS LastProcess;
|
||||
static volatile BOOLEAN MpwThreadShouldTerminate;
|
||||
static KEVENT MpwWroteOne;
|
||||
static ULONG MmDirtyPagesInMemory;
|
||||
static ULONG CountToWrite;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
BOOLEAN MmShouldIWrite(BOOLEAN Wait)
|
||||
VOID MmStartWritingPages(VOID)
|
||||
{
|
||||
if ((MmDirtyPagesInMemory*3) >
|
||||
CountToWrite = CountToWrite + MmStats.NrDirtyPages;
|
||||
}
|
||||
|
||||
VOID MmTryPageOutFromProcess(PEPROCESS Process)
|
||||
ULONG MmWritePage(PMADDRESS_SPACE AddressSpace,
|
||||
PVOID Address)
|
||||
{
|
||||
MmLockAddressSpace(&Process->Pcb.AddressSpace);
|
||||
PageCount = PageCout - MmTrimWorkingSet(Process);
|
||||
MmUnlockAddressSpace(&Process->Pcb.AddressSpace);
|
||||
PMEMORY_AREA MArea;
|
||||
NTSTATUS Status;
|
||||
|
||||
MArea = MmOpenMemoryAreaByAddress(AddressSpace, Address);
|
||||
|
||||
switch(MArea->Type)
|
||||
{
|
||||
case MEMORY_AREA_SYSTEM:
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
|
||||
case MEMORY_AREA_SECTION_VIEW_COMMIT:
|
||||
Status = MmWritePageSectionView(AddressSpace,
|
||||
MArea,
|
||||
Address);
|
||||
return(Status);
|
||||
|
||||
case MEMORY_AREA_COMMIT:
|
||||
Status = MmWritePageVirtualMemory(AddressSpace,
|
||||
MArea,
|
||||
Address);
|
||||
return(Status);
|
||||
|
||||
}
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
NTSTATUS MmPagerThreadMain(PVOID Ignored)
|
||||
VOID MmWritePagesInProcess(PEPROCESS Process)
|
||||
{
|
||||
PVOID Address;
|
||||
NTSTATUS Status;
|
||||
|
||||
MmLockAddressSpace(&Process->AddressSpace);
|
||||
|
||||
while ((Address = MmGetDirtyPagesFromWorkingSet(Process)) != NULL)
|
||||
{
|
||||
Status = MmWritePage(&Process->AddressSpace, Address);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
CountToWrite = CountToWrite - 1;
|
||||
if (CountToWrite == 0)
|
||||
{
|
||||
MmUnlockAddressSpace(&Process->AddressSpace);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MmUnlockAddressSpace(&Process->AddressSpace);
|
||||
}
|
||||
|
||||
NTSTATUS MmMpwThreadMain(PVOID Ignored)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
Status = KeWaitForSingleObject(&PagerThreadEvent,
|
||||
Status = KeWaitForSingleObject(&MpwThreadEvent,
|
||||
0,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DbgPrint("PagerThread: Wait failed\n");
|
||||
DbgPrint("MpwThread: Wait failed\n");
|
||||
KeBugCheck(0);
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
if (PagerThreadShouldTerminate)
|
||||
if (MpwThreadShouldTerminate)
|
||||
{
|
||||
DbgPrint("PagerThread: Terminating\n");
|
||||
DbgPrint("MpwThread: Terminating\n");
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
while (PageCount > 0)
|
||||
do
|
||||
{
|
||||
KeAttachProcess(LastProcess);
|
||||
MmTryPageOutFromProcess(LastProcess);
|
||||
MmWritePagesInProcess(LastProcess);
|
||||
KeDetachProcess();
|
||||
if (PageCount != 0)
|
||||
if (CountToWrite != 0)
|
||||
{
|
||||
LastProcess = PsGetNextProcess(LastProcess);
|
||||
}
|
||||
}
|
||||
} while (CountToWrite > 0 &&
|
||||
LastProcess != PsInitialSystemProcess);
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS MmInitPagerThread(VOID)
|
||||
NTSTATUS MmInitMpwThread(VOID)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
PageCount = 0;
|
||||
CountToWrite = 0;
|
||||
LastProcess = PsInitialSystemProcess;
|
||||
PagerThreadShouldTerminate = FALSE;
|
||||
KeInitializeEvent(&PagerThreadEvent,
|
||||
MpwThreadShouldTerminate = FALSE;
|
||||
KeInitializeEvent(&MpwThreadEvent,
|
||||
SynchronizationEvent,
|
||||
FALSE);
|
||||
|
||||
Status = PsCreateSystemThread(&PagerThreadHandle,
|
||||
Status = PsCreateSystemThread(&MpwThreadHandle,
|
||||
THREAD_ALL_ACCESS,
|
||||
NULL,
|
||||
NULL,
|
||||
&PagerThreadId,
|
||||
MmPagerThreadMain,
|
||||
&MpwThreadId,
|
||||
MmMpwThreadMain,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: pagefile.c,v 1.5 2000/07/04 08:52:45 dwelch Exp $
|
||||
/* $Id: pagefile.c,v 1.6 2000/07/07 10:30:56 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -53,8 +53,63 @@ static PVOID MmCoreDumpPageFrame;
|
|||
static BYTE MmCoreDumpHeader[PAGESIZE];
|
||||
#endif
|
||||
|
||||
#define FILE_FROM_ENTRY(i) ((i) >> 24)
|
||||
#define OFFSET_FROM_ENTRY(i) (((i) & 0xffffff) - 1)
|
||||
|
||||
#define ENTRY_FROM_FILE_OFFSET(i, j) (((i) << 24) || ((j) + 1))
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
NTSTATUS MmWriteToSwapPage(SWAPENTRY SwapEntry, PMDL Mdl)
|
||||
{
|
||||
ULONG i, offset;
|
||||
LARGE_INTEGER file_offset;
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
NTSTATUS Status;
|
||||
|
||||
if (SwapEntry == 0)
|
||||
{
|
||||
KeBugCheck(0);
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
i = FILE_FROM_ENTRY(SwapEntry);
|
||||
offset = OFFSET_FROM_ENTRY(SwapEntry);
|
||||
|
||||
file_offset.QuadPart = offset * 4096;
|
||||
|
||||
Status = IoPageWrite(PagingFileList[i]->FileObject,
|
||||
Mdl,
|
||||
&file_offset,
|
||||
&Iosb);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
NTSTATUS MmReadFromSwapPage(SWAPENTRY SwapEntry, PMDL Mdl)
|
||||
{
|
||||
ULONG i, offset;
|
||||
LARGE_INTEGER file_offset;
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
NTSTATUS Status;
|
||||
|
||||
if (SwapEntry == 0)
|
||||
{
|
||||
KeBugCheck(0);
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
i = FILE_FROM_ENTRY(SwapEntry);
|
||||
offset = OFFSET_FROM_ENTRY(SwapEntry);
|
||||
|
||||
file_offset.QuadPart = offset * 4096;
|
||||
|
||||
Status = IoPageRead(PagingFileList[i]->FileObject,
|
||||
Mdl,
|
||||
&file_offset,
|
||||
&Iosb);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
VOID MmInitPagingFile(VOID)
|
||||
{
|
||||
ULONG i;
|
||||
|
@ -107,7 +162,7 @@ ULONG MiAllocPageFromPagingFile(PPAGINGFILE PagingFile)
|
|||
PagingFile->UsedPages--;
|
||||
PagingFile->FreePages++;
|
||||
KeReleaseSpinLock(&PagingFile->AllocMapLock, oldIrql);
|
||||
return(off + 1);
|
||||
return(off);
|
||||
}
|
||||
|
||||
KeReleaseSpinLock(&PagingFile->AllocMapLock, oldIrql);
|
||||
|
@ -120,8 +175,8 @@ VOID MmFreeSwapPage(SWAPENTRY Entry)
|
|||
ULONG off;
|
||||
KIRQL oldIrql;
|
||||
|
||||
i = (Entry >> 24) - 1;
|
||||
off = Entry & 0xffffff;
|
||||
i = FILE_FROM_ENTRY(Entry);
|
||||
off = OFFSET_FROM_ENTRY(Entry);
|
||||
|
||||
KeAcquireSpinLock(&PagingFileListLock, &oldIrql);
|
||||
KeAcquireSpinLockAtDpcLevel(&PagingFileList[i]->AllocMapLock);
|
||||
|
@ -159,11 +214,17 @@ SWAPENTRY MmAllocSwapPage(VOID)
|
|||
PagingFileList[i]->FreePages >= 1)
|
||||
{
|
||||
off = MiAllocPageFromPagingFile(PagingFileList[i]);
|
||||
if (off != 0)
|
||||
{
|
||||
KeBugCheck(0);
|
||||
KeReleaseSpinLock(&PagingFileListLock, oldIrql);
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
MiUsedSwapPages++;
|
||||
MiFreeSwapPages--;
|
||||
KeReleaseSpinLock(&PagingFileListLock, oldIrql);
|
||||
|
||||
entry = ((i+1) << 24) || off;
|
||||
entry = ENTRY_FROM_FILE_OFFSET(i, off);
|
||||
return(entry);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: section.c,v 1.36 2000/07/06 14:34:51 dwelch Exp $
|
||||
/* $Id: section.c,v 1.37 2000/07/07 10:30:56 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -28,6 +28,13 @@ POBJECT_TYPE EXPORTED MmSectionObjectType = NULL;
|
|||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
NTSTATUS MmWritePageSectionView(PMADDRESS_SPACE AddressSpace,
|
||||
PMEMORY_AREA MArea,
|
||||
PVOID Address)
|
||||
{
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
VOID MmLockSection(PSECTION_OBJECT Section)
|
||||
{
|
||||
KeWaitForSingleObject(&Section->Lock,
|
||||
|
@ -132,8 +139,9 @@ NTSTATUS MmUnalignedLoadPageForSection(PMADDRESS_SPACE AddressSpace,
|
|||
Mdl,
|
||||
&Offset,
|
||||
&IoStatus);
|
||||
if (!NT_SUCCESS(Status))
|
||||
if (!NT_SUCCESS(Status) && Status != STATUS_END_OF_FILE)
|
||||
{
|
||||
MmLockAddressSpace(AddressSpace);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
|
@ -150,106 +158,6 @@ NTSTATUS MmUnalignedLoadPageForSection(PMADDRESS_SPACE AddressSpace,
|
|||
|
||||
}
|
||||
|
||||
NTSTATUS MmOldNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||
MEMORY_AREA* MemoryArea,
|
||||
PVOID Address)
|
||||
{
|
||||
LARGE_INTEGER Offset;
|
||||
IO_STATUS_BLOCK IoStatus;
|
||||
PMDL Mdl;
|
||||
PVOID Page;
|
||||
NTSTATUS Status;
|
||||
ULONG PAddress;
|
||||
PSECTION_OBJECT Section;
|
||||
ULONG Entry;
|
||||
|
||||
DPRINT("MmSectionHandleFault(MemoryArea %x, Address %x)\n",
|
||||
MemoryArea,Address);
|
||||
|
||||
if (MmIsPagePresent(NULL, Address))
|
||||
{
|
||||
DPRINT("Page is already present\n");
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
PAddress = (ULONG)PAGE_ROUND_DOWN(((ULONG)Address));
|
||||
Offset.QuadPart = (PAddress - (ULONG)MemoryArea->BaseAddress) +
|
||||
MemoryArea->Data.SectionData.ViewOffset;
|
||||
|
||||
if ((MemoryArea->Data.SectionData.ViewOffset % PAGESIZE) != 0)
|
||||
{
|
||||
return(MmUnalignedLoadPageForSection(AddressSpace,
|
||||
MemoryArea,
|
||||
Address));
|
||||
}
|
||||
|
||||
DPRINT("MemoryArea->BaseAddress %x\n", MemoryArea->BaseAddress);
|
||||
DPRINT("MemoryArea->Data.SectionData.ViewOffset %x\n",
|
||||
MemoryArea->Data.SectionData.ViewOffset);
|
||||
DPRINT("Got offset %x\n", Offset.QuadPart);
|
||||
|
||||
Section = MemoryArea->Data.SectionData.Section;
|
||||
|
||||
DPRINT("Section %x\n", Section);
|
||||
|
||||
MmLockSection(Section);
|
||||
|
||||
Entry = MmGetPageEntrySection(Section, Offset.u.LowPart);
|
||||
|
||||
DPRINT("Entry %x\n", Entry);
|
||||
|
||||
if (Entry == 0)
|
||||
{
|
||||
Page = MmAllocPageMaybeSwap(0);
|
||||
|
||||
|
||||
Mdl = MmCreateMdl(NULL, NULL, PAGESIZE);
|
||||
MmBuildMdlFromPages(Mdl, (PULONG)&Page);
|
||||
MmUnlockSection(Section);
|
||||
MmUnlockAddressSpace(AddressSpace);
|
||||
DPRINT("Reading file offset %x\n", Offset.QuadPart);
|
||||
Status = IoPageRead(MemoryArea->Data.SectionData.Section->FileObject,
|
||||
Mdl,
|
||||
&Offset,
|
||||
&IoStatus);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
|
||||
MmLockAddressSpace(AddressSpace);
|
||||
MmLockSection(Section);
|
||||
|
||||
Entry = MmGetPageEntrySection(Section, Offset.QuadPart);
|
||||
|
||||
if (Entry == 0)
|
||||
{
|
||||
MmSetPageEntrySection(Section,
|
||||
Offset.QuadPart,
|
||||
(ULONG)Page);
|
||||
}
|
||||
else
|
||||
{
|
||||
MmDereferencePage(Page);
|
||||
Page = (PVOID)Entry;
|
||||
MmReferencePage(Page);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Page = (PVOID)Entry;
|
||||
MmReferencePage(Page);
|
||||
}
|
||||
|
||||
MmSetPage(NULL,
|
||||
Address,
|
||||
MemoryArea->Attributes,
|
||||
(ULONG)Page);
|
||||
MmUnlockSection(Section);
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
NTSTATUS MmWaitForPendingOperationSection(PMADDRESS_SPACE AddressSpace,
|
||||
PMEMORY_AREA MemoryArea,
|
||||
PVOID Address,
|
||||
|
@ -484,7 +392,7 @@ NTSTATUS MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
|||
Mdl,
|
||||
&Offset,
|
||||
&IoStatus);
|
||||
if (!NT_SUCCESS(Status))
|
||||
if (!NT_SUCCESS(Status) && Status != STATUS_END_OF_FILE)
|
||||
{
|
||||
/*
|
||||
* FIXME: What do we know in this case?
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: virtual.c,v 1.31 2000/07/06 14:34:51 dwelch Exp $
|
||||
/* $Id: virtual.c,v 1.32 2000/07/07 10:30:56 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -27,6 +27,97 @@
|
|||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
NTSTATUS MmWritePageVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||
PMEMORY_AREA MArea,
|
||||
PVOID Address)
|
||||
{
|
||||
SWAPENTRY se;
|
||||
ULONG Flags;
|
||||
PHYSICAL_ADDRESS PhysicalAddress;
|
||||
PMDL Mdl;
|
||||
NTSTATUS Status;
|
||||
|
||||
/*
|
||||
* FIXME: What should we do if an i/o operation is pending on
|
||||
* this page
|
||||
*/
|
||||
|
||||
/*
|
||||
* If the memory area is readonly then there is nothing to do
|
||||
*/
|
||||
if (MArea->Attributes & PAGE_READONLY ||
|
||||
MArea->Attributes & PAGE_EXECUTE_READ)
|
||||
{
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
/*
|
||||
* Set the page to readonly. This ensures the current contents aren't
|
||||
* modified while we are writing it to swap.
|
||||
*/
|
||||
MmSetPageProtect(AddressSpace->Process,
|
||||
Address,
|
||||
PAGE_READONLY);
|
||||
/*
|
||||
* If the page isn't dirty then there is nothing to do.
|
||||
*/
|
||||
if (!MmIsPageDirty(AddressSpace->Process, Address))
|
||||
{
|
||||
MmSetPageProtect(AddressSpace->Process,
|
||||
Address,
|
||||
MArea->Attributes);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
PhysicalAddress = MmGetPhysicalAddress(Address);
|
||||
/*
|
||||
* If we haven't already allocated a swap entry for this page
|
||||
* then allocate one
|
||||
*/
|
||||
if ((se = MmGetSavedSwapEntryPage((PVOID)PhysicalAddress.u.LowPart)) != 0)
|
||||
{
|
||||
se = MmAllocSwapPage();
|
||||
if (se == 0)
|
||||
{
|
||||
MmSetPageProtect(AddressSpace->Process,
|
||||
Address,
|
||||
MArea->Attributes);
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
MmSetSavedSwapEntryPage((PVOID)PhysicalAddress.u.LowPart, se);
|
||||
}
|
||||
/*
|
||||
* Set the flags so other threads will know what we are doing
|
||||
*/
|
||||
Flags = MmGetFlagsPage((PVOID)PhysicalAddress.u.LowPart);
|
||||
Flags = Flags | MM_PHYSICAL_PAGE_MPW_PENDING;
|
||||
MmSetFlagsPage((PVOID)PhysicalAddress.u.LowPart, Flags);
|
||||
/*
|
||||
* Build an mdl to hold the page for writeout
|
||||
*/
|
||||
Mdl = MmCreateMdl(NULL, NULL, PAGESIZE);
|
||||
MmBuildMdlFromPages(Mdl, (PULONG)&PhysicalAddress.u.LowPart);
|
||||
/*
|
||||
* Unlock the address space and write out the page to swap.
|
||||
*/
|
||||
MmUnlockAddressSpace(AddressSpace);
|
||||
Status = MmWriteToSwapPage(se, Mdl);
|
||||
/*
|
||||
* Cleanup
|
||||
*/
|
||||
MmLockAddressSpace(AddressSpace);
|
||||
Flags = MmGetFlagsPage((PVOID)PhysicalAddress.u.LowPart);
|
||||
Flags = Flags & (~MM_PHYSICAL_PAGE_MPW_PENDING);
|
||||
MmSetFlagsPage((PVOID)PhysicalAddress.u.LowPart,Flags);
|
||||
/*
|
||||
* If we successfully wrote the page then reset the dirty bit
|
||||
*/
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
MmSetCleanPage(AddressSpace->Process, Address);
|
||||
}
|
||||
return(Status);
|
||||
}
|
||||
|
||||
|
||||
ULONG MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||
PMEMORY_AREA MemoryArea,
|
||||
PVOID Address,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: wset.c,v 1.2 2000/07/06 14:34:51 dwelch Exp $
|
||||
/* $Id: wset.c,v 1.3 2000/07/07 10:30:57 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -19,6 +19,11 @@
|
|||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
PVOID MmGetDirtyPagesFromWorkingSet(struct _EPROCESS* Process)
|
||||
{
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
VOID MmLockWorkingSet(PEPROCESS Process)
|
||||
{
|
||||
(VOID)KeWaitForMutexObject(&Process->WorkingSetLock,
|
||||
|
|
Loading…
Reference in a new issue