1
0
Fork 0
mirror of https://github.com/reactos/reactos.git synced 2025-06-10 12:24:48 +00:00

[RTL/DPH]

- Fix a bug with node count in RtlpDphAddNewPool().
- Unprotect needed amount of memory in RtlpDphSetProtectionBeforeUse() instead of always assuming PAGE_SIZE.
- Fix an incorrect virtual block pointer calculation in RtlpPageHeapAllocate(). 
- Silence RtlpDphShouldAllocateInPageHeap() debug print.
- Add helpful debug prints (disabled by default).
- Some code cleanup for better readibility.
- Heap create, destroy and allocating a block from the heap work now.

svn path=/trunk/; revision=50828
This commit is contained in:
Aleksey Bragin 2011-02-20 09:54:01 +00:00
parent ebc9df1a25
commit 37ab9f5320

View file

@ -313,7 +313,7 @@ RtlpDphAllocateVm(PVOID *Base, SIZE_T Size, ULONG Type, ULONG Protection)
&Size, &Size,
Type, Type,
Protection); Protection);
DPRINT1("Page heap: AllocVm (%p, %p, %x) status %x \n", Base, Size, Type, Status); DPRINT("Page heap: AllocVm (%p, %p, %x) status %x \n", Base, Size, Type, Status);
/* Check for failures */ /* Check for failures */
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
@ -434,6 +434,8 @@ RtlpDphPlaceOnBusyList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK DphNode)
BOOLEAN NewElement; BOOLEAN NewElement;
PVOID AddressUserData; PVOID AddressUserData;
DPRINT("RtlpDphPlaceOnBusyList(%p %p)\n", DphRoot, DphNode);
/* Add it to the AVL busy nodes table */ /* Add it to the AVL busy nodes table */
DphRoot->NodeToAllocate = DphNode; DphRoot->NodeToAllocate = DphNode;
AddressUserData = RtlInsertElementGenericTableAvl(&DphRoot->BusyNodesTable, AddressUserData = RtlInsertElementGenericTableAvl(&DphRoot->BusyNodesTable,
@ -451,35 +453,35 @@ RtlpDphPlaceOnBusyList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK DphNode)
} }
VOID NTAPI VOID NTAPI
RtlpDphPlaceOnPoolList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK DphNode) RtlpDphPlaceOnPoolList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
{ {
/* DphNode is being added to the tail of the list */ /* DphNode is being added to the tail of the list */
DphNode->pNextAlloc = NULL; Node->pNextAlloc = NULL;
/* Add it to the tail of the linked list */ /* Add it to the tail of the linked list */
if (DphRoot->pNodePoolListTail) if (DphRoot->pNodePoolListTail)
DphRoot->pNodePoolListTail->pNextAlloc = DphNode; DphRoot->pNodePoolListTail->pNextAlloc = Node;
else else
DphRoot->pNodePoolListHead = DphNode; DphRoot->pNodePoolListHead = Node;
DphRoot->pNodePoolListTail = DphNode; DphRoot->pNodePoolListTail = Node;
/* Update byte counts taking in account this new node */ /* Update byte counts taking in account this new node */
DphRoot->nNodePools++; DphRoot->nNodePools++;
DphRoot->nNodePoolBytes += DphNode->nVirtualBlockSize; DphRoot->nNodePoolBytes += Node->nVirtualBlockSize;
} }
VOID NTAPI VOID NTAPI
RtlpDphPlaceOnVirtualList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK DphNode) RtlpDphPlaceOnVirtualList(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK Node)
{ {
/* Add it to the head of the virtual list */ /* Add it to the head of the virtual list */
DphNode->pNextAlloc = DphRoot->pVirtualStorageListHead; Node->pNextAlloc = DphRoot->pVirtualStorageListHead;
if (!DphRoot->pVirtualStorageListHead) if (!DphRoot->pVirtualStorageListHead)
DphRoot->pVirtualStorageListTail = DphNode; DphRoot->pVirtualStorageListTail = Node;
DphRoot->pVirtualStorageListHead = DphNode; DphRoot->pVirtualStorageListHead = Node;
/* Update byte counts taking in account this new node */ /* Update byte counts taking in account this new node */
DphRoot->nVirtualStorageRanges++; DphRoot->nVirtualStorageRanges++;
DphRoot->nVirtualStorageBytes += DphNode->nVirtualBlockSize; DphRoot->nVirtualStorageBytes += Node->nVirtualBlockSize;
} }
PDPH_HEAP_BLOCK NTAPI PDPH_HEAP_BLOCK NTAPI
@ -508,7 +510,8 @@ RtlpDphReturnNodeToUnusedList(PDPH_HEAP_ROOT DphRoot,
{ {
/* Add it back to the head of the unused list */ /* Add it back to the head of the unused list */
Node->pNextAlloc = DphRoot->pUnusedNodeListHead; Node->pNextAlloc = DphRoot->pUnusedNodeListHead;
if (!DphRoot->pUnusedNodeListHead) DphRoot->pUnusedNodeListTail = Node; if (!DphRoot->pUnusedNodeListHead)
DphRoot->pUnusedNodeListTail = Node;
DphRoot->pUnusedNodeListHead = Node; DphRoot->pUnusedNodeListHead = Node;
/* Increase amount of unused nodes */ /* Increase amount of unused nodes */
@ -523,6 +526,8 @@ RtlpDphRemoveFromAvailableList(PDPH_HEAP_ROOT DphRoot,
//ASSERT(IS_BIASED_POINTER(Node->AdjacencyEntry.Flink)); //ASSERT(IS_BIASED_POINTER(Node->AdjacencyEntry.Flink));
//ASSERT(IS_BIASED_POINTER(Node->AdjacencyEntry.Blink)); //ASSERT(IS_BIASED_POINTER(Node->AdjacencyEntry.Blink));
DPRINT("RtlpDphRemoveFromAvailableList(%p %p)\n", DphRoot, Node);
/* Remove it from the list */ /* Remove it from the list */
RemoveEntryList(&Node->AvailableEntry); RemoveEntryList(&Node->AvailableEntry);
@ -565,6 +570,8 @@ RtlpDphCoalesceNodeIntoAvailable(PDPH_HEAP_ROOT DphRoot,
PLIST_ENTRY AvailListHead; PLIST_ENTRY AvailListHead;
PLIST_ENTRY CurEntry; PLIST_ENTRY CurEntry;
DPRINT("RtlpDphCoalesceNodeIntoAvailable(%p %p)\n", DphRoot, Node);
/* Update heap counters */ /* Update heap counters */
DphRoot->nAvailableAllocationBytesCommitted += Node->nVirtualBlockSize; DphRoot->nAvailableAllocationBytesCommitted += Node->nVirtualBlockSize;
DphRoot->nAvailableAllocations++; DphRoot->nAvailableAllocations++;
@ -658,14 +665,18 @@ VOID NTAPI
RtlpDphAddNewPool(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK NodeBlock, PVOID Virtual, SIZE_T Size, BOOLEAN PlaceOnPool) RtlpDphAddNewPool(PDPH_HEAP_ROOT DphRoot, PDPH_HEAP_BLOCK NodeBlock, PVOID Virtual, SIZE_T Size, BOOLEAN PlaceOnPool)
{ {
PDPH_HEAP_BLOCK DphNode, DphStartNode; PDPH_HEAP_BLOCK DphNode, DphStartNode;
ULONG NodeCount; ULONG NodeCount, i;
NodeCount = (Size >> 6) - 1; //NodeCount = (Size >> 6) - 1;
NodeCount = (Size / sizeof(DPH_HEAP_BLOCK));
DphStartNode = Virtual; DphStartNode = Virtual;
/* Set pNextAlloc for all blocks */ /* Set pNextAlloc for all blocks */
for (DphNode = Virtual; NodeCount > 0; DphNode++, NodeCount--) for (DphNode = Virtual, i=NodeCount-1; i > 0; i--)
{
DphNode->pNextAlloc = DphNode + 1; DphNode->pNextAlloc = DphNode + 1;
DphNode = DphNode->pNextAlloc;
}
/* and the last one */ /* and the last one */
DphNode->pNextAlloc = NULL; DphNode->pNextAlloc = NULL;
@ -797,13 +808,13 @@ RtlpDphSetProtectionBeforeUse(PDPH_HEAP_ROOT DphRoot, PUCHAR VirtualBlock, ULONG
} }
else else
{ {
Base = VirtualBlock + UserSize; Base = VirtualBlock + PAGE_SIZE;
} }
// FIXME: It should be different, but for now it's fine // FIXME: It should be different, but for now it's fine
Protection = PAGE_READWRITE; Protection = PAGE_READWRITE;
return RtlpDphProtectVm(Base, PAGE_SIZE, Protection); return RtlpDphProtectVm(Base, UserSize, Protection);
} }
PDPH_HEAP_BLOCK NTAPI PDPH_HEAP_BLOCK NTAPI
@ -1284,7 +1295,8 @@ BOOLEAN NTAPI
RtlpDphShouldAllocateInPageHeap(PDPH_HEAP_ROOT DphRoot, RtlpDphShouldAllocateInPageHeap(PDPH_HEAP_ROOT DphRoot,
SIZE_T Size) SIZE_T Size)
{ {
UNIMPLEMENTED; //UNIMPLEMENTED;
/* Always use page heap for now */
return TRUE; return TRUE;
} }
@ -1517,9 +1529,10 @@ RtlpPageHeapAllocate(IN PVOID HeapPtr,
PDPH_HEAP_ROOT DphRoot; PDPH_HEAP_ROOT DphRoot;
PDPH_HEAP_BLOCK Node, AllocatedNode; PDPH_HEAP_BLOCK Node, AllocatedNode;
BOOLEAN Biased = FALSE; BOOLEAN Biased = FALSE;
ULONG TotalSize, UserSize; ULONG TotalSize, AccessSize;
NTSTATUS Status; NTSTATUS Status;
SIZE_T UserActualSize; SIZE_T UserActualSize;
PVOID Ptr;
/* Check requested size */ /* Check requested size */
if (Size > 0x7FF00000) if (Size > 0x7FF00000)
@ -1569,8 +1582,8 @@ RtlpPageHeapAllocate(IN PVOID HeapPtr,
} }
/* Calculate sizes */ /* Calculate sizes */
UserSize = ROUND_UP(Size + sizeof(DPH_BLOCK_INFORMATION), PAGE_SIZE); AccessSize = ROUND_UP(Size + sizeof(DPH_BLOCK_INFORMATION), PAGE_SIZE);
TotalSize = UserSize + PAGE_SIZE; TotalSize = AccessSize + PAGE_SIZE;
// RtlpDphAllocateNode(DphRoot); // RtlpDphAllocateNode(DphRoot);
Node = RtlpDphFindAvailableMemory(DphRoot, TotalSize, TRUE); Node = RtlpDphFindAvailableMemory(DphRoot, TotalSize, TRUE);
@ -1587,12 +1600,14 @@ RtlpPageHeapAllocate(IN PVOID HeapPtr,
ASSERT(Node->nVirtualBlockSize >= TotalSize); ASSERT(Node->nVirtualBlockSize >= TotalSize);
/* Set protection */ /* Set protection */
Status = RtlpDphSetProtectionBeforeUse(DphRoot, Node->pVirtualBlock, UserSize); Status = RtlpDphSetProtectionBeforeUse(DphRoot, Node->pVirtualBlock, AccessSize);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
ASSERT(FALSE); ASSERT(FALSE);
} }
Ptr = Node->pVirtualBlock;
/* Check node's size */ /* Check node's size */
if (Node->nVirtualBlockSize > TotalSize) if (Node->nVirtualBlockSize > TotalSize)
{ {
@ -1603,7 +1618,7 @@ RtlpPageHeapAllocate(IN PVOID HeapPtr,
AllocatedNode = RtlpDphAllocateNode(DphRoot); AllocatedNode = RtlpDphAllocateNode(DphRoot);
ASSERT(AllocatedNode != NULL); ASSERT(AllocatedNode != NULL);
AllocatedNode->pVirtualBlock = Node->pVirtualBlock - TotalSize; AllocatedNode->pVirtualBlock = Ptr;
AllocatedNode->nVirtualBlockSize = TotalSize; AllocatedNode->nVirtualBlockSize = TotalSize;
} }
else else
@ -1620,7 +1635,7 @@ RtlpPageHeapAllocate(IN PVOID HeapPtr,
UserActualSize = ROUND_UP(Size, 8); UserActualSize = ROUND_UP(Size, 8);
/* Set up the block */ /* Set up the block */
AllocatedNode->nVirtualAccessSize = UserSize; AllocatedNode->nVirtualAccessSize = AccessSize;
AllocatedNode->nUserActualSize = UserActualSize; AllocatedNode->nUserActualSize = UserActualSize;
AllocatedNode->nUserRequestedSize = Size; AllocatedNode->nUserRequestedSize = Size;
@ -1647,7 +1662,7 @@ RtlpPageHeapAllocate(IN PVOID HeapPtr,
/* Write DPH info */ /* Write DPH info */
if (!(DphRoot->ExtraFlags & DPH_EXTRA_CHECK_UNDERRUN)) if (!(DphRoot->ExtraFlags & DPH_EXTRA_CHECK_UNDERRUN))
{ {
RtlpDphWritePageHeapBlockInformation(DphRoot, AllocatedNode->pUserAllocation, Size, UserSize); RtlpDphWritePageHeapBlockInformation(DphRoot, AllocatedNode->pUserAllocation, Size, AccessSize);
} }
/* Finally allocation is done, perform validation again if required */ /* Finally allocation is done, perform validation again if required */
@ -1659,6 +1674,8 @@ RtlpPageHeapAllocate(IN PVOID HeapPtr,
/* Release the lock */ /* Release the lock */
RtlpDphPostProcessing(DphRoot); RtlpDphPostProcessing(DphRoot);
DPRINT("Allocated user block pointer: %p\n", AllocatedNode->pUserAllocation);
/* Return pointer to user allocation */ /* Return pointer to user allocation */
return AllocatedNode->pUserAllocation; return AllocatedNode->pUserAllocation;
} }
@ -1668,6 +1685,7 @@ RtlpPageHeapFree(HANDLE HeapPtr,
ULONG Flags, ULONG Flags,
PVOID Ptr) PVOID Ptr)
{ {
UNIMPLEMENTED;
return FALSE; return FALSE;
} }
@ -1677,6 +1695,7 @@ RtlpPageHeapReAllocate(HANDLE HeapPtr,
PVOID Ptr, PVOID Ptr,
SIZE_T Size) SIZE_T Size)
{ {
UNIMPLEMENTED;
return NULL; return NULL;
} }
@ -1687,6 +1706,7 @@ RtlpPageHeapGetUserInfo(PVOID HeapHandle,
PVOID *UserValue, PVOID *UserValue,
PULONG UserFlags) PULONG UserFlags)
{ {
UNIMPLEMENTED;
return FALSE; return FALSE;
} }
@ -1696,6 +1716,7 @@ RtlpPageHeapSetUserValue(PVOID HeapHandle,
PVOID BaseAddress, PVOID BaseAddress,
PVOID UserValue) PVOID UserValue)
{ {
UNIMPLEMENTED;
return FALSE; return FALSE;
} }
@ -1707,6 +1728,7 @@ RtlpPageHeapSetUserFlags(PVOID HeapHandle,
ULONG UserFlagsReset, ULONG UserFlagsReset,
ULONG UserFlagsSet) ULONG UserFlagsSet)
{ {
UNIMPLEMENTED;
return FALSE; return FALSE;
} }
@ -1715,6 +1737,7 @@ RtlpPageHeapSize(HANDLE HeapPtr,
ULONG Flags, ULONG Flags,
PVOID Ptr) PVOID Ptr)
{ {
UNIMPLEMENTED;
return 0; return 0;
} }