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:
David Welch 2000-07-07 10:30:57 +00:00
parent 0ea1d03808
commit 8689a5cfe9
18 changed files with 432 additions and 180 deletions

View file

@ -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,

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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,

View file

@ -114,6 +114,7 @@ VOID KiSideEffectsBeforeWake(DISPATCHER_HEADER* hdr,
KMUTEX,
Header);
hdr->SignalState--;
assert(hdr->SignalState <= 1);
Mutex->OwnerThread = Thread;
}
break;

View file

@ -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 \

View file

@ -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;

View file

@ -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);

View file

@ -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:

View file

@ -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 ****************************************************************/

View file

@ -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
@ -157,6 +157,12 @@ 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();
/*

View file

@ -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))
{

View file

@ -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);
}
}

View file

@ -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?

View file

@ -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,

View file

@ -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,