Implemented Top-Down-Allocator.

svn path=/trunk/; revision=4704
This commit is contained in:
Eric Kohl 2003-05-17 15:29:50 +00:00
parent c865c87d30
commit e1c437438c
13 changed files with 154 additions and 44 deletions

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: view.c,v 1.58 2003/02/18 22:06:53 chorns Exp $
/* $Id: view.c,v 1.59 2003/05/17 15:27:34 ekohl Exp $
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/cc/view.c
@ -543,6 +543,7 @@ CcRosCreateCacheSegment(PBCB Bcb,
Bcb->CacheSegmentSize,
PAGE_READWRITE,
(PMEMORY_AREA*)&current->MemoryArea,
FALSE,
FALSE);
MmUnlockAddressSpace(MmGetKernelAddressSpace());
if (!NT_SUCCESS(Status))

View file

@ -126,7 +126,7 @@ typedef struct
union
{
struct
{
{
SECTION_OBJECT* Section;
ULONG ViewOffset;
LIST_ENTRY ViewListEntry;
@ -169,7 +169,8 @@ NTSTATUS MmCreateMemoryArea(struct _EPROCESS* Process,
ULONG Length,
ULONG Attributes,
MEMORY_AREA** Result,
BOOL FixedAddress);
BOOL FixedAddress,
BOOL TopDown);
MEMORY_AREA* MmOpenMemoryAreaByAddress(PMADDRESS_SPACE AddressSpace,
PVOID Address);
NTSTATUS MmInitMemoryAreas(VOID);
@ -289,7 +290,7 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
MEMORY_AREA* MmOpenMemoryAreaByRegion(PMADDRESS_SPACE AddressSpace,
PVOID Address,
ULONG Length);
PVOID MmFindGap(PMADDRESS_SPACE AddressSpace, ULONG Length);
PVOID MmFindGap(PMADDRESS_SPACE AddressSpace, ULONG Length, BOOL TopDown);
VOID ExUnmapPage(PVOID Addr);
PVOID ExAllocatePage(VOID);

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: kthread.c,v 1.36 2003/04/06 10:45:16 chorns Exp $
/* $Id: kthread.c,v 1.37 2003/05/17 15:28:06 ekohl Exp $
*
* FILE: ntoskrnl/ke/kthread.c
* PURPOSE: Microkernel thread support
@ -106,6 +106,7 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First)
MM_STACK_SIZE,
0,
&StackArea,
FALSE,
FALSE);
MmUnlockAddressSpace(MmGetKernelAddressSpace());

View file

@ -16,14 +16,14 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: anonmem.c,v 1.12 2003/04/28 10:37:39 gvg Exp $
/* $Id: anonmem.c,v 1.13 2003/05/17 15:28:58 ekohl Exp $
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/anonmem.c
* PURPOSE: Implementing anonymous memory.
* PROGRAMMER: David Welch
*/
/* INCLUDE *****************************************************************/
#include <ddk/ntddk.h>
@ -624,8 +624,8 @@ NtAllocateVirtualMemory(IN HANDLE ProcessHandle,
RegionSize,
Protect,
&MemoryArea,
PBaseAddress != 0);
PBaseAddress != 0,
(AllocationType & MEM_TOP_DOWN));
if (!NT_SUCCESS(Status))
{
MmUnlockAddressSpace(AddressSpace);

View file

@ -1,4 +1,4 @@
/* $Id: cont.c,v 1.25 2002/11/05 20:35:33 hbirr Exp $
/* $Id: cont.c,v 1.26 2003/05/17 15:28:58 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -50,6 +50,7 @@ MmAllocateContiguousAlignedMemory(IN ULONG NumberOfBytes,
NumberOfBytes,
0,
&MArea,
FALSE,
FALSE);
MmUnlockAddressSpace(MmGetKernelAddressSpace());

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: iospace.c,v 1.17 2002/11/05 20:35:33 hbirr Exp $
/* $Id: iospace.c,v 1.18 2003/05/17 15:28:58 ekohl Exp $
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/iospace.c
@ -84,6 +84,7 @@ MmMapIoSpace (IN PHYSICAL_ADDRESS PhysicalAddress,
NumberOfBytes,
0,
&marea,
FALSE,
FALSE);
MmUnlockAddressSpace(MmGetKernelAddressSpace());

View file

@ -1,6 +1,6 @@
/*
* ReactOS kernel
* Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
* Copyright (C) 1998, 1999, 2000, 2001, 2003 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
@ -188,12 +188,12 @@ static VOID MmInsertMemoryArea(PMADDRESS_SPACE AddressSpace,
current_entry->Flink = inserted_entry;
inserted_entry->Flink=ListHead;
inserted_entry->Blink=current_entry;
ListHead->Blink = inserted_entry;
ListHead->Blink = inserted_entry;
return;
}
if (current->BaseAddress < marea->BaseAddress &&
next->BaseAddress > marea->BaseAddress)
{
{
inserted_entry->Flink = current_entry->Flink;
inserted_entry->Blink = current_entry;
inserted_entry->Flink->Blink = inserted_entry;
@ -205,7 +205,8 @@ static VOID MmInsertMemoryArea(PMADDRESS_SPACE AddressSpace,
InsertTailList(ListHead,inserted_entry);
}
PVOID MmFindGap(PMADDRESS_SPACE AddressSpace, ULONG Length)
PVOID MmFindGapBottomUp(PMADDRESS_SPACE AddressSpace, ULONG Length)
{
PLIST_ENTRY ListHead;
PLIST_ENTRY current_entry;
@ -214,7 +215,7 @@ PVOID MmFindGap(PMADDRESS_SPACE AddressSpace, ULONG Length)
ULONG Gap;
PVOID Address;
DPRINT("MmFindGap(Length %x)\n",Length);
DPRINT("MmFindGapBottomUp(Length %x)\n",Length);
ListHead = &AddressSpace->MAreaListHead;
@ -258,6 +259,94 @@ PVOID MmFindGap(PMADDRESS_SPACE AddressSpace, ULONG Length)
return Address;
}
PVOID MmFindGapTopDown(PMADDRESS_SPACE AddressSpace, ULONG Length)
{
PLIST_ENTRY ListHead;
PLIST_ENTRY current_entry;
MEMORY_AREA* current;
ULONG Gap;
PVOID Address;
PVOID TopAddress;
PVOID BottomAddress;
PVOID HighestAddress;
DPRINT("MmFindGapTopDown(Length %lx)\n",Length);
if (AddressSpace->LowestAddress < KERNEL_BASE)
{
HighestAddress = (PVOID)0x7FFE0000; /* Start below the PEB */
}
else
{
HighestAddress = (PVOID)0xFFFFFFFF;
}
TopAddress = HighestAddress;
ListHead = &AddressSpace->MAreaListHead;
current_entry = ListHead->Blink;
while (current_entry->Blink != ListHead)
{
current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry);
BottomAddress = current->BaseAddress + PAGE_ROUND_UP(current->Length);
DPRINT("Base %p Length %lx\n", current->BaseAddress, PAGE_ROUND_UP(current->Length));
if (BottomAddress < HighestAddress)
{
Gap = TopAddress - BottomAddress;
DPRINT("Bottom %p Top %p Gap %lx\n", BottomAddress, TopAddress, Gap);
if (Gap >= Length)
{
DPRINT1("Found gap at %p\n", TopAddress - Length);
return(TopAddress - Length);
}
TopAddress = current->BaseAddress;
}
current_entry = current_entry->Blink;
}
if (current_entry == ListHead)
{
Address = (PVOID)HighestAddress - Length;
}
else
{
Address = TopAddress - Length;
}
/* Check if enough space for the block */
if (AddressSpace->LowestAddress < KERNEL_BASE)
{
if ((ULONG)Address >= KERNEL_BASE || Length > KERNEL_BASE - (ULONG)Address)
{
DPRINT("Failed to find gap\n");
return NULL;
}
}
else
{
if (Length >= 0xFFFFFFFF - (ULONG)Address)
{
DPRINT("Failed to find gap\n");
return NULL;
}
}
DPRINT("Found gap at %p\n", Address);
return Address;
}
PVOID MmFindGap(PMADDRESS_SPACE AddressSpace, ULONG Length, BOOL TopDown)
{
if (TopDown)
return MmFindGapTopDown(AddressSpace, Length);
return MmFindGapBottomUp(AddressSpace, Length);
}
NTSTATUS MmInitMemoryAreas(VOID)
/*
* FUNCTION: Initialize the memory area list
@ -286,7 +375,7 @@ MmFreeMemoryArea(PMADDRESS_SPACE AddressSpace,
MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace,
BaseAddress);
if (MemoryArea == NULL)
{
{
KeBugCheck(0);
return(STATUS_UNSUCCESSFUL);
}
@ -381,7 +470,8 @@ NTSTATUS MmCreateMemoryArea(PEPROCESS Process,
ULONG Length,
ULONG Attributes,
MEMORY_AREA** Result,
BOOL FixedAddress)
BOOL FixedAddress,
BOOL TopDown)
/*
* FUNCTION: Create a memory area
* ARGUMENTS:
@ -400,12 +490,13 @@ NTSTATUS MmCreateMemoryArea(PEPROCESS Process,
"*BaseAddress %x, Length %x, Attributes %x, Result %x)\n",
Type,BaseAddress,*BaseAddress,Length,Attributes,Result);
if ((*BaseAddress)==0 && !FixedAddress)
if ((*BaseAddress) == 0 && !FixedAddress)
{
tmpLength = PAGE_ROUND_UP(Length);
tmpLength = PAGE_ROUND_UP(Length);
*BaseAddress = MmFindGap(AddressSpace,
PAGE_ROUND_UP(Length) +(PAGE_SIZE*2));
if ((*BaseAddress)==0)
PAGE_ROUND_UP(Length) +(PAGE_SIZE*2),
TopDown);
if ((*BaseAddress) == 0)
{
DPRINT("No suitable gap\n");
return(STATUS_NO_MEMORY);
@ -413,9 +504,9 @@ NTSTATUS MmCreateMemoryArea(PEPROCESS Process,
(*BaseAddress)=(*BaseAddress)+PAGE_SIZE;
}
else
{
{
tmpLength = (ULONG)*BaseAddress + Length - PAGE_ROUND_DOWN((*BaseAddress));
(*BaseAddress) = (PVOID)PAGE_ROUND_DOWN((*BaseAddress));
(*BaseAddress) = (PVOID)PAGE_ROUND_DOWN((*BaseAddress));
if (MmOpenMemoryAreaByRegion(AddressSpace,
*BaseAddress,
tmpLength)!=NULL)

View file

@ -1,4 +1,4 @@
/* $Id: mdl.c,v 1.47 2002/11/10 18:17:42 chorns Exp $
/* $Id: mdl.c,v 1.48 2003/05/17 15:28:58 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -51,6 +51,7 @@ MmInitializeMdlImplementation(VOID)
MI_MDL_MAPPING_REGION_SIZE,
0,
&Result,
FALSE,
FALSE);
if (!NT_SUCCESS(Status))
{

View file

@ -1,4 +1,4 @@
/* $Id: mminit.c,v 1.44 2003/05/17 13:45:04 hbirr Exp $
/* $Id: mminit.c,v 1.45 2003/05/17 15:28:58 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top directory
* PROJECT: ReactOS kernel
@ -106,6 +106,7 @@ VOID MmInitVirtualMemory(ULONG LastKernelAddress,
Length,
0,
&kernel_text_desc,
FALSE,
FALSE);
Length = PAGE_ROUND_UP(((ULONG)&_bss_end__)) -
@ -120,24 +121,26 @@ VOID MmInitVirtualMemory(ULONG LastKernelAddress,
* the only thread running.
*/
MmCreateMemoryArea(NULL,
MmGetKernelAddressSpace(),
MmGetKernelAddressSpace(),
MEMORY_AREA_SYSTEM,
&BaseAddress,
Length,
0,
&kernel_data_desc,
FALSE,
FALSE);
BaseAddress = (PVOID)PAGE_ROUND_UP(((ULONG)&_bss_end__));
// Length = ParamLength;
Length = LastKernelAddress - (ULONG)BaseAddress;
MmCreateMemoryArea(NULL,
MmGetKernelAddressSpace(),
MmGetKernelAddressSpace(),
MEMORY_AREA_SYSTEM,
&BaseAddress,
Length,
0,
&kernel_param_desc,
FALSE,
FALSE);
BaseAddress = (PVOID)(LastKernelAddress + PAGE_SIZE);
@ -149,6 +152,7 @@ VOID MmInitVirtualMemory(ULONG LastKernelAddress,
Length,
0,
&kernel_pool_desc,
FALSE,
FALSE);
MmPagedPoolSize = MM_PAGED_POOL_SIZE;
@ -163,6 +167,7 @@ VOID MmInitVirtualMemory(ULONG LastKernelAddress,
Length,
0,
&MiPagedPoolDescriptor,
FALSE,
FALSE);
MmInitializePagedPool();
@ -178,6 +183,7 @@ VOID MmInitVirtualMemory(ULONG LastKernelAddress,
Length,
0,
&kernel_shared_data_desc,
FALSE,
FALSE);
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE,
&MmSharedDataPagePhysicalAddress);

View file

@ -1,4 +1,4 @@
/* $Id: ncache.c,v 1.23 2002/11/05 20:35:33 hbirr Exp $
/* $Id: ncache.c,v 1.24 2003/05/17 15:28:58 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -62,6 +62,7 @@ MmAllocateNonCachedMemory(IN ULONG NumberOfBytes)
NumberOfBytes,
0,
&marea,
FALSE,
FALSE);
MmUnlockAddressSpace(MmGetKernelAddressSpace());

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: section.c,v 1.112 2003/05/17 13:43:44 hbirr Exp $
/* $Id: section.c,v 1.113 2003/05/17 15:28:58 ekohl Exp $
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/section.c
@ -2790,7 +2790,8 @@ MmMapViewOfSegment(PEPROCESS Process,
PVOID* BaseAddress,
ULONG ViewSize,
ULONG Protect,
ULONG ViewOffset)
ULONG ViewOffset,
BOOL TopDown)
{
PMEMORY_AREA MArea;
NTSTATUS Status;
@ -2803,7 +2804,8 @@ MmMapViewOfSegment(PEPROCESS Process,
ViewSize,
Protect,
&MArea,
FALSE);
FALSE,
TopDown);
if (!NT_SUCCESS(Status))
{
DPRINT1("Mapping between 0x%.8X and 0x%.8X failed.\n",
@ -3280,6 +3282,7 @@ MmAllocateSection (IN ULONG Length)
Length,
0,
&marea,
FALSE,
FALSE);
if (!NT_SUCCESS(Status))
{
@ -3305,7 +3308,7 @@ MmAllocateSection (IN ULONG Length)
TRUE);
if (!NT_SUCCESS(Status))
{
DbgPrint("Unable to create virtual mapping\n");
DbgPrint("Unable to create virtual mapping\n");
KeBugCheck(0);
}
}
@ -3420,7 +3423,7 @@ MmMapViewOfSection(IN PVOID SectionObject,
return(STATUS_UNSUCCESSFUL);
}
/* Otherwise find a gap to map the image. */
ImageBase = MmFindGap(AddressSpace, PAGE_ROUND_UP(ImageSize));
ImageBase = MmFindGap(AddressSpace, PAGE_ROUND_UP(ImageSize), FALSE);
if (ImageBase == NULL)
{
MmUnlockSection(Section);
@ -3446,7 +3449,8 @@ MmMapViewOfSection(IN PVOID SectionObject,
&SBaseAddress,
Section->Segments[i].Length,
Section->Segments[i].Protection,
Section->Segments[i].FileOffset);
Section->Segments[i].FileOffset,
FALSE);
MmUnlockSectionSegment(&Section->Segments[i]);
if (!NT_SUCCESS(Status))
{
@ -3521,7 +3525,8 @@ MmMapViewOfSection(IN PVOID SectionObject,
BaseAddress,
*ViewSize,
Protect,
ViewOffset);
ViewOffset,
(AllocationType & MEM_TOP_DOWN));
MmUnlockSectionSegment(Section->Segments);
MmUnlockAddressSpace(AddressSpace);
if (!NT_SUCCESS(Status))
@ -3618,7 +3623,8 @@ MmMapViewInSystemSpace (IN PVOID SectionObject,
MappedBase,
*ViewSize,
PAGE_READWRITE,
0);
0,
FALSE);
MmUnlockSectionSegment(Section->Segments);
MmUnlockAddressSpace(AddressSpace);

View file

@ -1,4 +1,4 @@
/* $Id: process.c,v 1.99 2003/05/16 17:37:17 ekohl Exp $
/* $Id: process.c,v 1.100 2003/05/17 15:29:50 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -586,9 +586,7 @@ NtCreateProcess(OUT PHANDLE ProcessHandle,
* Now we have created the process proper
*/
/*
* Create the shared data page
*/
/* Create the shared data page */
MmLockAddressSpace(&Process->AddressSpace);
BaseAddress = (PVOID)USER_SHARED_DATA;
Status = MmCreateMemoryArea(Process,
@ -598,6 +596,7 @@ NtCreateProcess(OUT PHANDLE ProcessHandle,
PAGE_SIZE,
PAGE_READONLY,
&MemoryArea,
FALSE,
FALSE);
MmUnlockAddressSpace(&Process->AddressSpace);
if (!NT_SUCCESS(Status))
@ -605,7 +604,7 @@ NtCreateProcess(OUT PHANDLE ProcessHandle,
DPRINT1("Failed to create shared data page\n");
KeBugCheck(0);
}
/*
* Map ntdll
*/

View file

@ -1,4 +1,4 @@
/* $Id: w32call.c,v 1.5 2002/10/01 19:27:25 chorns Exp $
/* $Id: w32call.c,v 1.6 2003/05/17 15:29:50 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -162,8 +162,9 @@ PsAllocateCallbackStack(ULONG StackSize)
StackSize,
0,
&StackArea,
FALSE,
FALSE);
MmUnlockAddressSpace(MmGetKernelAddressSpace());
MmUnlockAddressSpace(MmGetKernelAddressSpace());
if (!NT_SUCCESS(Status))
{
DPRINT("Failed to create thread stack\n");