mirror of
https://github.com/reactos/reactos.git
synced 2025-04-26 16:40:27 +00:00
Swapping to disk
svn path=/trunk/; revision=2467
This commit is contained in:
parent
36214fbd89
commit
3ea11463b3
17 changed files with 1006 additions and 208 deletions
|
@ -1,4 +1,4 @@
|
||||||
# $Id: Makefile,v 1.60 2001/12/31 01:53:44 dwelch Exp $
|
# $Id: Makefile,v 1.61 2001/12/31 19:06:46 dwelch Exp $
|
||||||
#
|
#
|
||||||
# ReactOS Operating System
|
# ReactOS Operating System
|
||||||
#
|
#
|
||||||
|
@ -151,7 +151,8 @@ OBJECTS_MM = \
|
||||||
mm/mpw.o \
|
mm/mpw.o \
|
||||||
mm/pageop.o \
|
mm/pageop.o \
|
||||||
mm/balance.o \
|
mm/balance.o \
|
||||||
mm/rmap.o
|
mm/rmap.o \
|
||||||
|
mm/slab.o
|
||||||
|
|
||||||
# I/O Subsystem (Io)
|
# I/O Subsystem (Io)
|
||||||
OBJECTS_IO = \
|
OBJECTS_IO = \
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: view.c,v 1.32 2001/12/31 01:53:44 dwelch Exp $
|
/* $Id: view.c,v 1.33 2001/12/31 19:06:47 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -357,8 +357,9 @@ CcRosRequestCacheSegment(PBCB Bcb,
|
||||||
|
|
||||||
STATIC VOID
|
STATIC VOID
|
||||||
CcFreeCachePage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, ULONG PhysAddr,
|
CcFreeCachePage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, ULONG PhysAddr,
|
||||||
BOOLEAN Dirty)
|
SWAPENTRY SwapEntry, BOOLEAN Dirty)
|
||||||
{
|
{
|
||||||
|
assert(SwapEntry == 0);
|
||||||
if (PhysAddr != 0)
|
if (PhysAddr != 0)
|
||||||
{
|
{
|
||||||
MmReleasePageMemoryConsumer(MC_CACHE, (PVOID)PhysAddr);
|
MmReleasePageMemoryConsumer(MC_CACHE, (PVOID)PhysAddr);
|
||||||
|
|
|
@ -62,7 +62,7 @@ typedef ULONG SWAPENTRY;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
ULONG Pages[NR_SECTION_PAGE_ENTRIES];
|
ULONG Entry[NR_SECTION_PAGE_ENTRIES];
|
||||||
} SECTION_PAGE_TABLE, *PSECTION_PAGE_TABLE;
|
} SECTION_PAGE_TABLE, *PSECTION_PAGE_TABLE;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -141,23 +141,12 @@ typedef struct
|
||||||
} Data;
|
} Data;
|
||||||
} MEMORY_AREA, *PMEMORY_AREA;
|
} MEMORY_AREA, *PMEMORY_AREA;
|
||||||
|
|
||||||
typedef struct _KCIRCULAR_QUEUE
|
|
||||||
{
|
|
||||||
ULONG First;
|
|
||||||
ULONG Last;
|
|
||||||
ULONG CurrentSize;
|
|
||||||
ULONG MaximumSize;
|
|
||||||
PVOID* Mem;
|
|
||||||
} KCIRCULAR_QUEUE, *PKCIRCULAR_QUEUE;
|
|
||||||
|
|
||||||
typedef struct _MADDRESS_SPACE
|
typedef struct _MADDRESS_SPACE
|
||||||
{
|
{
|
||||||
LIST_ENTRY MAreaListHead;
|
LIST_ENTRY MAreaListHead;
|
||||||
KMUTEX Lock;
|
KMUTEX Lock;
|
||||||
ULONG LowestAddress;
|
ULONG LowestAddress;
|
||||||
struct _EPROCESS* Process;
|
struct _EPROCESS* Process;
|
||||||
PMEMORY_AREA WorkingSetArea;
|
|
||||||
KCIRCULAR_QUEUE WSQueue;
|
|
||||||
PUSHORT PageTableRefCountTable;
|
PUSHORT PageTableRefCountTable;
|
||||||
ULONG PageTableRefCountTableSize;
|
ULONG PageTableRefCountTableSize;
|
||||||
} MADDRESS_SPACE, *PMADDRESS_SPACE;
|
} MADDRESS_SPACE, *PMADDRESS_SPACE;
|
||||||
|
@ -189,7 +178,8 @@ NTSTATUS MmFreeMemoryArea(PMADDRESS_SPACE AddressSpace,
|
||||||
PVOID BaseAddress,
|
PVOID BaseAddress,
|
||||||
ULONG Length,
|
ULONG Length,
|
||||||
VOID (*FreePage)(PVOID Context, MEMORY_AREA* MemoryArea,
|
VOID (*FreePage)(PVOID Context, MEMORY_AREA* MemoryArea,
|
||||||
PVOID Address, ULONG PhysAddr, BOOLEAN Dirty),
|
PVOID Address, ULONG PhysAddr, SWAPENTRY SwapEntry,
|
||||||
|
BOOLEAN Dirty),
|
||||||
PVOID FreePageContext);
|
PVOID FreePageContext);
|
||||||
VOID MmDumpMemoryAreas(PLIST_ENTRY ListHead);
|
VOID MmDumpMemoryAreas(PLIST_ENTRY ListHead);
|
||||||
NTSTATUS MmLockMemoryArea(MEMORY_AREA* MemoryArea);
|
NTSTATUS MmLockMemoryArea(MEMORY_AREA* MemoryArea);
|
||||||
|
@ -507,5 +497,12 @@ MmTrimUserMemory(ULONG Target, ULONG Priority, PULONG NrFreedPages);
|
||||||
VOID
|
VOID
|
||||||
MmDisableVirtualMapping(PEPROCESS Process, PVOID Address, BOOL* WasDirty, ULONG* PhysicalAddr);
|
MmDisableVirtualMapping(PEPROCESS Process, PVOID Address, BOOL* WasDirty, ULONG* PhysicalAddr);
|
||||||
VOID MmEnableVirtualMapping(PEPROCESS Process, PVOID Address);
|
VOID MmEnableVirtualMapping(PEPROCESS Process, PVOID Address);
|
||||||
|
VOID
|
||||||
|
MmDeletePageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY* SwapEntry);
|
||||||
|
NTSTATUS
|
||||||
|
MmCreatePageFileMapping(PEPROCESS Process,
|
||||||
|
PVOID Address,
|
||||||
|
SWAPENTRY SwapEntry);
|
||||||
|
BOOLEAN MmIsPageSwapEntry(PEPROCESS Process, PVOID Address);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: kdebug.c,v 1.29 2001/09/09 09:47:18 hbirr Exp $
|
/* $Id: kdebug.c,v 1.30 2001/12/31 19:06:47 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -302,6 +302,8 @@ KeEnterKernelDebugger (VOID)
|
||||||
VOID STDCALL
|
VOID STDCALL
|
||||||
KdSystemDebugControl(ULONG Code)
|
KdSystemDebugControl(ULONG Code)
|
||||||
{
|
{
|
||||||
|
extern VOID PsDumpThreads(BOOLEAN IncludeSystem);
|
||||||
|
|
||||||
/* A - Dump the entire contents of the non-paged pool. */
|
/* A - Dump the entire contents of the non-paged pool. */
|
||||||
if (Code == 0)
|
if (Code == 0)
|
||||||
{
|
{
|
||||||
|
@ -336,10 +338,12 @@ KdSystemDebugControl(ULONG Code)
|
||||||
/* F */
|
/* F */
|
||||||
else if (Code == 5)
|
else if (Code == 5)
|
||||||
{
|
{
|
||||||
|
PsDumpThreads(TRUE);
|
||||||
}
|
}
|
||||||
/* G */
|
/* G */
|
||||||
else if (Code == 6)
|
else if (Code == 6)
|
||||||
{
|
{
|
||||||
|
PsDumpThreads(FALSE);
|
||||||
}
|
}
|
||||||
/* H */
|
/* H */
|
||||||
else if (Code == 7)
|
else if (Code == 7)
|
||||||
|
|
|
@ -44,8 +44,9 @@
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
KeFreeStackPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, ULONG PhysAddr,
|
KeFreeStackPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, ULONG PhysAddr,
|
||||||
BOOLEAN Dirty)
|
SWAPENTRY SwapEntry, BOOLEAN Dirty)
|
||||||
{
|
{
|
||||||
|
assert(SwapEntry == 0);
|
||||||
if (PhysAddr != 0)
|
if (PhysAddr != 0)
|
||||||
{
|
{
|
||||||
MmDereferencePage((PVOID)PhysAddr);
|
MmDereferencePage((PVOID)PhysAddr);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: cont.c,v 1.15 2001/12/31 01:53:45 dwelch Exp $
|
/* $Id: cont.c,v 1.16 2001/12/31 19:06:47 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -21,8 +21,9 @@
|
||||||
|
|
||||||
VOID STATIC
|
VOID STATIC
|
||||||
MmFreeContinuousPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, ULONG PhysAddr,
|
MmFreeContinuousPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, ULONG PhysAddr,
|
||||||
BOOLEAN Dirty)
|
SWAPENTRY SwapEntry, BOOLEAN Dirty)
|
||||||
{
|
{
|
||||||
|
assert(SwapEntry == 0);
|
||||||
if (PhysAddr != 0)
|
if (PhysAddr != 0)
|
||||||
{
|
{
|
||||||
MmDereferencePage((PVOID)PhysAddr);
|
MmDereferencePage((PVOID)PhysAddr);
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: page.c,v 1.30 2001/12/31 01:53:46 dwelch Exp $
|
/* $Id: page.c,v 1.31 2001/12/31 19:06:48 dwelch Exp $
|
||||||
*
|
*
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/mm/i386/page.c
|
* FILE: ntoskrnl/mm/i386/page.c
|
||||||
|
@ -508,6 +508,85 @@ MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOL FreePage,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MmDeletePageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY* SwapEntry)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Delete a virtual mapping
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
ULONG Pte;
|
||||||
|
PULONG Pde;
|
||||||
|
PEPROCESS CurrentProcess = PsGetCurrentProcess();
|
||||||
|
BOOLEAN WasValid;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we are setting a page in another process we need to be in its
|
||||||
|
* context.
|
||||||
|
*/
|
||||||
|
if (Process != NULL && Process != CurrentProcess)
|
||||||
|
{
|
||||||
|
KeAttachProcess(Process);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the page directory entry, we may have to copy the entry from
|
||||||
|
* the global page directory.
|
||||||
|
*/
|
||||||
|
Pde = ADDR_TO_PDE(Address);
|
||||||
|
if ((*Pde) == 0 &&
|
||||||
|
MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] != 0)
|
||||||
|
{
|
||||||
|
(*Pde) = MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)];
|
||||||
|
FLUSH_TLB;
|
||||||
|
}
|
||||||
|
if ((*Pde) == 0)
|
||||||
|
{
|
||||||
|
if (Process != NULL && Process != CurrentProcess)
|
||||||
|
{
|
||||||
|
KeDetachProcess();
|
||||||
|
}
|
||||||
|
*SwapEntry = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Atomically set the entry to zero and get the old value.
|
||||||
|
*/
|
||||||
|
Pte = (ULONG)InterlockedExchange((PLONG)ADDR_TO_PTE(Address), 0);
|
||||||
|
FLUSH_TLB;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decrement the reference count for this page table.
|
||||||
|
*/
|
||||||
|
if (Process != NULL && WasValid &&
|
||||||
|
Process->AddressSpace.PageTableRefCountTable != NULL &&
|
||||||
|
ADDR_TO_PAGE_TABLE(Address) < 768)
|
||||||
|
{
|
||||||
|
PUSHORT Ptrc;
|
||||||
|
|
||||||
|
Ptrc = Process->AddressSpace.PageTableRefCountTable;
|
||||||
|
|
||||||
|
Ptrc[ADDR_TO_PAGE_TABLE(Address)]--;
|
||||||
|
if (Ptrc[ADDR_TO_PAGE_TABLE(Address)] == 0)
|
||||||
|
{
|
||||||
|
MmFreePageTable(Process, Address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If necessary go back to the original context
|
||||||
|
*/
|
||||||
|
if (Process != NULL && Process != CurrentProcess)
|
||||||
|
{
|
||||||
|
KeDetachProcess();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return some information to the caller
|
||||||
|
*/
|
||||||
|
*SwapEntry = Pte >> 1;
|
||||||
|
}
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
Mmi386MakeKernelPageTableGlobal(PVOID PAddress)
|
Mmi386MakeKernelPageTableGlobal(PVOID PAddress)
|
||||||
{
|
{
|
||||||
|
@ -680,6 +759,13 @@ BOOLEAN MmIsPagePresent(PEPROCESS Process, PVOID Address)
|
||||||
return((MmGetPageEntryForProcess1(Process, Address)) & PA_PRESENT);
|
return((MmGetPageEntryForProcess1(Process, Address)) & PA_PRESENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOLEAN MmIsPageSwapEntry(PEPROCESS Process, PVOID Address)
|
||||||
|
{
|
||||||
|
ULONG Pte;
|
||||||
|
Pte = MmGetPageEntryForProcess1(Process, Address);
|
||||||
|
return((!(Pte & PA_PRESENT)) && Pte != 0);
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MmCreateVirtualMappingForKernel(PVOID Address,
|
MmCreateVirtualMappingForKernel(PVOID Address,
|
||||||
ULONG flProtect,
|
ULONG flProtect,
|
||||||
|
@ -726,8 +812,13 @@ MmCreateVirtualMappingForKernel(PVOID Address,
|
||||||
}
|
}
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
if (PAGE_MASK((*Pte)) != 0 && !((*Pte) & PA_PRESENT))
|
||||||
|
{
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
if (PAGE_MASK((*Pte)) != 0)
|
if (PAGE_MASK((*Pte)) != 0)
|
||||||
{
|
{
|
||||||
|
MmMarkPageUnmapped((PVOID)PAGE_MASK((*Pte)));
|
||||||
}
|
}
|
||||||
*Pte = PhysicalAddress | Attributes;
|
*Pte = PhysicalAddress | Attributes;
|
||||||
if (Process != NULL &&
|
if (Process != NULL &&
|
||||||
|
@ -749,6 +840,76 @@ MmCreateVirtualMappingForKernel(PVOID Address,
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
MmCreatePageFileMapping(PEPROCESS Process,
|
||||||
|
PVOID Address,
|
||||||
|
SWAPENTRY SwapEntry)
|
||||||
|
{
|
||||||
|
PEPROCESS CurrentProcess;
|
||||||
|
PULONG Pte;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
if (Process != NULL)
|
||||||
|
{
|
||||||
|
CurrentProcess = PsGetCurrentProcess();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CurrentProcess = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Process == NULL && Address < (PVOID)KERNEL_BASE)
|
||||||
|
{
|
||||||
|
DPRINT1("No process\n");
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
|
if (Process != NULL && Address >= (PVOID)KERNEL_BASE)
|
||||||
|
{
|
||||||
|
DPRINT1("Setting kernel address with process context\n");
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
|
if (SwapEntry & (1 << 31))
|
||||||
|
{
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Process != NULL && Process != CurrentProcess)
|
||||||
|
{
|
||||||
|
KeAttachProcess(Process);
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = MmGetPageEntry2(Address, &Pte);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
if (Process != NULL && Process != CurrentProcess)
|
||||||
|
{
|
||||||
|
KeDetachProcess();
|
||||||
|
}
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
if (PAGE_MASK((*Pte)) != 0)
|
||||||
|
{
|
||||||
|
MmMarkPageUnmapped((PVOID)PAGE_MASK((*Pte)));
|
||||||
|
}
|
||||||
|
*Pte = SwapEntry << 1;
|
||||||
|
if (Process != NULL &&
|
||||||
|
Process->AddressSpace.PageTableRefCountTable != NULL &&
|
||||||
|
ADDR_TO_PAGE_TABLE(Address) < 768)
|
||||||
|
{
|
||||||
|
PUSHORT Ptrc;
|
||||||
|
|
||||||
|
Ptrc = Process->AddressSpace.PageTableRefCountTable;
|
||||||
|
|
||||||
|
Ptrc[ADDR_TO_PAGE_TABLE(Address)]++;
|
||||||
|
}
|
||||||
|
FLUSH_TLB;
|
||||||
|
if (Process != NULL && Process != CurrentProcess)
|
||||||
|
{
|
||||||
|
KeDetachProcess();
|
||||||
|
}
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MmCreateVirtualMappingUnsafe(PEPROCESS Process,
|
MmCreateVirtualMappingUnsafe(PEPROCESS Process,
|
||||||
PVOID Address,
|
PVOID Address,
|
||||||
|
@ -797,6 +958,10 @@ MmCreateVirtualMappingUnsafe(PEPROCESS Process,
|
||||||
}
|
}
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
if (PAGE_MASK((*Pte)) != 0 && !((*Pte) & PA_PRESENT))
|
||||||
|
{
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
if (PAGE_MASK((*Pte)) != 0)
|
if (PAGE_MASK((*Pte)) != 0)
|
||||||
{
|
{
|
||||||
MmMarkPageUnmapped((PVOID)PAGE_MASK((*Pte)));
|
MmMarkPageUnmapped((PVOID)PAGE_MASK((*Pte)));
|
||||||
|
@ -893,10 +1058,19 @@ MmGetPhysicalAddress(PVOID vaddr)
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
PHYSICAL_ADDRESS p;
|
PHYSICAL_ADDRESS p;
|
||||||
|
ULONG Pte;
|
||||||
|
|
||||||
DPRINT("MmGetPhysicalAddress(vaddr %x)\n", vaddr);
|
DPRINT("MmGetPhysicalAddress(vaddr %x)\n", vaddr);
|
||||||
|
|
||||||
p.QuadPart = PAGE_MASK(*MmGetPageEntry(vaddr));
|
Pte = *MmGetPageEntry(vaddr);
|
||||||
|
if (Pte & PA_PRESENT)
|
||||||
|
{
|
||||||
|
p.QuadPart = PAGE_MASK(Pte);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p.QuadPart = 0;
|
||||||
|
}
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
|
@ -295,7 +295,7 @@ MmFreeMemoryArea(PMADDRESS_SPACE AddressSpace,
|
||||||
PVOID BaseAddress,
|
PVOID BaseAddress,
|
||||||
ULONG Length,
|
ULONG Length,
|
||||||
VOID (*FreePage)(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
|
VOID (*FreePage)(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
|
||||||
ULONG PhysAddr, BOOLEAN Dirty),
|
ULONG PhysAddr, SWAPENTRY SwapEntry, BOOLEAN Dirty),
|
||||||
PVOID FreePageContext)
|
PVOID FreePageContext)
|
||||||
{
|
{
|
||||||
MEMORY_AREA* MemoryArea;
|
MEMORY_AREA* MemoryArea;
|
||||||
|
@ -315,14 +315,25 @@ MmFreeMemoryArea(PMADDRESS_SPACE AddressSpace,
|
||||||
{
|
{
|
||||||
ULONG PhysAddr;
|
ULONG PhysAddr;
|
||||||
BOOL Dirty;
|
BOOL Dirty;
|
||||||
|
SWAPENTRY SwapEntry = 0;
|
||||||
|
|
||||||
MmDeleteVirtualMapping(AddressSpace->Process,
|
if (MmIsPageSwapEntry(AddressSpace->Process,
|
||||||
MemoryArea->BaseAddress + (i*PAGESIZE),
|
MemoryArea->BaseAddress + (i * PAGESIZE)))
|
||||||
FALSE, &Dirty, &PhysAddr);
|
{
|
||||||
|
MmDeletePageFileMapping(AddressSpace->Process,
|
||||||
|
MemoryArea->BaseAddress + (i * PAGESIZE),
|
||||||
|
&SwapEntry);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MmDeleteVirtualMapping(AddressSpace->Process,
|
||||||
|
MemoryArea->BaseAddress + (i*PAGESIZE),
|
||||||
|
FALSE, &Dirty, &PhysAddr);
|
||||||
|
}
|
||||||
if (FreePage != NULL)
|
if (FreePage != NULL)
|
||||||
{
|
{
|
||||||
FreePage(FreePageContext, MemoryArea,
|
FreePage(FreePageContext, MemoryArea,
|
||||||
MemoryArea->BaseAddress + (i * PAGESIZE), PhysAddr, Dirty);
|
MemoryArea->BaseAddress + (i * PAGESIZE), PhysAddr, SwapEntry, Dirty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: ncache.c,v 1.13 2001/12/31 01:53:45 dwelch Exp $
|
/* $Id: ncache.c,v 1.14 2001/12/31 19:06:47 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -86,8 +86,9 @@ MmAllocateNonCachedMemory(IN ULONG NumberOfBytes)
|
||||||
|
|
||||||
VOID STATIC
|
VOID STATIC
|
||||||
MmFreeNonCachedPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, ULONG PhysAddr,
|
MmFreeNonCachedPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, ULONG PhysAddr,
|
||||||
BOOLEAN Dirty)
|
SWAPENTRY SwapEntry, BOOLEAN Dirty)
|
||||||
{
|
{
|
||||||
|
assert(SwapEntry == 0);
|
||||||
if (PhysAddr != 0)
|
if (PhysAddr != 0)
|
||||||
{
|
{
|
||||||
MmDereferencePage((PVOID)PhysAddr);
|
MmDereferencePage((PVOID)PhysAddr);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: npool.c,v 1.52 2001/12/31 01:53:45 dwelch Exp $
|
/* $Id: npool.c,v 1.53 2001/12/31 19:06:47 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -1013,7 +1013,7 @@ ExAllocateWholePageBlock(ULONG UserSize)
|
||||||
|
|
||||||
for (i = 0; i < NrPages; i++)
|
for (i = 0; i < NrPages; i++)
|
||||||
{
|
{
|
||||||
Page = MmAllocPage(0);
|
Page = MmAllocPage(MC_NPPOOL, 0);
|
||||||
if (Page == NULL)
|
if (Page == NULL)
|
||||||
{
|
{
|
||||||
KeBugCheck(0);
|
KeBugCheck(0);
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: pagefile.c,v 1.13 2001/12/06 00:54:54 dwelch Exp $
|
/* $Id: pagefile.c,v 1.14 2001/12/31 19:06:47 dwelch Exp $
|
||||||
*
|
*
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/mm/pagefile.c
|
* FILE: ntoskrnl/mm/pagefile.c
|
||||||
|
@ -96,7 +96,7 @@ static BYTE MmCoreDumpHeader[PAGESIZE];
|
||||||
*/
|
*/
|
||||||
#define FILE_FROM_ENTRY(i) ((i) >> 24)
|
#define FILE_FROM_ENTRY(i) ((i) >> 24)
|
||||||
#define OFFSET_FROM_ENTRY(i) (((i) & 0xffffff) - 1)
|
#define OFFSET_FROM_ENTRY(i) (((i) & 0xffffff) - 1)
|
||||||
#define ENTRY_FROM_FILE_OFFSET(i, j) (((i) << 24) || ((j) + 1))
|
#define ENTRY_FROM_FILE_OFFSET(i, j) (((i) << 24) | ((j) + 1))
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ NTSTATUS MmWriteToSwapPage(SWAPENTRY SwapEntry, PMDL Mdl)
|
||||||
Mdl,
|
Mdl,
|
||||||
&file_offset,
|
&file_offset,
|
||||||
&Iosb,
|
&Iosb,
|
||||||
FALSE);
|
TRUE);
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,6 +204,7 @@ MiAllocPageFromPagingFile(PPAGINGFILE PagingFile)
|
||||||
{
|
{
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
ULONG i, j;
|
ULONG i, j;
|
||||||
|
static BOOLEAN SwapSpaceMessage = FALSE;
|
||||||
|
|
||||||
KeAcquireSpinLock(&PagingFile->AllocMapLock, &oldIrql);
|
KeAcquireSpinLock(&PagingFile->AllocMapLock, &oldIrql);
|
||||||
|
|
||||||
|
@ -221,14 +222,19 @@ MiAllocPageFromPagingFile(PPAGINGFILE PagingFile)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
PagingFile->AllocMap[i] |= (1 << j);
|
PagingFile->AllocMap[i] |= (1 << j);
|
||||||
PagingFile->UsedPages--;
|
PagingFile->UsedPages++;
|
||||||
PagingFile->FreePages++;
|
PagingFile->FreePages--;
|
||||||
KeReleaseSpinLock(&PagingFile->AllocMapLock, oldIrql);
|
KeReleaseSpinLock(&PagingFile->AllocMapLock, oldIrql);
|
||||||
return((i * 32) + j);
|
return((i * 32) + j);
|
||||||
}
|
}
|
||||||
|
|
||||||
KeReleaseSpinLock(&PagingFile->AllocMapLock, oldIrql);
|
KeReleaseSpinLock(&PagingFile->AllocMapLock, oldIrql);
|
||||||
return(0);
|
if (!SwapSpaceMessage)
|
||||||
|
{
|
||||||
|
DPRINT1("MM: Out of swap space.\n");
|
||||||
|
SwapSpaceMessage = TRUE;
|
||||||
|
}
|
||||||
|
return(0xFFFFFFFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -242,9 +248,13 @@ MmFreeSwapPage(SWAPENTRY Entry)
|
||||||
off = OFFSET_FROM_ENTRY(Entry);
|
off = OFFSET_FROM_ENTRY(Entry);
|
||||||
|
|
||||||
KeAcquireSpinLock(&PagingFileListLock, &oldIrql);
|
KeAcquireSpinLock(&PagingFileListLock, &oldIrql);
|
||||||
|
if (PagingFileList[i] == NULL)
|
||||||
|
{
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
KeAcquireSpinLockAtDpcLevel(&PagingFileList[i]->AllocMapLock);
|
KeAcquireSpinLockAtDpcLevel(&PagingFileList[i]->AllocMapLock);
|
||||||
|
|
||||||
PagingFileList[i]->AllocMap[off / 32] |= (1 << (off % 32));
|
PagingFileList[i]->AllocMap[off / 32] &= (~(1 << (off % 32)));
|
||||||
|
|
||||||
PagingFileList[i]->FreePages++;
|
PagingFileList[i]->FreePages++;
|
||||||
PagingFileList[i]->UsedPages--;
|
PagingFileList[i]->UsedPages--;
|
||||||
|
@ -278,7 +288,7 @@ MmAllocSwapPage(VOID)
|
||||||
PagingFileList[i]->FreePages >= 1)
|
PagingFileList[i]->FreePages >= 1)
|
||||||
{
|
{
|
||||||
off = MiAllocPageFromPagingFile(PagingFileList[i]);
|
off = MiAllocPageFromPagingFile(PagingFileList[i]);
|
||||||
if (off != 0)
|
if (off == 0xFFFFFFFF)
|
||||||
{
|
{
|
||||||
KeBugCheck(0);
|
KeBugCheck(0);
|
||||||
KeReleaseSpinLock(&PagingFileListLock, oldIrql);
|
KeReleaseSpinLock(&PagingFileListLock, oldIrql);
|
||||||
|
@ -334,6 +344,11 @@ NtCreatePagingFile(IN PUNICODE_STRING PageFileName,
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
ULONG AllocMapSize;
|
ULONG AllocMapSize;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
PVOID Buffer;
|
||||||
|
LARGE_INTEGER ByteOffset;
|
||||||
|
|
||||||
|
DPRINT1("NtCreatePagingFile(PageFileName %wZ, MinimumSize %d)\n",
|
||||||
|
PageFileName, MinimumSize);
|
||||||
|
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
PageFileName,
|
PageFileName,
|
||||||
|
@ -347,7 +362,7 @@ NtCreatePagingFile(IN PUNICODE_STRING PageFileName,
|
||||||
NULL,
|
NULL,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
FILE_OPEN,
|
FILE_OPEN_IF,
|
||||||
FILE_SYNCHRONOUS_IO_NONALERT,
|
FILE_SYNCHRONOUS_IO_NONALERT,
|
||||||
NULL,
|
NULL,
|
||||||
0);
|
0);
|
||||||
|
@ -356,6 +371,24 @@ NtCreatePagingFile(IN PUNICODE_STRING PageFileName,
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Buffer = ExAllocatePool(NonPagedPool, 4096);
|
||||||
|
memset(Buffer, 0, 4096);
|
||||||
|
ByteOffset.QuadPart = MinimumSize * 4096;
|
||||||
|
Status = NtWriteFile(FileHandle,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&IoStatus,
|
||||||
|
Buffer,
|
||||||
|
4096,
|
||||||
|
&ByteOffset,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
NtClose(FileHandle);
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle(FileHandle,
|
Status = ObReferenceObjectByHandle(FileHandle,
|
||||||
FILE_ALL_ACCESS,
|
FILE_ALL_ACCESS,
|
||||||
IoFileObjectType,
|
IoFileObjectType,
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: section.c,v 1.70 2001/12/31 01:53:45 dwelch Exp $
|
/* $Id: section.c,v 1.71 2001/12/31 19:06:48 dwelch Exp $
|
||||||
*
|
*
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/mm/section.c
|
* FILE: ntoskrnl/mm/section.c
|
||||||
|
@ -65,8 +65,13 @@ static GENERIC_MAPPING MmpSectionMapping = {
|
||||||
#define TAG_MM_SECTION_SEGMENT TAG('M', 'M', 'S', 'S')
|
#define TAG_MM_SECTION_SEGMENT TAG('M', 'M', 'S', 'S')
|
||||||
#define TAG_SECTION_PAGE_TABLE TAG('M', 'S', 'P', 'T')
|
#define TAG_SECTION_PAGE_TABLE TAG('M', 'S', 'P', 'T')
|
||||||
|
|
||||||
#define SHARE_COUNT(E) ((E) & 0xFFF)
|
#define PAGE_FROM_SSE(E) ((E) & 0xFFFFF000)
|
||||||
#define MAX_SHARE_COUNT 0xFFF
|
#define SHARE_COUNT_FROM_SSE(E) (((E) & 0x00000FFE) >> 1)
|
||||||
|
#define IS_SWAP_FROM_SSE(E) ((E) & 0x00000001)
|
||||||
|
#define MAX_SHARE_COUNT 0x7FF
|
||||||
|
#define MAKE_SSE(P, C) ((P) | ((C) << 1))
|
||||||
|
#define SWAPENTRY_FROM_SSE(E) ((E) >> 1)
|
||||||
|
#define MAKE_SWAP_SSE(S) (((S) << 1) | 0x1)
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
@ -189,7 +194,7 @@ MmSetPageEntrySectionSegment(PMM_SECTION_SEGMENT Segment,
|
||||||
DPRINT("Table %x\n", Table);
|
DPRINT("Table %x\n", Table);
|
||||||
}
|
}
|
||||||
TableOffset = PAGE_TO_SECTION_PAGE_TABLE_OFFSET(Offset);
|
TableOffset = PAGE_TO_SECTION_PAGE_TABLE_OFFSET(Offset);
|
||||||
Table->Pages[TableOffset] = Entry;
|
Table->Entry[TableOffset] = Entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -212,7 +217,7 @@ MmGetPageEntrySectionSegment(PMM_SECTION_SEGMENT Segment,
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
TableOffset = PAGE_TO_SECTION_PAGE_TABLE_OFFSET(Offset);
|
TableOffset = PAGE_TO_SECTION_PAGE_TABLE_OFFSET(Offset);
|
||||||
Entry = Table->Pages[TableOffset];
|
Entry = Table->Entry[TableOffset];
|
||||||
return(Entry);
|
return(Entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,12 +233,16 @@ MmSharePageEntrySectionSegment(PMM_SECTION_SEGMENT Segment,
|
||||||
DPRINT1("Entry == 0 for MmSharePageEntrySectionSegment\n");
|
DPRINT1("Entry == 0 for MmSharePageEntrySectionSegment\n");
|
||||||
KeBugCheck(0);
|
KeBugCheck(0);
|
||||||
}
|
}
|
||||||
if (SHARE_COUNT(Entry) == MAX_SHARE_COUNT)
|
if (SHARE_COUNT_FROM_SSE(Entry) == MAX_SHARE_COUNT)
|
||||||
{
|
{
|
||||||
DPRINT1("Maximum share count reached\n");
|
DPRINT1("Maximum share count reached\n");
|
||||||
KeBugCheck(0);
|
KeBugCheck(0);
|
||||||
}
|
}
|
||||||
Entry = (Entry & 0xFFFFF000) | (SHARE_COUNT(Entry) + 1);
|
if (IS_SWAP_FROM_SSE(Entry))
|
||||||
|
{
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
|
Entry = MAKE_SSE(PAGE_FROM_SSE(Entry), SHARE_COUNT_FROM_SSE(Entry) + 1);
|
||||||
MmSetPageEntrySectionSegment(Segment, Offset, Entry);
|
MmSetPageEntrySectionSegment(Segment, Offset, Entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,17 +260,21 @@ MmUnsharePageEntrySectionSegment(PSECTION_OBJECT Section,
|
||||||
DPRINT1("Entry == 0 for MmSharePageEntrySectionSegment\n");
|
DPRINT1("Entry == 0 for MmSharePageEntrySectionSegment\n");
|
||||||
KeBugCheck(0);
|
KeBugCheck(0);
|
||||||
}
|
}
|
||||||
if (SHARE_COUNT(Entry) == 0)
|
if (SHARE_COUNT_FROM_SSE(Entry) == 0)
|
||||||
{
|
{
|
||||||
DPRINT1("Zero share count for unshare\n");
|
DPRINT1("Zero share count for unshare\n");
|
||||||
KeBugCheck(0);
|
KeBugCheck(0);
|
||||||
}
|
}
|
||||||
Entry = (Entry & 0xFFFFF000) | (SHARE_COUNT(Entry) - 1);
|
if (IS_SWAP_FROM_SSE(Entry))
|
||||||
|
{
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
|
Entry = MAKE_SSE(PAGE_FROM_SSE(Entry), SHARE_COUNT_FROM_SSE(Entry) - 1);
|
||||||
/*
|
/*
|
||||||
* If we reducing the share count of this entry to zero then set the entry to zero and
|
* If we reducing the share count of this entry to zero then set the entry to zero and
|
||||||
* tell the cache the page is no longer mapped.
|
* tell the cache the page is no longer mapped.
|
||||||
*/
|
*/
|
||||||
if (SHARE_COUNT(Entry) == 0)
|
if (SHARE_COUNT_FROM_SSE(Entry) == 0)
|
||||||
{
|
{
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
PREACTOS_COMMON_FCB_HEADER Fcb;
|
PREACTOS_COMMON_FCB_HEADER Fcb;
|
||||||
|
@ -288,7 +301,7 @@ MmUnsharePageEntrySectionSegment(PSECTION_OBJECT Section,
|
||||||
{
|
{
|
||||||
MmSetPageEntrySectionSegment(Segment, Offset, Entry);
|
MmSetPageEntrySectionSegment(Segment, Offset, Entry);
|
||||||
}
|
}
|
||||||
return(SHARE_COUNT(Entry) > 1);
|
return(SHARE_COUNT_FROM_SSE(Entry) > 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -508,7 +521,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
{
|
{
|
||||||
Entry = MmGetPageEntrySectionSegment(Segment, Offset.u.LowPart);
|
Entry = MmGetPageEntrySectionSegment(Segment, Offset.u.LowPart);
|
||||||
|
|
||||||
Page = (PVOID)(Entry & 0xFFFFF000);
|
Page = (PVOID)(PAGE_FROM_SSE(Entry));
|
||||||
MmReferencePage(Page);
|
MmReferencePage(Page);
|
||||||
MmSharePageEntrySectionSegment(Segment, Offset.u.LowPart);
|
MmSharePageEntrySectionSegment(Segment, Offset.u.LowPart);
|
||||||
|
|
||||||
|
@ -533,6 +546,70 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Must be private page we have swapped out.
|
||||||
|
*/
|
||||||
|
if (MmIsPageSwapEntry(NULL, (PVOID)PAddress))
|
||||||
|
{
|
||||||
|
SWAPENTRY SwapEntry;
|
||||||
|
PMDL Mdl;
|
||||||
|
|
||||||
|
MmUnlockSectionSegment(Segment);
|
||||||
|
MmUnlockSection(Section);
|
||||||
|
|
||||||
|
Status = MmRequestPageMemoryConsumer(MC_USER, FALSE, &Page);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Mdl = MmCreateMdl(NULL, NULL, PAGESIZE);
|
||||||
|
MmBuildMdlFromPages(Mdl, (PULONG)&Page);
|
||||||
|
Status = MmReadFromSwapPage(SwapEntry, Mdl);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
|
||||||
|
Address,
|
||||||
|
MemoryArea->Attributes,
|
||||||
|
(ULONG)Page);
|
||||||
|
while (Status == STATUS_NO_MEMORY)
|
||||||
|
{
|
||||||
|
MmUnlockAddressSpace(AddressSpace);
|
||||||
|
KeBugCheck(0);
|
||||||
|
MmLockAddressSpace(AddressSpace);
|
||||||
|
Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
|
||||||
|
Address,
|
||||||
|
MemoryArea->Attributes,
|
||||||
|
(ULONG)Page);
|
||||||
|
}
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("MmCreateVirtualMapping failed, not out of memory\n");
|
||||||
|
KeBugCheck(0);
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add the page to the process's working set
|
||||||
|
*/
|
||||||
|
MmInsertRmap(Page, PsGetCurrentProcess(), (PVOID)PAGE_ROUND_DOWN(Address));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Finish the operation
|
||||||
|
*/
|
||||||
|
if (Locked)
|
||||||
|
{
|
||||||
|
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address));
|
||||||
|
}
|
||||||
|
PageOp->Status = STATUS_SUCCESS;
|
||||||
|
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||||
|
MmReleasePageOp(PageOp);
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Satisfying a page fault on a map of /Device/PhysicalMemory is easy
|
* Satisfying a page fault on a map of /Device/PhysicalMemory is easy
|
||||||
*/
|
*/
|
||||||
|
@ -615,83 +692,159 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
/*
|
/*
|
||||||
* Get the entry corresponding to the offset within the section
|
* Get the entry corresponding to the offset within the section
|
||||||
*/
|
*/
|
||||||
Entry = MmGetPageEntrySectionSegment(Segment, Offset.u.LowPart) & 0xFFFFF000;
|
Entry = MmGetPageEntrySectionSegment(Segment, Offset.u.LowPart);
|
||||||
|
|
||||||
if (Entry == 0)
|
if (Entry == 0)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* If the entry is zero (and it can't change because we have
|
* If the entry is zero (and it can't change because we have
|
||||||
* locked the segment) then we need to load the page.
|
* locked the segment) then we need to load the page.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Release all our locks and read in the page from disk
|
* Release all our locks and read in the page from disk
|
||||||
*/
|
*/
|
||||||
MmUnlockSectionSegment(Segment);
|
MmUnlockSectionSegment(Segment);
|
||||||
MmUnlockSection(Section);
|
MmUnlockSection(Section);
|
||||||
MmUnlockAddressSpace(AddressSpace);
|
MmUnlockAddressSpace(AddressSpace);
|
||||||
|
|
||||||
if (Segment->Flags & MM_PAGEFILE_SECTION)
|
if (Segment->Flags & MM_PAGEFILE_SECTION)
|
||||||
{
|
{
|
||||||
Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page);
|
Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Status = MiReadPage(MemoryArea, &Offset, &Page);
|
Status = MiReadPage(MemoryArea, &Offset, &Page);
|
||||||
}
|
}
|
||||||
if (!NT_SUCCESS(Status) && Status != STATUS_END_OF_FILE)
|
if (!NT_SUCCESS(Status) && Status != STATUS_END_OF_FILE)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* FIXME: What do we know in this case?
|
* FIXME: What do we know in this case?
|
||||||
*/
|
*/
|
||||||
DPRINT1("IoPageRead failed (Status %x)\n", Status);
|
DPRINT1("IoPageRead failed (Status %x)\n", Status);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Cleanup and release locks
|
* Cleanup and release locks
|
||||||
*/
|
*/
|
||||||
PageOp->Status = Status;
|
PageOp->Status = Status;
|
||||||
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||||
MmReleasePageOp(PageOp);
|
MmReleasePageOp(PageOp);
|
||||||
MmLockAddressSpace(AddressSpace);
|
MmLockAddressSpace(AddressSpace);
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Relock the address space, section and segment
|
* Relock the address space, section and segment
|
||||||
*/
|
*/
|
||||||
MmLockAddressSpace(AddressSpace);
|
MmLockAddressSpace(AddressSpace);
|
||||||
MmLockSection(Section);
|
MmLockSection(Section);
|
||||||
MmLockSectionSegment(Segment);
|
MmLockSectionSegment(Segment);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check the entry. No one should change the status of a page
|
* Check the entry. No one should change the status of a page
|
||||||
* that has a pending page-in.
|
* that has a pending page-in.
|
||||||
*/
|
*/
|
||||||
Entry1 = MmGetPageEntrySectionSegment(Segment, Offset.QuadPart) & 0xFFFFF000;
|
Entry1 = MmGetPageEntrySectionSegment(Segment, Offset.QuadPart);
|
||||||
if (Entry != Entry1)
|
if (Entry != Entry1)
|
||||||
{
|
{
|
||||||
DbgPrint("Someone changed ppte entry while we slept\n");
|
DbgPrint("Someone changed ppte entry while we slept\n");
|
||||||
KeBugCheck(0);
|
KeBugCheck(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mark the offset within the section as having valid, in-memory
|
* Mark the offset within the section as having valid, in-memory
|
||||||
* data
|
* data
|
||||||
*/
|
*/
|
||||||
Entry = (ULONG)Page;
|
Entry = (ULONG)Page;
|
||||||
MmSetPageEntrySectionSegment(Segment, Offset.QuadPart, Entry);
|
MmSetPageEntrySectionSegment(Segment, Offset.QuadPart, Entry);
|
||||||
MmSharePageEntrySectionSegment(Segment, Offset.QuadPart);
|
MmSharePageEntrySectionSegment(Segment, Offset.QuadPart);
|
||||||
|
|
||||||
Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
|
Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
|
||||||
Address,
|
Address,
|
||||||
Attributes,
|
Attributes,
|
||||||
(ULONG)Page);
|
(ULONG)Page);
|
||||||
MmInsertRmap(Page, PsGetCurrentProcess(), (PVOID)PAGE_ROUND_DOWN(Address));
|
MmInsertRmap(Page, PsGetCurrentProcess(), (PVOID)PAGE_ROUND_DOWN(Address));
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DbgPrint("Unable to create virtual mapping\n");
|
DbgPrint("Unable to create virtual mapping\n");
|
||||||
KeBugCheck(0);
|
KeBugCheck(0);
|
||||||
}
|
}
|
||||||
|
if (Locked)
|
||||||
|
{
|
||||||
|
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address));
|
||||||
|
}
|
||||||
|
PageOp->Status = STATUS_SUCCESS;
|
||||||
|
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||||
|
MmReleasePageOp(PageOp);
|
||||||
|
MmUnlockSectionSegment(Segment);
|
||||||
|
MmUnlockSection(Section);
|
||||||
|
DPRINT("MmNotPresentFaultSectionView succeeded\n");
|
||||||
|
return(STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
else if (IS_SWAP_FROM_SSE(Entry))
|
||||||
|
{
|
||||||
|
SWAPENTRY SwapEntry;
|
||||||
|
PMDL Mdl;
|
||||||
|
|
||||||
|
SwapEntry = SWAPENTRY_FROM_SSE(Entry);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Release all our locks and read in the page from disk
|
||||||
|
*/
|
||||||
|
MmUnlockSectionSegment(Segment);
|
||||||
|
MmUnlockSection(Section);
|
||||||
|
MmUnlockAddressSpace(AddressSpace);
|
||||||
|
|
||||||
|
Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Mdl = MmCreateMdl(NULL, NULL, PAGESIZE);
|
||||||
|
MmBuildMdlFromPages(Mdl, (PULONG)&Page);
|
||||||
|
Status = MmReadFromSwapPage(SwapEntry, Mdl);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Relock the address space, section and segment
|
||||||
|
*/
|
||||||
|
MmLockAddressSpace(AddressSpace);
|
||||||
|
MmLockSection(Section);
|
||||||
|
MmLockSectionSegment(Segment);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check the entry. No one should change the status of a page
|
||||||
|
* that has a pending page-in.
|
||||||
|
*/
|
||||||
|
Entry1 = MmGetPageEntrySectionSegment(Segment, Offset.QuadPart);
|
||||||
|
if (Entry != Entry1)
|
||||||
|
{
|
||||||
|
DbgPrint("Someone changed ppte entry while we slept\n");
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Mark the offset within the section as having valid, in-memory
|
||||||
|
* data
|
||||||
|
*/
|
||||||
|
Entry = (ULONG)Page;
|
||||||
|
MmSetPageEntrySectionSegment(Segment, Offset.QuadPart, Entry);
|
||||||
|
MmSharePageEntrySectionSegment(Segment, Offset.QuadPart);
|
||||||
|
|
||||||
|
Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
|
||||||
|
Address,
|
||||||
|
Attributes,
|
||||||
|
(ULONG)Page);
|
||||||
|
MmInsertRmap(Page, PsGetCurrentProcess(), (PVOID)PAGE_ROUND_DOWN(Address));
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DbgPrint("Unable to create virtual mapping\n");
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
if (Locked)
|
if (Locked)
|
||||||
{
|
{
|
||||||
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address));
|
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address));
|
||||||
|
@ -711,7 +864,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
* take another reference to the page
|
* take another reference to the page
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Page = (PVOID)Entry;
|
Page = (PVOID)PAGE_FROM_SSE(Entry);
|
||||||
MmReferencePage(Page);
|
MmReferencePage(Page);
|
||||||
MmSharePageEntrySectionSegment(Segment, Offset.QuadPart);
|
MmSharePageEntrySectionSegment(Segment, Offset.QuadPart);
|
||||||
|
|
||||||
|
@ -854,6 +1007,11 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
memcpy(NewAddress, (PVOID)PAGE_ROUND_DOWN(Address), PAGESIZE);
|
memcpy(NewAddress, (PVOID)PAGE_ROUND_DOWN(Address), PAGESIZE);
|
||||||
ExUnmapPage(NewAddress);
|
ExUnmapPage(NewAddress);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Delete the old entry.
|
||||||
|
*/
|
||||||
|
MmDeleteVirtualMapping(PsGetCurrentProcess(), Address, FALSE, NULL, NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the PTE to point to the new page
|
* Set the PTE to point to the new page
|
||||||
*/
|
*/
|
||||||
|
@ -891,13 +1049,14 @@ MmPageOutDeleteMapping(PVOID Context, PEPROCESS Process, PVOID Address)
|
||||||
{
|
{
|
||||||
MM_SECTION_PAGEOUT_CONTEXT* PageOutContext;
|
MM_SECTION_PAGEOUT_CONTEXT* PageOutContext;
|
||||||
BOOL WasDirty;
|
BOOL WasDirty;
|
||||||
|
PVOID PhysicalAddress;
|
||||||
|
|
||||||
PageOutContext = (MM_SECTION_PAGEOUT_CONTEXT*)Context;
|
PageOutContext = (MM_SECTION_PAGEOUT_CONTEXT*)Context;
|
||||||
MmDeleteVirtualMapping(Process,
|
MmDeleteVirtualMapping(Process,
|
||||||
Address,
|
Address,
|
||||||
FALSE,
|
FALSE,
|
||||||
&WasDirty,
|
&WasDirty,
|
||||||
NULL);
|
(PULONG)&PhysicalAddress);
|
||||||
PageOutContext->WasDirty = PageOutContext->WasDirty || WasDirty;
|
PageOutContext->WasDirty = PageOutContext->WasDirty || WasDirty;
|
||||||
if (!PageOutContext->Private)
|
if (!PageOutContext->Private)
|
||||||
{
|
{
|
||||||
|
@ -906,6 +1065,7 @@ MmPageOutDeleteMapping(PVOID Context, PEPROCESS Process, PVOID Address)
|
||||||
PageOutContext->Offset.u.LowPart,
|
PageOutContext->Offset.u.LowPart,
|
||||||
PageOutContext->WasDirty);
|
PageOutContext->WasDirty);
|
||||||
}
|
}
|
||||||
|
MmDereferencePage(PhysicalAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -986,6 +1146,10 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
Context.WasDirty = FALSE;
|
Context.WasDirty = FALSE;
|
||||||
Context.Private = Private = ((PVOID)(Entry & 0xFFFFF000) != PhysicalAddress);
|
Context.Private = Private = ((PVOID)(Entry & 0xFFFFF000) != PhysicalAddress);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Take an additional reference to the page.
|
||||||
|
*/
|
||||||
|
MmReferencePage(PhysicalAddress);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Paging only data mapped read-only is easy.
|
* Paging only data mapped read-only is easy.
|
||||||
|
@ -1055,6 +1219,7 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
*/
|
*/
|
||||||
if (DirectMapped)
|
if (DirectMapped)
|
||||||
{
|
{
|
||||||
|
MmDereferencePage((PVOID)PhysicalAddress);
|
||||||
PageOp->Status = STATUS_SUCCESS;
|
PageOp->Status = STATUS_SUCCESS;
|
||||||
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||||
MmReleasePageOp(PageOp);
|
MmReleasePageOp(PageOp);
|
||||||
|
@ -1090,13 +1255,13 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
* set it back into section segment entry so we don't loose our
|
* set it back into section segment entry so we don't loose our
|
||||||
* copy. Otherwise it will be handled by the cache manager.
|
* copy. Otherwise it will be handled by the cache manager.
|
||||||
*/
|
*/
|
||||||
if (!DirectMapped)
|
Status = MmCreateVirtualMapping(MemoryArea->Process,
|
||||||
{
|
Address,
|
||||||
MmSetPageEntrySectionSegment(Segment, Offset.QuadPart, (ULONG)PhysicalAddress);
|
MemoryArea->Attributes,
|
||||||
MmSharePageEntrySectionSegment(Segment, Offset.QuadPart);
|
(ULONG)PhysicalAddress);
|
||||||
}
|
MmSetPageEntrySectionSegment(Segment, Offset.QuadPart, (ULONG)PhysicalAddress);
|
||||||
|
MmSharePageEntrySectionSegment(Segment, Offset.QuadPart);
|
||||||
}
|
}
|
||||||
|
|
||||||
PageOp->Status = STATUS_UNSUCCESSFUL;
|
PageOp->Status = STATUS_UNSUCCESSFUL;
|
||||||
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||||
MmReleasePageOp(PageOp);
|
MmReleasePageOp(PageOp);
|
||||||
|
@ -1112,7 +1277,7 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
Status = MmWriteToSwapPage(SwapEntry, Mdl);
|
Status = MmWriteToSwapPage(SwapEntry, Mdl);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("MM: Failed to write to swap page\n");
|
DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n", Status);
|
||||||
/*
|
/*
|
||||||
* As above: undo our actions.
|
* As above: undo our actions.
|
||||||
* FIXME: Also free the swap page.
|
* FIXME: Also free the swap page.
|
||||||
|
@ -1129,13 +1294,13 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!DirectMapped)
|
Status = MmCreateVirtualMapping(MemoryArea->Process,
|
||||||
{
|
Address,
|
||||||
MmSetPageEntrySectionSegment(Segment, Offset.QuadPart, (ULONG)PhysicalAddress);
|
MemoryArea->Attributes,
|
||||||
MmSharePageEntrySectionSegment(Segment, Offset.QuadPart);
|
(ULONG)PhysicalAddress);
|
||||||
}
|
MmSetPageEntrySectionSegment(Segment, Offset.QuadPart, (ULONG)PhysicalAddress);
|
||||||
|
MmSharePageEntrySectionSegment(Segment, Offset.QuadPart);
|
||||||
}
|
}
|
||||||
|
|
||||||
PageOp->Status = STATUS_UNSUCCESSFUL;
|
PageOp->Status = STATUS_UNSUCCESSFUL;
|
||||||
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||||
MmReleasePageOp(PageOp);
|
MmReleasePageOp(PageOp);
|
||||||
|
@ -1145,9 +1310,23 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
/*
|
/*
|
||||||
* Otherwise we have succeeded.
|
* Otherwise we have succeeded.
|
||||||
*/
|
*/
|
||||||
if (!DirectMapped)
|
DPRINT1("MM: Wrote section page to swap!\n");
|
||||||
|
MmReleasePageMemoryConsumer(MC_USER, PhysicalAddress);
|
||||||
|
|
||||||
|
if (Private)
|
||||||
{
|
{
|
||||||
MmReleasePageMemoryConsumer(MC_USER, PhysicalAddress);
|
Status = MmCreatePageFileMapping(MemoryArea->Process,
|
||||||
|
Address,
|
||||||
|
SwapEntry);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Entry = MAKE_SWAP_SSE(SwapEntry);
|
||||||
|
MmSetPageEntrySectionSegment(Segment, Offset.QuadPart, Entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
PageOp->Status = STATUS_SUCCESS;
|
PageOp->Status = STATUS_SUCCESS;
|
||||||
|
@ -2166,14 +2345,18 @@ NtMapViewOfSection(HANDLE SectionHandle,
|
||||||
|
|
||||||
VOID STATIC
|
VOID STATIC
|
||||||
MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, ULONG PhysAddr,
|
MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, ULONG PhysAddr,
|
||||||
BOOLEAN Dirty)
|
SWAPENTRY SwapEntry, BOOLEAN Dirty)
|
||||||
{
|
{
|
||||||
PMEMORY_AREA MArea;
|
PMEMORY_AREA MArea;
|
||||||
ULONG Entry;
|
ULONG Entry;
|
||||||
|
|
||||||
MArea = (PMEMORY_AREA)Context;
|
MArea = (PMEMORY_AREA)Context;
|
||||||
|
|
||||||
if (PhysAddr != 0)
|
if (SwapEntry != 0)
|
||||||
|
{
|
||||||
|
MmFreeSwapPage(SwapEntry);
|
||||||
|
}
|
||||||
|
else if (PhysAddr != 0)
|
||||||
{
|
{
|
||||||
ULONG Offset;
|
ULONG Offset;
|
||||||
|
|
||||||
|
|
315
reactos/ntoskrnl/mm/slab.c
Normal file
315
reactos/ntoskrnl/mm/slab.c
Normal file
|
@ -0,0 +1,315 @@
|
||||||
|
/*
|
||||||
|
* ReactOS kernel
|
||||||
|
* Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
/* $Id: slab.c,v 1.1 2001/12/31 19:06:48 dwelch Exp $
|
||||||
|
*
|
||||||
|
* COPYRIGHT: See COPYING in the top directory
|
||||||
|
* PROJECT: ReactOS kernel
|
||||||
|
* FILE: ntoskrnl/mm/slab.c
|
||||||
|
* PURPOSE: kernel memory managment functions
|
||||||
|
* PROGRAMMER: David Welch (welch@cwcom.net)
|
||||||
|
* UPDATE HISTORY:
|
||||||
|
* Created 27/12/01
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES *****************************************************************/
|
||||||
|
|
||||||
|
#include <ddk/ntddk.h>
|
||||||
|
#include <internal/mm.h>
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
|
#include <internal/debug.h>
|
||||||
|
|
||||||
|
/* TYPES ********************************************************************/
|
||||||
|
|
||||||
|
typedef VOID (*SLAB_CACHE_CONSTRUCTOR)(VOID*, ULONG);
|
||||||
|
typedef VOID (*SLAB_CACHE_DESTRUCTOR)(VOID*, ULONG);
|
||||||
|
|
||||||
|
struct _SLAB_CACHE_PAGE;
|
||||||
|
|
||||||
|
typedef struct _SLAB_CACHE
|
||||||
|
{
|
||||||
|
SLAB_CACHE_CONSTRUCTOR Constructor;
|
||||||
|
SLAB_CACHE_DESTRUCTOR Destructor;
|
||||||
|
ULONG BaseSize;
|
||||||
|
ULONG ObjectSize;
|
||||||
|
ULONG ObjectsPerPage;
|
||||||
|
LIST_ENTRY PageListHead;
|
||||||
|
struct _SLAB_CACHE_PAGE* FirstFreePage;
|
||||||
|
KSPIN_LOCK SlabLock;
|
||||||
|
} SLAB_CACHE, *PSLAB_CACHE;
|
||||||
|
|
||||||
|
typedef struct _SLAB_CACHE_BUFCTL
|
||||||
|
{
|
||||||
|
struct _SLAB_CACHE_BUFCTL* NextFree;
|
||||||
|
} SLAB_CACHE_BUFCTL, *PSLAB_CACHE_BUFCTL;
|
||||||
|
|
||||||
|
typedef struct _SLAB_CACHE_PAGE
|
||||||
|
{
|
||||||
|
LIST_ENTRY PageListEntry;
|
||||||
|
PSLAB_CACHE_BUFCTL FirstFreeBuffer;
|
||||||
|
ULONG ReferenceCount;
|
||||||
|
} SLAB_CACHE_PAGE, *PSLAB_CACHE_PAGE;
|
||||||
|
|
||||||
|
/* GLOBALS ******************************************************************/
|
||||||
|
|
||||||
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
|
PSLAB_CACHE
|
||||||
|
ExCreateSlabCache(PUNICODE_STRING Name, ULONG Size, ULONG Align,
|
||||||
|
SLAB_CACHE_CONSTRUCTOR Constructor,
|
||||||
|
SLAB_CACHE_DESTRUCTOR Destructor)
|
||||||
|
{
|
||||||
|
PSLAB_CACHE Slab;
|
||||||
|
ULONG ObjectSize;
|
||||||
|
ULONG AlignSize;
|
||||||
|
|
||||||
|
Slab = ExAllocatePool(NonPagedPool, sizeof(SLAB_CACHE));
|
||||||
|
if (Slab == NULL)
|
||||||
|
{
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
Slab->Constructor = Constructor;
|
||||||
|
Slab->Destructor = Destructor;
|
||||||
|
Slab->BaseSize = Size;
|
||||||
|
ObjectSize = Size + sizeof(SLAB_CACHE_BUFCTL);
|
||||||
|
AlignSize = Align - (ObjectSize % Align);
|
||||||
|
Slab->ObjectSize = ObjectSize + AlignSize;
|
||||||
|
Slab->ObjectsPerPage = (PAGESIZE - sizeof(SLAB_CACHE_PAGE)) / Slab->ObjectSize;
|
||||||
|
InitializeListHead(&Slab->PageListHead);
|
||||||
|
KeInitializeSpinLock(&Slab->SlabLock);
|
||||||
|
|
||||||
|
return(Slab);
|
||||||
|
}
|
||||||
|
|
||||||
|
PSLAB_CACHE_PAGE
|
||||||
|
ExGrowSlabCache(PSLAB_CACHE Slab)
|
||||||
|
{
|
||||||
|
PSLAB_CACHE_PAGE SlabPage;
|
||||||
|
PVOID PhysicalPage;
|
||||||
|
PVOID Page;
|
||||||
|
NTSTATUS Status;
|
||||||
|
ULONG i;
|
||||||
|
PSLAB_CACHE_BUFCTL BufCtl;
|
||||||
|
PVOID Object;
|
||||||
|
|
||||||
|
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &PhysicalPage);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
Page = ExAllocatePageWithPhysPage((ULONG)PhysicalPage);
|
||||||
|
if (Page == NULL)
|
||||||
|
{
|
||||||
|
MmReleasePageMemoryConsumer(MC_NPPOOL, PhysicalPage);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
SlabPage = (PSLAB_CACHE_PAGE)(Page + PAGESIZE - sizeof(SLAB_CACHE_PAGE));
|
||||||
|
SlabPage->ReferenceCount = 0;
|
||||||
|
SlabPage->FirstFreeBuffer = (PSLAB_CACHE_BUFCTL)Page;
|
||||||
|
for (i = 0; i < Slab->ObjectsPerPage; i++)
|
||||||
|
{
|
||||||
|
BufCtl = (PSLAB_CACHE_BUFCTL)(Page + (i * Slab->ObjectSize));
|
||||||
|
Object = (PVOID)(BufCtl + 1);
|
||||||
|
if (Slab->Constructor != NULL)
|
||||||
|
{
|
||||||
|
Slab->Constructor(Object, Slab->BaseSize);
|
||||||
|
}
|
||||||
|
if (i == (Slab->ObjectsPerPage - 1))
|
||||||
|
{
|
||||||
|
BufCtl->NextFree = (PSLAB_CACHE_BUFCTL)(Page + ((i + 1) * Slab->ObjectSize));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BufCtl->NextFree = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return(SlabPage);
|
||||||
|
}
|
||||||
|
|
||||||
|
PVOID
|
||||||
|
ExAllocateSlabCache(PSLAB_CACHE Slab, BOOLEAN MayWait)
|
||||||
|
{
|
||||||
|
KIRQL oldIrql;
|
||||||
|
PSLAB_CACHE_PAGE Page;
|
||||||
|
PVOID Object;
|
||||||
|
BOOLEAN NewPage;
|
||||||
|
|
||||||
|
KeAcquireSpinLock(&Slab->SlabLock, &oldIrql);
|
||||||
|
/*
|
||||||
|
* Check if there is a slab with free objects
|
||||||
|
* present, if so allocation from it, if
|
||||||
|
* not grow the slab.
|
||||||
|
*/
|
||||||
|
if (Slab->FirstFreePage == NULL)
|
||||||
|
{
|
||||||
|
KeReleaseSpinLock(&Slab->SlabLock, oldIrql);
|
||||||
|
Page = ExGrowSlabCache(Slab);
|
||||||
|
NewPage = TRUE;
|
||||||
|
KeAcquireSpinLock(&Slab->SlabLock, &oldIrql);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Page = Slab->FirstFreePage;
|
||||||
|
NewPage = FALSE;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* We shouldn't have got a page without free buffer.
|
||||||
|
*/
|
||||||
|
if (Page->FirstFreeBuffer == NULL)
|
||||||
|
{
|
||||||
|
DPRINT1("First free page had no free buffers.\n");
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Allocate the first free object from the page.
|
||||||
|
*/
|
||||||
|
Object = (PVOID)Page->FirstFreeBuffer + sizeof(SLAB_CACHE_BUFCTL);
|
||||||
|
Page->FirstFreeBuffer = Page->FirstFreeBuffer->NextFree;
|
||||||
|
Page->ReferenceCount++;
|
||||||
|
/*
|
||||||
|
* If we just allocate all the objects from this page
|
||||||
|
* and it was the first free page then adjust the
|
||||||
|
* first free page pointer and move the page to the head
|
||||||
|
* of the list.
|
||||||
|
*/
|
||||||
|
if (Page->ReferenceCount == Slab->ObjectsPerPage && !NewPage)
|
||||||
|
{
|
||||||
|
if (Page->PageListEntry.Flink == &Slab->PageListHead)
|
||||||
|
{
|
||||||
|
Slab->FirstFreePage = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PSLAB_CACHE_PAGE NextPage;
|
||||||
|
|
||||||
|
NextPage = CONTAINING_RECORD(Page->PageListEntry.Flink,
|
||||||
|
SLAB_CACHE_PAGE,
|
||||||
|
PageListEntry);
|
||||||
|
Slab->FirstFreePage = NextPage;
|
||||||
|
}
|
||||||
|
RemoveEntryList(&Page->PageListEntry);
|
||||||
|
InsertHeadList(&Slab->PageListHead, &Page->PageListEntry);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Otherwise if we created a new page then add it to the end of
|
||||||
|
* the page list.
|
||||||
|
*/
|
||||||
|
else if (NewPage)
|
||||||
|
{
|
||||||
|
InsertTailList(&Slab->PageListHead, &Page->PageListEntry);
|
||||||
|
if (Slab->FirstFreePage == NULL)
|
||||||
|
{
|
||||||
|
Slab->FirstFreePage = Page;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
KeReleaseSpinLock(&Slab->SlabLock, oldIrql);
|
||||||
|
return(Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
ExFreeFromPageSlabCache(PSLAB_CACHE Slab,
|
||||||
|
PSLAB_CACHE_PAGE Page,
|
||||||
|
PVOID Object)
|
||||||
|
{
|
||||||
|
PSLAB_CACHE_BUFCTL BufCtl;
|
||||||
|
|
||||||
|
BufCtl = (PSLAB_CACHE_BUFCTL)(Object - sizeof(SLAB_CACHE_BUFCTL));
|
||||||
|
BufCtl->NextFree = Page->FirstFreeBuffer;
|
||||||
|
Page->FirstFreeBuffer = BufCtl;
|
||||||
|
Page->ReferenceCount--;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
ExFreeSlabCache(PSLAB_CACHE Slab, PVOID Object)
|
||||||
|
{
|
||||||
|
KIRQL oldIrql;
|
||||||
|
PLIST_ENTRY current_entry;
|
||||||
|
PSLAB_CACHE_PAGE current;
|
||||||
|
|
||||||
|
KeAcquireSpinLock(&Slab->SlabLock, &oldIrql);
|
||||||
|
current_entry = Slab->PageListHead.Flink;
|
||||||
|
while (current_entry != &Slab->PageListHead)
|
||||||
|
{
|
||||||
|
PVOID Base;
|
||||||
|
|
||||||
|
current = CONTAINING_RECORD(current_entry,
|
||||||
|
SLAB_CACHE_PAGE,
|
||||||
|
PageListEntry);
|
||||||
|
Base = (PVOID)current + sizeof(SLAB_CACHE_PAGE) - PAGESIZE;
|
||||||
|
if (Base >= Object &&
|
||||||
|
(Base + PAGESIZE - sizeof(SLAB_CACHE_PAGE)) >=
|
||||||
|
(Object + Slab->ObjectSize))
|
||||||
|
{
|
||||||
|
ExFreeFromPageSlabCache(Slab, current, Object);
|
||||||
|
/*
|
||||||
|
* If the page just become free then rearrange things.
|
||||||
|
*/
|
||||||
|
if (current->ReferenceCount == (Slab->ObjectsPerPage - 1))
|
||||||
|
{
|
||||||
|
RemoveEntryList(¤t->PageListEntry);
|
||||||
|
InsertTailList(&Slab->PageListHead, ¤t->PageListEntry);
|
||||||
|
if (Slab->FirstFreePage == NULL)
|
||||||
|
{
|
||||||
|
Slab->FirstFreePage = current;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
KeReleaseSpinLock(&Slab->SlabLock, oldIrql);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DPRINT1("Tried to free object not in cache.\n");
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
ExDestroySlabCache(PSLAB_CACHE Slab)
|
||||||
|
{
|
||||||
|
PLIST_ENTRY current_entry;
|
||||||
|
PSLAB_CACHE_PAGE current;
|
||||||
|
ULONG i;
|
||||||
|
PVOID Object;
|
||||||
|
|
||||||
|
current_entry = Slab->PageListHead.Flink;
|
||||||
|
while (current_entry != &Slab->PageListHead)
|
||||||
|
{
|
||||||
|
PVOID Base;
|
||||||
|
PVOID PhysicalPage;
|
||||||
|
|
||||||
|
current = CONTAINING_RECORD(current_entry,
|
||||||
|
SLAB_CACHE_PAGE,
|
||||||
|
PageListEntry);
|
||||||
|
Base = (PVOID)current + sizeof(SLAB_CACHE_PAGE) - PAGESIZE;
|
||||||
|
if (Slab->Destructor != NULL)
|
||||||
|
{
|
||||||
|
for (i = 0; i < Slab->ObjectsPerPage; i++)
|
||||||
|
{
|
||||||
|
Object = Base + (i * Slab->ObjectSize) + sizeof(SLAB_CACHE_BUFCTL);
|
||||||
|
Slab->Destructor(Object, Slab->BaseSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PhysicalPage = (PVOID)MmGetPhysicalAddressForProcess(NULL, Base);
|
||||||
|
ExUnmapPage(Base);
|
||||||
|
MmReleasePageMemoryConsumer(MC_NPPOOL, PhysicalPage);
|
||||||
|
}
|
||||||
|
ExFreePool(Slab);
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: virtual.c,v 1.51 2001/12/31 01:53:45 dwelch Exp $
|
/* $Id: virtual.c,v 1.52 2001/12/31 19:06:48 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top directory
|
* COPYRIGHT: See COPYING in the top directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -156,7 +156,6 @@ MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
SwapEntry = MmAllocSwapPage();
|
SwapEntry = MmAllocSwapPage();
|
||||||
if (SwapEntry == 0)
|
if (SwapEntry == 0)
|
||||||
{
|
{
|
||||||
DPRINT("MM: Out of swap space.\n");
|
|
||||||
MmEnableVirtualMapping(MemoryArea->Process, Address);
|
MmEnableVirtualMapping(MemoryArea->Process, Address);
|
||||||
PageOp->Status = STATUS_UNSUCCESSFUL;
|
PageOp->Status = STATUS_UNSUCCESSFUL;
|
||||||
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||||
|
@ -173,7 +172,7 @@ MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
Status = MmWriteToSwapPage(SwapEntry, Mdl);
|
Status = MmWriteToSwapPage(SwapEntry, Mdl);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("MM: Failed to write to swap page\n");
|
DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n", Status);
|
||||||
MmEnableVirtualMapping(MemoryArea->Process, Address);
|
MmEnableVirtualMapping(MemoryArea->Process, Address);
|
||||||
PageOp->Status = STATUS_UNSUCCESSFUL;
|
PageOp->Status = STATUS_UNSUCCESSFUL;
|
||||||
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||||
|
@ -184,7 +183,9 @@ MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
/*
|
/*
|
||||||
* Otherwise we have succeeded, free the page
|
* Otherwise we have succeeded, free the page
|
||||||
*/
|
*/
|
||||||
|
DPRINT1("MM: Swapped out virtual memory swap!\n");
|
||||||
MmDeleteVirtualMapping(MemoryArea->Process, Address, FALSE, NULL, NULL);
|
MmDeleteVirtualMapping(MemoryArea->Process, Address, FALSE, NULL, NULL);
|
||||||
|
MmCreatePageFileMapping(MemoryArea->Process, Address, SwapEntry);
|
||||||
MmDeleteAllRmaps(PhysicalAddress, NULL, NULL);
|
MmDeleteAllRmaps(PhysicalAddress, NULL, NULL);
|
||||||
MmReleasePageMemoryConsumer(MC_USER, PhysicalAddress);
|
MmReleasePageMemoryConsumer(MC_USER, PhysicalAddress);
|
||||||
PageOp->Status = STATUS_SUCCESS;
|
PageOp->Status = STATUS_SUCCESS;
|
||||||
|
@ -314,6 +315,24 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
MmLockAddressSpace(AddressSpace);
|
MmLockAddressSpace(AddressSpace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handle swapped out pages.
|
||||||
|
*/
|
||||||
|
if (MmIsPageSwapEntry(NULL, Address))
|
||||||
|
{
|
||||||
|
SWAPENTRY SwapEntry;
|
||||||
|
PMDL Mdl;
|
||||||
|
|
||||||
|
MmDeletePageFileMapping(NULL, Address, &SwapEntry);
|
||||||
|
Mdl = MmCreateMdl(NULL, NULL, PAGESIZE);
|
||||||
|
MmBuildMdlFromPages(Mdl, (PULONG)&Page);
|
||||||
|
Status = MmReadFromSwapPage(SwapEntry, Mdl);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the page. If we fail because we are out of memory then
|
* Set the page. If we fail because we are out of memory then
|
||||||
* try again
|
* try again
|
||||||
|
@ -381,15 +400,28 @@ MmModifyAttributes(PMADDRESS_SPACE AddressSpace,
|
||||||
{
|
{
|
||||||
LARGE_INTEGER PhysicalAddr;
|
LARGE_INTEGER PhysicalAddr;
|
||||||
|
|
||||||
PhysicalAddr = MmGetPhysicalAddress(BaseAddress + (i*PAGESIZE));
|
if (MmIsPageSwapEntry(AddressSpace->Process,
|
||||||
MmDeleteVirtualMapping(AddressSpace->Process,
|
BaseAddress + (i * PAGESIZE)))
|
||||||
BaseAddress + (i*PAGESIZE),
|
|
||||||
FALSE, NULL, NULL);
|
|
||||||
if (PhysicalAddr.u.LowPart != 0)
|
|
||||||
{
|
{
|
||||||
MmDeleteRmap((PVOID)PhysicalAddr.u.LowPart, AddressSpace->Process,
|
SWAPENTRY SwapEntry;
|
||||||
BaseAddress + (i * PAGESIZE));
|
|
||||||
MmDereferencePage((PVOID)(ULONG)(PhysicalAddr.u.LowPart));
|
MmDeletePageFileMapping(AddressSpace->Process,
|
||||||
|
BaseAddress + (i * PAGESIZE),
|
||||||
|
&SwapEntry);
|
||||||
|
MmFreeSwapPage(SwapEntry);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PhysicalAddr = MmGetPhysicalAddress(BaseAddress + (i*PAGESIZE));
|
||||||
|
MmDeleteVirtualMapping(AddressSpace->Process,
|
||||||
|
BaseAddress + (i*PAGESIZE),
|
||||||
|
FALSE, NULL, NULL);
|
||||||
|
if (PhysicalAddr.u.LowPart != 0)
|
||||||
|
{
|
||||||
|
MmDeleteRmap((PVOID)PhysicalAddr.u.LowPart, AddressSpace->Process,
|
||||||
|
BaseAddress + (i * PAGESIZE));
|
||||||
|
MmDereferencePage((PVOID)(ULONG)(PhysicalAddr.u.LowPart));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1006,6 +1038,7 @@ MmFreeVirtualMemoryPage(PVOID Context,
|
||||||
MEMORY_AREA* MemoryArea,
|
MEMORY_AREA* MemoryArea,
|
||||||
PVOID Address,
|
PVOID Address,
|
||||||
ULONG PhysicalAddr,
|
ULONG PhysicalAddr,
|
||||||
|
SWAPENTRY SwapEntry,
|
||||||
BOOLEAN Dirty)
|
BOOLEAN Dirty)
|
||||||
{
|
{
|
||||||
PEPROCESS Process = (PEPROCESS)Context;
|
PEPROCESS Process = (PEPROCESS)Context;
|
||||||
|
@ -1015,6 +1048,10 @@ MmFreeVirtualMemoryPage(PVOID Context,
|
||||||
MmDeleteRmap((PVOID)PhysicalAddr, Process, Address);
|
MmDeleteRmap((PVOID)PhysicalAddr, Process, Address);
|
||||||
MmDereferencePage((PVOID)PhysicalAddr);
|
MmDereferencePage((PVOID)PhysicalAddr);
|
||||||
}
|
}
|
||||||
|
else if (SwapEntry != 0)
|
||||||
|
{
|
||||||
|
MmFreeSwapPage(SwapEntry);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: handle.c,v 1.33 2001/11/20 02:29:45 dwelch Exp $
|
/* $Id: handle.c,v 1.34 2001/12/31 19:06:48 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -136,19 +136,27 @@ NTSTATUS STDCALL NtDuplicateObject (IN HANDLE SourceProcessHandle,
|
||||||
|
|
||||||
ASSERT_IRQL(PASSIVE_LEVEL);
|
ASSERT_IRQL(PASSIVE_LEVEL);
|
||||||
|
|
||||||
ObReferenceObjectByHandle(SourceProcessHandle,
|
Status = ObReferenceObjectByHandle(SourceProcessHandle,
|
||||||
PROCESS_DUP_HANDLE,
|
PROCESS_DUP_HANDLE,
|
||||||
NULL,
|
NULL,
|
||||||
UserMode,
|
UserMode,
|
||||||
(PVOID*)&SourceProcess,
|
(PVOID*)&SourceProcess,
|
||||||
NULL);
|
NULL);
|
||||||
ObReferenceObjectByHandle(TargetProcessHandle,
|
if (!NT_SUCCESS(Status))
|
||||||
PROCESS_DUP_HANDLE,
|
{
|
||||||
NULL,
|
return(Status);
|
||||||
UserMode,
|
}
|
||||||
(PVOID*)&TargetProcess,
|
Status = ObReferenceObjectByHandle(TargetProcessHandle,
|
||||||
NULL);
|
PROCESS_DUP_HANDLE,
|
||||||
|
NULL,
|
||||||
|
UserMode,
|
||||||
|
(PVOID*)&TargetProcess,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ObDereferenceObject(SourceProcess);
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
KeAcquireSpinLock(&SourceProcess->HandleTable.ListLock, &oldIrql);
|
KeAcquireSpinLock(&SourceProcess->HandleTable.ListLock, &oldIrql);
|
||||||
SourceHandleRep = ObpGetObjectByHandle(&SourceProcess->HandleTable,
|
SourceHandleRep = ObpGetObjectByHandle(&SourceProcess->HandleTable,
|
||||||
SourceHandle);
|
SourceHandle);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: thread.c,v 1.80 2001/12/05 01:40:25 dwelch Exp $
|
/* $Id: thread.c,v 1.81 2001/12/31 19:06:48 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -83,36 +83,55 @@ PsInsertIntoThreadList(KPRIORITY Priority, PETHREAD Thread)
|
||||||
PiNrRunnableThreads++;
|
PiNrRunnableThreads++;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID PsDumpThreads(VOID)
|
VOID PsDumpThreads(BOOLEAN IncludeSystem)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY current_entry;
|
PLIST_ENTRY current_entry;
|
||||||
PETHREAD current;
|
PETHREAD current;
|
||||||
ULONG t;
|
ULONG t;
|
||||||
|
ULONG i;
|
||||||
// return;
|
|
||||||
|
|
||||||
current_entry = PiThreadListHead.Flink;
|
current_entry = PiThreadListHead.Flink;
|
||||||
t = 0;
|
t = 0;
|
||||||
|
|
||||||
while (current_entry != &PiThreadListHead)
|
while (current_entry != &PiThreadListHead)
|
||||||
{
|
{
|
||||||
current = CONTAINING_RECORD(current_entry, ETHREAD,
|
PULONG Ebp;
|
||||||
Tcb.ThreadListEntry);
|
PULONG Esp;
|
||||||
t++;
|
|
||||||
if (t > PiNrThreads)
|
|
||||||
{
|
|
||||||
DbgPrint("Too many threads on list\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
DbgPrint("current %x current->Tcb.State %d eip %x/%x ",
|
|
||||||
current, current->Tcb.State,
|
|
||||||
0, current->Tcb.LastEip);
|
|
||||||
// KeDumpStackFrames((PVOID)current->Tcb.KernelStack,
|
|
||||||
// 16);
|
|
||||||
DbgPrint("PID %d ", current->ThreadsProcess->UniqueProcessId);
|
|
||||||
DbgPrint("\n");
|
|
||||||
|
|
||||||
current_entry = current_entry->Flink;
|
current = CONTAINING_RECORD(current_entry, ETHREAD,
|
||||||
|
Tcb.ThreadListEntry);
|
||||||
|
t++;
|
||||||
|
if (t > PiNrThreads)
|
||||||
|
{
|
||||||
|
DbgPrint("Too many threads on list\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (IncludeSystem || current->ThreadsProcess->UniqueProcessId >= 6)
|
||||||
|
{
|
||||||
|
DbgPrint("current->Tcb.State %d PID.TID %d.%d Name %.8s\n",
|
||||||
|
current->Tcb.State, current->ThreadsProcess->UniqueProcessId,
|
||||||
|
current->Cid.UniqueThread, current->ThreadsProcess->ImageFileName);
|
||||||
|
if (current->Tcb.State == THREAD_STATE_RUNNABLE ||
|
||||||
|
current->Tcb.State == THREAD_STATE_SUSPENDED ||
|
||||||
|
current->Tcb.State == THREAD_STATE_BLOCKED)
|
||||||
|
{
|
||||||
|
Esp = (PULONG)current->Tcb.KernelStack;
|
||||||
|
Ebp = (PULONG)Esp[3];
|
||||||
|
DbgPrint("Ebp 0x%.8X\n", Ebp);
|
||||||
|
i = 0;
|
||||||
|
while (Ebp != 0 && Ebp >= (PULONG)current->Tcb.StackLimit)
|
||||||
|
{
|
||||||
|
DbgPrint("Frame: 0x%.8X Eip: 0x%.8X%s", Ebp[0], Ebp[1],
|
||||||
|
(i % 2) == 1 ? "\n" : "");
|
||||||
|
Ebp = (PULONG)Ebp[0];
|
||||||
|
}
|
||||||
|
if ((i % 2) == 0)
|
||||||
|
{
|
||||||
|
DbgPrint("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
current_entry = current_entry->Flink;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: init.c,v 1.28 2001/12/02 23:37:25 dwelch Exp $
|
/* $Id: init.c,v 1.29 2001/12/31 19:06:49 dwelch Exp $
|
||||||
*
|
*
|
||||||
* init.c - Session Manager initialization
|
* init.c - Session Manager initialization
|
||||||
*
|
*
|
||||||
|
@ -58,6 +58,7 @@ PWSTR SmSystemEnvironment = NULL;
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
|
#if 0
|
||||||
static VOID
|
static VOID
|
||||||
SmCreatePagingFiles (VOID)
|
SmCreatePagingFiles (VOID)
|
||||||
{
|
{
|
||||||
|
@ -126,27 +127,38 @@ SmCreatePagingFiles (VOID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if 0
|
#if 1
|
||||||
static VOID
|
static VOID
|
||||||
SmCreatePagingFiles (VOID)
|
SmCreatePagingFiles (VOID)
|
||||||
{
|
{
|
||||||
UNICODE_STRING FileName;
|
UNICODE_STRING FileName;
|
||||||
ULONG ulCurrentSize;
|
ULONG ulCurrentSize;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
/* FIXME: Read file names from registry */
|
/* FIXME: Read file names from registry */
|
||||||
|
|
||||||
RtlInitUnicodeString (&FileName,
|
RtlInitUnicodeString (&FileName,
|
||||||
L"\\SystemRoot\\pagefile.sys");
|
L"\\SystemRoot\\pagefile.sys");
|
||||||
|
|
||||||
NtCreatePagingFile (&FileName,
|
Status = NtCreatePagingFile (&FileName,
|
||||||
50,
|
50,
|
||||||
80,
|
80,
|
||||||
&ulCurrentSize);
|
&ulCurrentSize);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
PrintString("SM: Failed to create paging file (Status was 0x%.8X)\n", Status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static VOID
|
||||||
|
SmCreatePagingFiles (VOID)
|
||||||
|
{
|
||||||
|
/* Nothing. */
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static VOID
|
static VOID
|
||||||
SmInitDosDevices(VOID)
|
SmInitDosDevices(VOID)
|
||||||
{
|
{
|
||||||
|
@ -437,7 +449,7 @@ BOOL InitSessionManager (HANDLE Children[])
|
||||||
/* FIXME: Load the well known DLLs */
|
/* FIXME: Load the well known DLLs */
|
||||||
|
|
||||||
/* Create paging files */
|
/* Create paging files */
|
||||||
// SmCreatePagingFiles ();
|
SmCreatePagingFiles ();
|
||||||
|
|
||||||
/* Load remaining registry hives */
|
/* Load remaining registry hives */
|
||||||
NtInitializeRegistry (FALSE);
|
NtInitializeRegistry (FALSE);
|
||||||
|
|
Loading…
Reference in a new issue