Change the MEMORY_AREAs to be stored it a binary search tree instead of
linked list. Thanks to Royce Mitchell III and Mike Nordell for helping
me.
Modified: trunk/reactos/ntoskrnl/cc/view.c
Modified: trunk/reactos/ntoskrnl/include/internal/mm.h
Modified: trunk/reactos/ntoskrnl/ke/bug.c
Modified: trunk/reactos/ntoskrnl/ke/i386/exp.c
Modified: trunk/reactos/ntoskrnl/ke/kthread.c
Modified: trunk/reactos/ntoskrnl/mm/anonmem.c
Modified: trunk/reactos/ntoskrnl/mm/aspace.c
Modified: trunk/reactos/ntoskrnl/mm/cont.c
Modified: trunk/reactos/ntoskrnl/mm/drvlck.c
Modified: trunk/reactos/ntoskrnl/mm/iospace.c
Modified: trunk/reactos/ntoskrnl/mm/marea.c
Modified: trunk/reactos/ntoskrnl/mm/mdl.c
Modified: trunk/reactos/ntoskrnl/mm/mm.c
Modified: trunk/reactos/ntoskrnl/mm/mminit.c
Modified: trunk/reactos/ntoskrnl/mm/ncache.c
Modified: trunk/reactos/ntoskrnl/mm/pe.c
Modified: trunk/reactos/ntoskrnl/mm/rmap.c
Modified: trunk/reactos/ntoskrnl/mm/section.c
Modified: trunk/reactos/ntoskrnl/mm/virtual.c
Modified: trunk/reactos/ntoskrnl/ps/w32call.c
_____
Modified: trunk/reactos/ntoskrnl/cc/view.c
--- trunk/reactos/ntoskrnl/cc/view.c 2005-01-02 17:47:07 UTC (rev
12727)
+++ trunk/reactos/ntoskrnl/cc/view.c 2005-01-02 17:55:06 UTC (rev
12728)
@@ -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.79 2004/10/22 20:11:12 ekohl Exp $
+/* $Id$
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/cc/view.c
@@ -813,8 +813,7 @@
#else
MmLockAddressSpace(MmGetKernelAddressSpace());
MmFreeMemoryArea(MmGetKernelAddressSpace(),
- CacheSeg->BaseAddress,
- CacheSeg->Bcb->CacheSegmentSize,
+ CacheSeg->MemoryArea,
CcFreeCachePage,
NULL);
MmUnlockAddressSpace(MmGetKernelAddressSpace());
_____
Modified: trunk/reactos/ntoskrnl/include/internal/mm.h
--- trunk/reactos/ntoskrnl/include/internal/mm.h 2005-01-02
17:47:07 UTC (rev 12727)
+++ trunk/reactos/ntoskrnl/include/internal/mm.h 2005-01-02
17:55:06 UTC (rev 12728)
@@ -184,15 +184,17 @@
#endif /* __USE_W32API */
-typedef struct
+typedef struct _MEMORY_AREA
{
+ PVOID StartingAddress;
+ PVOID EndingAddress;
+ struct _MEMORY_AREA *Parent;
+ struct _MEMORY_AREA *LeftChild;
+ struct _MEMORY_AREA *RightChild;
ULONG Type;
- PVOID BaseAddress;
- ULONG Length;
ULONG Attributes;
- LIST_ENTRY Entry;
ULONG LockCount;
- struct _EPROCESS* Process;
+ struct _EPROCESS* Process; /* FIXME: We don't need this! */
BOOLEAN DeleteInProgress;
ULONG PageOpCount;
union
@@ -215,7 +217,7 @@
typedef struct _MADDRESS_SPACE
{
- LIST_ENTRY MAreaListHead;
+ PMEMORY_AREA MemoryAreaRoot;
FAST_MUTEX Lock;
PVOID LowestAddress;
struct _EPROCESS* Process;
@@ -333,6 +335,10 @@
LIST_ENTRY RegionListEntry;
} MM_REGION, *PMM_REGION;
+typedef VOID (*PMM_FREE_PAGE_FUNC)(PVOID Context, PMEMORY_AREA
MemoryArea,
+ PVOID Address, PFN_TYPE Page,
+ SWAPENTRY SwapEntry, BOOLEAN Dirty);
+
/* FUNCTIONS */
/* aspace.c
******************************************************************/
@@ -354,49 +360,68 @@
/* marea.c
*******************************************************************/
-NTSTATUS MmCreateMemoryArea(struct _EPROCESS* Process,
- PMADDRESS_SPACE AddressSpace,
- ULONG Type,
- PVOID* BaseAddress,
- ULONG Length,
- ULONG Attributes,
- MEMORY_AREA** Result,
- BOOL FixedAddress,
- BOOL TopDown,
- PHYSICAL_ADDRESS BoundaryAddressMultiple
OPTIONAL);
+NTSTATUS INIT_FUNCTION
+MmInitMemoryAreas(VOID);
-MEMORY_AREA* MmOpenMemoryAreaByAddress(PMADDRESS_SPACE AddressSpace,
- PVOID Address);
+NTSTATUS STDCALL
+MmCreateMemoryArea(
+ struct _EPROCESS* Process,
+ PMADDRESS_SPACE AddressSpace,
+ ULONG Type,
+ PVOID *BaseAddress,
+ ULONG_PTR Length,
+ ULONG Attributes,
+ PMEMORY_AREA *Result,
+ BOOLEAN FixedAddress,
+ BOOLEAN TopDown,
+ PHYSICAL_ADDRESS BoundaryAddressMultiple OPTIONAL);
-ULONG MmFindGapAtAddress(PMADDRESS_SPACE AddressSpace,
- PVOID Address);
+PMEMORY_AREA STDCALL
+MmOpenMemoryAreaByAddress(
+ PMADDRESS_SPACE AddressSpace,
+ PVOID Address);
-NTSTATUS MmInitMemoryAreas(VOID);
+ULONG STDCALL
+MmFindGapAtAddress(
+ PMADDRESS_SPACE AddressSpace,
+ PVOID Address);
-NTSTATUS MmFreeMemoryArea(PMADDRESS_SPACE AddressSpace,
- PVOID BaseAddress,
- ULONG Length,
- VOID (*FreePage)(PVOID Context, MEMORY_AREA*
MemoryArea,
- PVOID Address, PFN_TYPE Page,
SWAPENTRY SwapEntry,
- BOOLEAN Dirty),
- PVOID FreePageContext);
+NTSTATUS STDCALL
+MmFreeMemoryArea(
+ PMADDRESS_SPACE AddressSpace,
+ PMEMORY_AREA MemoryArea,
+ PMM_FREE_PAGE_FUNC FreePage,
+ PVOID FreePageContext);
-VOID MmDumpMemoryAreas(PLIST_ENTRY ListHead);
+NTSTATUS STDCALL
+MmFreeMemoryAreaByPtr(
+ PMADDRESS_SPACE AddressSpace,
+ PVOID BaseAddress,
+ PMM_FREE_PAGE_FUNC FreePage,
+ PVOID FreePageContext);
-NTSTATUS MmLockMemoryArea(MEMORY_AREA* MemoryArea);
+VOID STDCALL
+MmDumpMemoryAreas(PMADDRESS_SPACE AddressSpace);
-NTSTATUS MmUnlockMemoryArea(MEMORY_AREA* MemoryArea);
+PMEMORY_AREA STDCALL
+MmOpenMemoryAreaByRegion(
+ PMADDRESS_SPACE AddressSpace,
+ PVOID Address,
+ ULONG_PTR Length);
-MEMORY_AREA* MmOpenMemoryAreaByRegion(PMADDRESS_SPACE AddressSpace,
- PVOID Address,
- ULONG Length);
+PVOID STDCALL
+MmFindGap(
+ PMADDRESS_SPACE AddressSpace,
+ ULONG_PTR Length,
+ ULONG_PTR Granularity,
+ BOOLEAN TopDown);
-PVOID MmFindGap(PMADDRESS_SPACE AddressSpace, ULONG Length, ULONG
Granularity, BOOL TopDown);
+VOID STDCALL
+MmReleaseMemoryAreaIfDecommitted(
+ PEPROCESS Process,
+ PMADDRESS_SPACE AddressSpace,
+ PVOID BaseAddress);
-void MmReleaseMemoryAreaIfDecommitted(PEPROCESS Process,
- PMADDRESS_SPACE AddressSpace,
- PVOID BaseAddress);
-
/* npool.c
*******************************************************************/
VOID MiDebugDumpNonPagedPool(BOOLEAN NewOnly);
_____
Modified: trunk/reactos/ntoskrnl/ke/bug.c
--- trunk/reactos/ntoskrnl/ke/bug.c 2005-01-02 17:47:07 UTC (rev
12727)
+++ trunk/reactos/ntoskrnl/ke/bug.c 2005-01-02 17:55:06 UTC (rev
12728)
@@ -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: bug.c,v 1.48 2004/12/12 17:42:00 hbirr Exp $
+/* $Id$
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/bug.c
@@ -116,6 +116,11 @@
Ke386DisableInterrupts();
DebugLogDumpMessages();
+ if (MmGetKernelAddressSpace()->Lock.Owner == KeGetCurrentThread())
+ {
+ MmUnlockAddressSpace(MmGetKernelAddressSpace());
+ }
+
if (KeGetCurrentIrql() < DISPATCH_LEVEL)
{
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
_____
Modified: trunk/reactos/ntoskrnl/ke/i386/exp.c
--- trunk/reactos/ntoskrnl/ke/i386/exp.c 2005-01-02 17:47:07 UTC
(rev 12727)
+++ trunk/reactos/ntoskrnl/ke/i386/exp.c 2005-01-02 17:55:06 UTC
(rev 12728)
@@ -320,7 +320,7 @@
{
KeRosPrintAddress((PVOID)Frame[1]);
Frame = (PULONG)Frame[0];
- DbgPrint(" ");
+ DbgPrint("\n");
}
#else
DbgPrint("Frames: ");
@@ -663,7 +663,7 @@
break;
StackBase = Frame;
Frame = (PULONG)Frame[0];
- DbgPrint(" ");
+ DbgPrint("\n");
}
}
_SEH_HANDLE
_____
Modified: trunk/reactos/ntoskrnl/ke/kthread.c
--- trunk/reactos/ntoskrnl/ke/kthread.c 2005-01-02 17:47:07 UTC (rev
12727)
+++ trunk/reactos/ntoskrnl/ke/kthread.c 2005-01-02 17:55:06 UTC (rev
12728)
@@ -90,11 +90,10 @@
if (Thread->StackLimit != (ULONG_PTR)&init_stack)
{
MmLockAddressSpace(MmGetKernelAddressSpace());
- MmFreeMemoryArea(MmGetKernelAddressSpace(),
- (PVOID)Thread->StackLimit,
- MM_STACK_SIZE,
- KeFreeStackPage,
- NULL);
+ MmFreeMemoryAreaByPtr(MmGetKernelAddressSpace(),
+ (PVOID)Thread->StackLimit,
+ KeFreeStackPage,
+ NULL);
MmUnlockAddressSpace(MmGetKernelAddressSpace());
}
Thread->StackLimit = 0;
_____
Modified: trunk/reactos/ntoskrnl/mm/anonmem.c
--- trunk/reactos/ntoskrnl/mm/anonmem.c 2005-01-02 17:47:07 UTC (rev
12727)
+++ trunk/reactos/ntoskrnl/mm/anonmem.c 2005-01-02 17:55:06 UTC (rev
12728)
@@ -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: anonmem.c,v 1.34 2004/12/19 16:16:57 navaraf Exp $
+/* $Id$
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/anonmem.c
@@ -261,7 +261,7 @@
/*
* Get the segment corresponding to the virtual address
*/
- Region = MmFindRegion(MemoryArea->BaseAddress,
+ Region = MmFindRegion(MemoryArea->StartingAddress,
&MemoryArea->Data.VirtualMemoryData.RegionListHead,
Address, NULL);
if (Region->Type == MEM_RESERVE || Region->Protect == PAGE_NOACCESS)
@@ -525,6 +525,7 @@
{
PEPROCESS Process;
MEMORY_AREA* MemoryArea;
+ ULONG_PTR MemoryAreaLength;
ULONG Type;
NTSTATUS Status;
PMADDRESS_SPACE AddressSpace;
@@ -582,40 +583,44 @@
MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace,
BaseAddress);
- if (MemoryArea != NULL &&
- MemoryArea->Type == MEMORY_AREA_VIRTUAL_MEMORY &&
- MemoryArea->Length >= RegionSize)
+ if (MemoryArea != NULL)
{
- Status =
- MmAlterRegion(AddressSpace,
- MemoryArea->BaseAddress,
-
&MemoryArea->Data.VirtualMemoryData.RegionListHead,
- BaseAddress, RegionSize,
- Type, Protect, MmModifyAttributes);
- MmUnlockAddressSpace(AddressSpace);
- ObDereferenceObject(Process);
- DPRINT("NtAllocateVirtualMemory() = %x\n",Status);
- return(Status);
+ MemoryAreaLength = (ULONG_PTR)MemoryArea->EndingAddress -
+ (ULONG_PTR)MemoryArea->StartingAddress;
+ if (MemoryArea->Type == MEMORY_AREA_VIRTUAL_MEMORY &&
+ MemoryAreaLength >= RegionSize)
+ {
+ Status =
+ MmAlterRegion(AddressSpace,
+ MemoryArea->StartingAddress,
+
&MemoryArea->Data.VirtualMemoryData.RegionListHead,
+ BaseAddress, RegionSize,
+ Type, Protect, MmModifyAttributes);
+ MmUnlockAddressSpace(AddressSpace);
+ ObDereferenceObject(Process);
+ DPRINT("NtAllocateVirtualMemory() = %x\n",Status);
+ return(Status);
+ }
+ else if (MemoryAreaLength >= RegionSize)
+ {
+ Status =
+ MmAlterRegion(AddressSpace,
+ MemoryArea->StartingAddress,
+
&MemoryArea->Data.SectionData.RegionListHead,
+ BaseAddress, RegionSize,
+ Type, Protect, MmModifyAttributes);
+ MmUnlockAddressSpace(AddressSpace);
+ ObDereferenceObject(Process);
+ DPRINT("NtAllocateVirtualMemory() = %x\n",Status);
+ return(Status);
+ }
+ else
+ {
+ MmUnlockAddressSpace(AddressSpace);
+ ObDereferenceObject(Process);
+ return(STATUS_UNSUCCESSFUL);
+ }
}
- else if (MemoryArea != NULL && MemoryArea->Length >= RegionSize)
- {
- Status =
- MmAlterRegion(AddressSpace,
- MemoryArea->BaseAddress,
- &MemoryArea->Data.SectionData.RegionListHead,
- BaseAddress, RegionSize,
- Type, Protect, MmModifyAttributes);
- MmUnlockAddressSpace(AddressSpace);
- ObDereferenceObject(Process);
- DPRINT("NtAllocateVirtualMemory() = %x\n",Status);
- return(Status);
- }
- else if (MemoryArea != NULL)
- {
- MmUnlockAddressSpace(AddressSpace);
- ObDereferenceObject(Process);
- return(STATUS_UNSUCCESSFUL);
- }
}
Status = MmCreateMemoryArea(Process,
@@ -626,7 +631,7 @@
Protect,
&MemoryArea,
PBaseAddress != 0,
- (AllocationType & MEM_TOP_DOWN),
+ (AllocationType & MEM_TOP_DOWN) ==
MEM_TOP_DOWN,
BoundaryAddressMultiple);
if (!NT_SUCCESS(Status))
{
@@ -635,18 +640,22 @@
DPRINT("NtAllocateVirtualMemory() = %x\n",Status);
return(Status);
}
+
+ MemoryAreaLength = (ULONG_PTR)MemoryArea->EndingAddress -
+ (ULONG_PTR)MemoryArea->StartingAddress;
+
MmInitialiseRegion(&MemoryArea->Data.VirtualMemoryData.RegionListHead,
- MemoryArea->Length, Type, Protect);
+ MemoryAreaLength, Type, Protect);
if ((AllocationType & MEM_COMMIT) &&
((Protect & PAGE_READWRITE) ||
(Protect & PAGE_EXECUTE_READWRITE)))
{
- MmReserveSwapPages(MemoryArea->Length);
+ MmReserveSwapPages(MemoryAreaLength);
}
*UBaseAddress = BaseAddress;
- *URegionSize = MemoryArea->Length;
+ *URegionSize = MemoryAreaLength;
DPRINT("*UBaseAddress %x *URegionSize %x\n", BaseAddress,
RegionSize);
MmUnlockAddressSpace(AddressSpace);
@@ -702,7 +711,11 @@
*/
if (MemoryArea->PageOpCount > 0)
{
- for (i = 0; i < PAGE_ROUND_UP(MemoryArea->Length) / PAGE_SIZE;
i++)
+ ULONG_PTR MemoryAreaLength = (ULONG_PTR)MemoryArea->EndingAddress
-
+
(ULONG_PTR)MemoryArea->StartingAddress;
+
+ /* FiN TODO: Optimize loop counter! */
+ for (i = 0; i < PAGE_ROUND_UP(MemoryAreaLength) / PAGE_SIZE; i++)
{
PMM_PAGEOP PageOp;
@@ -712,7 +725,7 @@
}
PageOp = MmCheckForPageOp(MemoryArea,
Process->UniqueProcessId,
- (char*)MemoryArea->BaseAddress + (i
* PAGE_SIZE),
+
(PVOID)((ULONG_PTR)MemoryArea->StartingAddress + (i * PAGE_SIZE)),
NULL, 0);
if (PageOp != NULL)
{
@@ -745,8 +758,7 @@
/* Actually free the memory area. */
MmFreeMemoryArea(&Process->AddressSpace,
- MemoryArea->BaseAddress,
- 0,
+ MemoryArea,
MmFreeVirtualMemoryPage,
(PVOID)Process);
}
@@ -814,7 +826,7 @@
{
case MEM_RELEASE:
/* We can only free a memory area in one step. */
- if (MemoryArea->BaseAddress != BaseAddress ||
+ if (MemoryArea->StartingAddress != BaseAddress ||
MemoryArea->Type != MEMORY_AREA_VIRTUAL_MEMORY)
{
MmUnlockAddressSpace(AddressSpace);
@@ -829,7 +841,7 @@
case MEM_DECOMMIT:
Status =
MmAlterRegion(AddressSpace,
- MemoryArea->BaseAddress,
+ MemoryArea->StartingAddress,
&MemoryArea->Data.VirtualMemoryData.RegionListHead,
BaseAddress,
RegionSize,
@@ -856,11 +868,11 @@
PMM_REGION Region;
NTSTATUS Status;
- Region = MmFindRegion(MemoryArea->BaseAddress,
+ Region = MmFindRegion(MemoryArea->StartingAddress,
&MemoryArea->Data.VirtualMemoryData.RegionListHead,
BaseAddress, NULL);
*OldProtect = Region->Protect;
- Status = MmAlterRegion(AddressSpace, MemoryArea->BaseAddress,
+ Status = MmAlterRegion(AddressSpace, MemoryArea->StartingAddress,
&MemoryArea->Data.VirtualMemoryData.RegionListHead,
BaseAddress, Length, Region->Type, Protect,
MmModifyAttributes);
@@ -878,11 +890,11 @@
Info->BaseAddress = (PVOID)PAGE_ROUND_DOWN(Address);
- Region = MmFindRegion(MemoryArea->BaseAddress,
+ Region = MmFindRegion(MemoryArea->StartingAddress,
&MemoryArea->Data.VirtualMemoryData.RegionListHead,
Address, &RegionBase);
Info->BaseAddress = RegionBase;
- Info->AllocationBase = MemoryArea->BaseAddress;
+ Info->AllocationBase = MemoryArea->StartingAddress;
Info->AllocationProtect = MemoryArea->Attributes;
Info->RegionSize = (char*)RegionBase + Region->Length -
(char*)Info->BaseAddress;
Info->State = Region->Type;
_____
Modified: trunk/reactos/ntoskrnl/mm/aspace.c
--- trunk/reactos/ntoskrnl/mm/aspace.c 2005-01-02 17:47:07 UTC (rev
12727)
+++ trunk/reactos/ntoskrnl/mm/aspace.c 2005-01-02 17:55:06 UTC (rev
12728)
@@ -68,7 +68,7 @@
MmInitializeAddressSpace(PEPROCESS Process,
PMADDRESS_SPACE AddressSpace)
{
- InitializeListHead(&AddressSpace->MAreaListHead);
+ AddressSpace->MemoryAreaRoot = NULL;
ExInitializeFastMutex(&AddressSpace->Lock);
if (Process != NULL)
{
_____
Modified: trunk/reactos/ntoskrnl/mm/cont.c
--- trunk/reactos/ntoskrnl/mm/cont.c 2005-01-02 17:47:07 UTC (rev
12727)
+++ trunk/reactos/ntoskrnl/mm/cont.c 2005-01-02 17:55:06 UTC (rev
12728)
@@ -1,4 +1,4 @@
-/* $Id: cont.c,v 1.35 2004/10/22 20:38:22 ekohl Exp $
+/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@@ -42,7 +42,7 @@
{
PMEMORY_AREA MArea;
NTSTATUS Status;
- PVOID BaseAddress = 0;
+ PVOID BaseAddress = NULL;
PFN_TYPE PBase;
ULONG Attributes;
ULONG i;
@@ -83,8 +83,7 @@
{
MmLockAddressSpace(MmGetKernelAddressSpace());
MmFreeMemoryArea(MmGetKernelAddressSpace(),
- BaseAddress,
- 0,
+ MArea,
NULL,
NULL);
MmUnlockAddressSpace(MmGetKernelAddressSpace());
@@ -174,11 +173,10 @@
MmFreeContiguousMemory(IN PVOID BaseAddress)
{
MmLockAddressSpace(MmGetKernelAddressSpace());
- MmFreeMemoryArea(MmGetKernelAddressSpace(),
- BaseAddress,
- 0,
- MmFreeContinuousPage,
- NULL);
+ MmFreeMemoryAreaByPtr(MmGetKernelAddressSpace(),
+ BaseAddress,
+ MmFreeContinuousPage,
+ NULL);
MmUnlockAddressSpace(MmGetKernelAddressSpace());
}
@@ -260,11 +258,10 @@
IN MEMORY_CACHING_TYPE CacheType)
{
MmLockAddressSpace(MmGetKernelAddressSpace());
- MmFreeMemoryArea(MmGetKernelAddressSpace(),
- BaseAddress,
- NumberOfBytes,
- MmFreeContinuousPage,
- NULL);
+ MmFreeMemoryAreaByPtr(MmGetKernelAddressSpace(),
+ BaseAddress,
+ MmFreeContinuousPage,
+ NULL);
MmUnlockAddressSpace(MmGetKernelAddressSpace());
}
_____
Modified: trunk/reactos/ntoskrnl/mm/drvlck.c
--- trunk/reactos/ntoskrnl/mm/drvlck.c 2005-01-02 17:47:07 UTC (rev
12727)
+++ trunk/reactos/ntoskrnl/mm/drvlck.c 2005-01-02 17:55:06 UTC (rev
12728)
@@ -1,4 +1,4 @@
-/* $Id: drvlck.c,v 1.6 2004/08/15 16:39:06 chorns Exp $
+/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@@ -64,7 +64,7 @@
MmLockPagableDataSection(IN PVOID AddressWithinSection)
{
PVOID Handle;
- Handle = MmOpenMemoryAreaByAddress(NULL,AddressWithinSection);
+ Handle = MmOpenMemoryAreaByAddress(NULL, AddressWithinSection);
MmLockPagableSectionByHandle(Handle);
return(Handle);
}
_____
Modified: trunk/reactos/ntoskrnl/mm/iospace.c
--- trunk/reactos/ntoskrnl/mm/iospace.c 2005-01-02 17:47:07 UTC (rev
12727)
+++ trunk/reactos/ntoskrnl/mm/iospace.c 2005-01-02 17:55:06 UTC (rev
12728)
@@ -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.30 2004/08/15 16:39:07 chorns Exp $
+/* $Id$
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/iospace.c
@@ -127,7 +127,7 @@
KEBUGCHECK(0);
}
}
- return ((PVOID)((char*)Result + Offset));
+ return (PVOID)((ULONG_PTR)Result + Offset);
}
@@ -160,16 +160,17 @@
IN ULONG NumberOfBytes)
{
ULONG Offset;
- Offset = (ULONG_PTR)BaseAddress % PAGE_SIZE;
- BaseAddress = (PVOID)((PUCHAR)BaseAddress - Offset);
+ PVOID Address = BaseAddress;
+
+ Offset = (ULONG_PTR)Address % PAGE_SIZE;
+ Address -= Offset;
NumberOfBytes += Offset;
MmLockAddressSpace(MmGetKernelAddressSpace());
- MmFreeMemoryArea(MmGetKernelAddressSpace(),
- BaseAddress,
- NumberOfBytes,
- NULL,
- NULL);
+ MmFreeMemoryAreaByPtr(MmGetKernelAddressSpace(),
+ Address,
+ NULL,
+ NULL);
MmUnlockAddressSpace(MmGetKernelAddressSpace());
}
_____
Modified: trunk/reactos/ntoskrnl/mm/marea.c
--- trunk/reactos/ntoskrnl/mm/marea.c 2005-01-02 17:47:07 UTC (rev
12727)
+++ trunk/reactos/ntoskrnl/mm/marea.c 2005-01-02 17:55:06 UTC (rev
12728)
@@ -35,331 +35,590 @@
#define TAG_MAREA TAG('M', 'A', 'R', 'E')
+/* #define VALIDATE_MEMORY_AREAS */
+
/* FUNCTIONS
*****************************************************************/
-VOID MmDumpMemoryAreas(PLIST_ENTRY ListHead)
+/**
+ * @name MmIterateFirstNode
+ *
+ * @param Node
+ * Head node of the MEMORY_AREA tree.
+ *
+ * @return The leftmost MEMORY_AREA node (ie. the one with lowest
+ * address)
+ */
+
+static PMEMORY_AREA MmIterateFirstNode(PMEMORY_AREA Node)
{
- PLIST_ENTRY current_entry;
- MEMORY_AREA* current;
+ while (Node->LeftChild != NULL)
+ Node = Node->LeftChild;
+ return Node;
+}
+
+/**
+ * @name MmIterateNextNode
+ *
+ * @param Node
+ * Current node in the tree.
+ *
+ * @return Next node in the tree (sorted by address).
+ */
+
+static PMEMORY_AREA MmIterateNextNode(PMEMORY_AREA Node)
+{
+ if (Node->RightChild != NULL)
+ {
+ Node = Node->RightChild;
+ while (Node->LeftChild != NULL)
+ Node = Node->LeftChild;
+ }
+ else
+ {
+ PMEMORY_AREA TempNode = NULL;
+
+ do
+ {
+ /* Check if we're at the end of tree. */
+ if (Node->Parent == NULL)
+ return NULL;
+
+ TempNode = Node;
+ Node = Node->Parent;
+ }
+ while (TempNode == Node->RightChild);
+ }
+ return Node;
+}
+
+/**
+ * @name MmIterateFirstNode
+ *
+ * @param Node
+ * Head node of the MEMORY_AREA tree.
+ *
+ * @return The rightmost MEMORY_AREA node (ie. the one with highest
+ * address)
+ */
+
+static PMEMORY_AREA MmIterateLastNode(PMEMORY_AREA Node)
+{
+ while (Node->RightChild != NULL)
+ Node = Node->RightChild;
+
+ return Node;
+}
+
+/**
+ * @name MmIterateNextNode
+ *
+ * @param Node
+ * Current node in the tree.
+ *
+ * @return Previous node in the tree (sorted by address).
+ */
+
+static PMEMORY_AREA MmIteratePrevNode(PMEMORY_AREA Node)
+{
+ if (Node->LeftChild != NULL)
+ {
+ Node = Node->LeftChild;
+ while (Node->RightChild != NULL)
+ Node = Node->RightChild;
+ }
+ else
+ {
+ PMEMORY_AREA TempNode = NULL;
+
+ do
+ {
+ /* Check if we're at the end of tree. */
+ if (Node->Parent == NULL)
+ return NULL;
+
+ TempNode = Node;
+ Node = Node->Parent;
+ }
+ while (TempNode == Node->LeftChild);
+ }
+ return Node;
+}
+
+#ifdef VALIDATE_MEMORY_AREAS
+static VOID MmVerifyMemoryAreas(PMADDRESS_SPACE AddressSpace)
+{
+ PMEMORY_AREA Node;
+
+ ASSERT(AddressSpace != NULL);
+
+ /* Special case for empty tree. */
+ if (AddressSpace->MemoryAreaRoot == NULL)
+ return;
+
+ /* Traverse the tree from left to right. */
+ for (Node = MmIterateFirstNode(AddressSpace->MemoryAreaRoot);
+ Node != NULL;
+ Node = MmIterateNextNode(Node))
+ {
+ /* FiN: The starting address can be NULL if someone explicitely
asks
+ * for NULL address. */
+ ASSERT(Node->StartingAddress >= AddressSpace->LowestAddress ||
+ Node->StartingAddress == NULL);
+ ASSERT(Node->EndingAddress >= Node->StartingAddress);
+ }
+}
+#else
+#define MmVerifyMemoryAreas(x)
+#endif
+
+VOID STDCALL
+MmDumpMemoryAreas(PMADDRESS_SPACE AddressSpace)
+{
+ PMEMORY_AREA Node;
+
DbgPrint("MmDumpMemoryAreas()\n");
+
+ /* Special case for empty tree. */
+ if (AddressSpace->MemoryAreaRoot == NULL)
+ return;
- current_entry = ListHead->Flink;
- while (current_entry!=ListHead)
+ /* Traverse the tree from left to right. */
+ for (Node = MmIterateFirstNode(AddressSpace->MemoryAreaRoot);
+ Node != NULL;
+ Node = MmIterateNextNode(Node))
{
- current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry);
- DbgPrint("Base %x Length %x End %x Attributes %x Flink %x\n",
- current->BaseAddress,current->Length,
-
(char*)current->BaseAddress+current->Length,current->Attributes,
- current->Entry.Flink);
- current_entry = current_entry->Flink;
+ DbgPrint("Start %x End %x Attributes %x\n",
+ Node->StartingAddress, Node->EndingAddress,
+ Node->Attributes);
}
+
DbgPrint("Finished MmDumpMemoryAreas()\n");
}
-MEMORY_AREA* MmOpenMemoryAreaByAddress(PMADDRESS_SPACE AddressSpace,
- PVOID Address)
+PMEMORY_AREA STDCALL
+MmOpenMemoryAreaByAddress(
+ PMADDRESS_SPACE AddressSpace,
+ PVOID Address)
{
- PLIST_ENTRY current_entry;
- MEMORY_AREA* current;
- PLIST_ENTRY previous_entry;
+ PMEMORY_AREA Node = AddressSpace->MemoryAreaRoot;
DPRINT("MmOpenMemoryAreaByAddress(AddressSpace %x, Address %x)\n",
- AddressSpace, Address);
+ AddressSpace, Address);
- previous_entry = &AddressSpace->MAreaListHead;
- current_entry = AddressSpace->MAreaListHead.Flink;
- while (current_entry != &AddressSpace->MAreaListHead)
+ if (!(KdDebugState & KD_DEBUG_SCREEN))
+ MmVerifyMemoryAreas(AddressSpace);
+
+ while (Node != NULL)
{
- current = CONTAINING_RECORD(current_entry,
- MEMORY_AREA,
- Entry);
- ASSERT(current_entry->Blink->Flink == current_entry);
- ASSERT(current_entry->Flink->Blink == current_entry);
- ASSERT(previous_entry->Flink == current_entry);
- if (current->BaseAddress <= Address &&
- (PVOID)((char*)current->BaseAddress + current->Length) >
Address)
+ if (Address < Node->StartingAddress)
+ Node = Node->LeftChild;
+ else if (Address >= Node->EndingAddress)
+ Node = Node->RightChild;
+ else
{
- DPRINT("%s() = %x\n",__FUNCTION__,current);
- return(current);
+ DPRINT("MmOpenMemoryAreaByAddress(%x): %x [%x - %x]\n",
+ Address, Node, Node->StartingAddress,
Node->EndingAddress);
+ return Node;
}
- if (current->BaseAddress > Address)
- {
- DPRINT("%s() = NULL\n",__FUNCTION__);
- return(NULL);
- }
- previous_entry = current_entry;
- current_entry = current_entry->Flink;
}
- DPRINT("%s() = NULL\n",__FUNCTION__);
- return(NULL);
+
+ DPRINT("MmOpenMemoryAreaByAddress(%x): 0\n", Address);
+ return NULL;
}
-MEMORY_AREA* MmOpenMemoryAreaByRegion(PMADDRESS_SPACE AddressSpace,
- PVOID Address,
- ULONG Length)
+PMEMORY_AREA STDCALL
+MmOpenMemoryAreaByRegion(
+ PMADDRESS_SPACE AddressSpace,
+ PVOID Address,
+ ULONG_PTR Length)
{
- PLIST_ENTRY current_entry;
- MEMORY_AREA* current;
- ULONG Extent;
+ PMEMORY_AREA Node;
+ PVOID Extent = (PVOID)((ULONG_PTR)Address + Length);
- DPRINT("MmOpenMemoryByRegion(AddressSpace %x, Address %x, Length
%x)\n",
- AddressSpace, Address, Length);
+ MmVerifyMemoryAreas(AddressSpace);
- current_entry = AddressSpace->MAreaListHead.Flink;
- while (current_entry != &AddressSpace->MAreaListHead)
+ /* Special case for empty tree. */
+ if (AddressSpace->MemoryAreaRoot == NULL)
+ return NULL;
+
+ /* Traverse the tree from left to right. */
+ for (Node = MmIterateFirstNode(AddressSpace->MemoryAreaRoot);
+ Node != NULL;
+ Node = MmIterateNextNode(Node))
{
- current = CONTAINING_RECORD(current_entry,
- MEMORY_AREA,
- Entry);
- DPRINT("current->BaseAddress %x current->Length %x\n",
- current->BaseAddress,current->Length);
- if (current->BaseAddress >= Address &&
- current->BaseAddress < (PVOID)((char*)Address+Length))
+ if (Node->StartingAddress >= Address &&
+ Node->StartingAddress < Extent)
{
- DPRINT("Finished MmOpenMemoryAreaByRegion() = %x\n",
- current);
- return(current);
+ DPRINT("MmOpenMemoryAreaByRegion(%x - %x): %x - %x\n",
+ Address, Address + Length, Node->StartingAddress,
+ Node->EndingAddress);
+ return Node;
}
- Extent = (ULONG)current->BaseAddress + current->Length;
- if (Extent > (ULONG)Address &&
- Extent < (ULONG)((char*)Address+Length))
+ if (Node->EndingAddress > Address &&
+ Node->EndingAddress < Extent)
{
- DPRINT("Finished MmOpenMemoryAreaByRegion() = %x\n",
- current);
- return(current);
+ DPRINT("MmOpenMemoryAreaByRegion(%x - %x): %x - %x\n",
+ Address, Address + Length, Node->StartingAddress,
+ Node->EndingAddress);
+ return Node;
}
- if (current->BaseAddress <= Address &&
- Extent >= (ULONG)((char*)Address+Length))
+ if (Node->StartingAddress <= Address &&
+ Node->EndingAddress >= Extent)
{
- DPRINT("Finished MmOpenMemoryAreaByRegion() = %x\n",
- current);
- return(current);
+ DPRINT("MmOpenMemoryAreaByRegion(%x - %x): %x - %x\n",
+ Address, Address + Length, Node->StartingAddress,
+ Node->EndingAddress);
+ return Node;
}
- if (current->BaseAddress >= (PVOID)((char*)Address+Length))
+ if (Node->StartingAddress >= Extent)
{
- DPRINT("Finished MmOpenMemoryAreaByRegion()= NULL\n",0);
- return(NULL);
+ DPRINT("Finished MmOpenMemoryAreaByRegion() = NULL\n");
+ return NULL;
}
- current_entry = current_entry->Flink;
}
- DPRINT("Finished MmOpenMemoryAreaByRegion() = NULL\n",0);
- return(NULL);
+
+ return NULL;
}
-static VOID MmInsertMemoryArea(PMADDRESS_SPACE AddressSpace,
- MEMORY_AREA* marea)
+/*
+ * @name MmCompressHelper
+ *
+ * This is helper of MmRebalanceTree. Performs a compression
transformation
+ * count times, starting at root.
+ */
+
+static VOID
+MmCompressHelper(
+ PMADDRESS_SPACE AddressSpace,
+ ULONG Count)
{
- PLIST_ENTRY ListHead;
- PLIST_ENTRY current_entry;
- PLIST_ENTRY inserted_entry = &marea->Entry;
- MEMORY_AREA* current;
- MEMORY_AREA* next;
+ PMEMORY_AREA Root = NULL;
+ PMEMORY_AREA Red = AddressSpace->MemoryAreaRoot;
+ PMEMORY_AREA Black = Red->LeftChild;
- DPRINT("MmInsertMemoryArea(marea %x)\n", marea);
- DPRINT("marea->BaseAddress %x\n", marea->BaseAddress);
- DPRINT("marea->Length %x\n", marea->Length);
+ while (Count--)
+ {
+ if (Root)
+ Root->LeftChild = Black;
+ else
+ AddressSpace->MemoryAreaRoot = Black;
+ Black->Parent = Root;
+ Red->LeftChild = Black->RightChild;
+ if (Black->RightChild)
+ Black->RightChild->Parent = Red;
+ Black->RightChild = Red;
+ Red->Parent = Black;
+ Root = Black;
- ListHead = &AddressSpace->MAreaListHead;
-
- current_entry = ListHead->Flink;
- if (IsListEmpty(ListHead))
- {
- InsertHeadList(ListHead,&marea->Entry);
- return;
- }
- current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry);
- if (current->BaseAddress > marea->BaseAddress)
- {
- InsertHeadList(ListHead,&marea->Entry);
- return;
- }
- while (current_entry->Flink!=ListHead)
- {
- current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry);
- next = CONTAINING_RECORD(current_entry->Flink,MEMORY_AREA,Entry);
- if (current->BaseAddress < marea->BaseAddress &&
- current->Entry.Flink==ListHead)
+ if (Count)
{
- current_entry->Flink = inserted_entry;
- inserted_entry->Flink=ListHead;
- inserted_entry->Blink=current_entry;
- ListHead->Blink = inserted_entry;
- return;
+ Red = Root->LeftChild;
+ Black = Red->LeftChild;
}
- if (current->BaseAddress < marea->BaseAddress &&
[truncated at 1000 lines; 1533 more skipped]