Author: fireball
Date: Sat Nov 19 11:02:24 2011
New Revision: 54434
URL:
http://svn.reactos.org/svn/reactos?rev=54434&view=rev
Log:
[RTL/HEAP]
- Bring more awesomeness to the heap manager by zefklop's request:
* Add support for settable user values and flags in RtlAllocateHeap and
RtlReAllocateHeap.
* Return error if RtlSetUserValueHeap was unable to set the value.
* Fixes remaining 2 failures of the kernel32_winetest alloc test.
Modified:
trunk/reactos/lib/rtl/heap.c
trunk/reactos/lib/rtl/heap.h
Modified: trunk/reactos/lib/rtl/heap.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/heap.c?rev=54434&a…
==============================================================================
--- trunk/reactos/lib/rtl/heap.c [iso-8859-1] (original)
+++ trunk/reactos/lib/rtl/heap.c [iso-8859-1] Sat Nov 19 11:02:24 2011
@@ -1722,15 +1722,31 @@
PHEAP_ENTRY NTAPI
RtlpSplitEntry(PHEAP Heap,
+ ULONG Flags,
PHEAP_FREE_ENTRY FreeBlock,
SIZE_T AllocationSize,
SIZE_T Index,
SIZE_T Size)
{
PHEAP_FREE_ENTRY SplitBlock, SplitBlock2;
- UCHAR FreeFlags;
+ UCHAR FreeFlags, EntryFlags = HEAP_ENTRY_BUSY;
PHEAP_ENTRY InUseEntry;
SIZE_T FreeSize;
+
+ /* Add extra flags in case of settable user value feature is requested,
+ or there is a tag (small or normal) or there is a request to
+ capture stack backtraces */
+ if ((Flags & HEAP_EXTRA_FLAGS_MASK) ||
+ Heap->PseudoTagEntries)
+ {
+ /* Add flag which means that the entry will have extra stuff attached */
+ EntryFlags |= HEAP_ENTRY_EXTRA_PRESENT;
+
+ /* NB! AllocationSize is already adjusted by RtlAllocateHeap */
+ }
+
+ /* Add settable user flags, if any */
+ EntryFlags |= (Flags & HEAP_SETTABLE_USER_FLAGS) >> 4;
/* Save flags, update total free size */
FreeFlags = FreeBlock->Flags;
@@ -1738,7 +1754,7 @@
/* Make this block an in-use one */
InUseEntry = (PHEAP_ENTRY)FreeBlock;
- InUseEntry->Flags = HEAP_ENTRY_BUSY;
+ InUseEntry->Flags = EntryFlags;
InUseEntry->SmallTagIndex = 0;
/* Calculate the extra amount */
@@ -1877,7 +1893,7 @@
RemoveEntryList(&FreeBlock->FreeList);
/* Split it */
- InUseEntry = RtlpSplitEntry(Heap, FreeBlock, AllocationSize, Index,
Size);
+ InUseEntry = RtlpSplitEntry(Heap, Flags, FreeBlock, AllocationSize,
Index, Size);
/* Release the lock */
if (HeapLocked) RtlLeaveHeapLock(Heap->LockVariable);
@@ -1926,7 +1942,7 @@
RemoveEntryList(&FreeBlock->FreeList);
/* Split it */
- InUseEntry = RtlpSplitEntry(Heap, FreeBlock, AllocationSize, Index, Size);
+ InUseEntry = RtlpSplitEntry(Heap, Flags, FreeBlock, AllocationSize, Index,
Size);
/* Release the lock */
if (HeapLocked) RtlLeaveHeapLock(Heap->LockVariable);
@@ -2003,7 +2019,7 @@
PLIST_ENTRY FreeListHead;
PHEAP_ENTRY InUseEntry;
PHEAP_FREE_ENTRY FreeBlock;
- UCHAR FreeFlags;
+ UCHAR FreeFlags, EntryFlags = HEAP_ENTRY_BUSY;
EXCEPTION_RECORD ExceptionRecord;
BOOLEAN HeapLocked = FALSE;
PHEAP_VIRTUAL_ALLOC_ENTRY VirtualBlock = NULL;
@@ -2039,6 +2055,23 @@
else
AllocationSize = 1;
AllocationSize = (AllocationSize + Heap->AlignRound) & Heap->AlignMask;
+
+ /* Add extra flags in case of settable user value feature is requested,
+ or there is a tag (small or normal) or there is a request to
+ capture stack backtraces */
+ if ((Flags & HEAP_EXTRA_FLAGS_MASK) ||
+ Heap->PseudoTagEntries)
+ {
+ /* Add flag which means that the entry will have extra stuff attached */
+ EntryFlags |= HEAP_ENTRY_EXTRA_PRESENT;
+
+ /* Account for extra stuff size */
+ AllocationSize += sizeof(HEAP_ENTRY_EXTRA);
+ }
+
+ /* Add settable user flags, if any */
+ EntryFlags |= (Flags & HEAP_SETTABLE_USER_FLAGS) >> 4;
+
Index = AllocationSize >> HEAP_ENTRY_SHIFT;
/* Acquire the lock if necessary */
@@ -2070,7 +2103,7 @@
/* Initialize this block */
InUseEntry = (PHEAP_ENTRY)FreeBlock;
- InUseEntry->Flags = HEAP_ENTRY_BUSY | (FreeFlags &
HEAP_ENTRY_LAST_ENTRY);
+ InUseEntry->Flags = EntryFlags | (FreeFlags & HEAP_ENTRY_LAST_ENTRY);
InUseEntry->UnusedBytes = (UCHAR)(AllocationSize - Size);
InUseEntry->SmallTagIndex = 0;
}
@@ -2113,7 +2146,7 @@
RtlpRemoveFreeBlock(Heap, FreeBlock, TRUE, FALSE);
/* Split it */
- InUseEntry = RtlpSplitEntry(Heap, FreeBlock, AllocationSize, Index, Size);
+ InUseEntry = RtlpSplitEntry(Heap, Flags, FreeBlock, AllocationSize, Index,
Size);
}
/* Release the lock */
@@ -2175,7 +2208,7 @@
/* Initialize the newly allocated block */
VirtualBlock->BusyBlock.Size = (USHORT)(AllocationSize - Size);
- VirtualBlock->BusyBlock.Flags = HEAP_ENTRY_VIRTUAL_ALLOC |
HEAP_ENTRY_EXTRA_PRESENT | HEAP_ENTRY_BUSY;
+ VirtualBlock->BusyBlock.Flags = EntryFlags | HEAP_ENTRY_VIRTUAL_ALLOC |
HEAP_ENTRY_EXTRA_PRESENT;
VirtualBlock->CommitSize = AllocationSize;
VirtualBlock->ReserveSize = AllocationSize;
@@ -2536,41 +2569,41 @@
}
}
+ /* Properly "zero out" (and fill!) the space */
+ if (Flags & HEAP_ZERO_MEMORY)
+ {
+ RtlZeroMemory((PCHAR)(InUseEntry + 1) + PrevSize, Size - PrevSize);
+ }
+ else if (Heap->Flags & HEAP_FREE_CHECKING_ENABLED)
+ {
+ /* Calculate tail part which we need to fill */
+ TailPart = PrevSize & (sizeof(ULONG) - 1);
+
+ /* "Invert" it as usual */
+ if (TailPart) TailPart = 4 - TailPart;
+
+ if (Size > (PrevSize + TailPart))
+ AddedSize = (Size - (PrevSize + TailPart)) & ~(sizeof(ULONG) - 1);
+
+ if (AddedSize)
+ {
+ RtlFillMemoryUlong((PCHAR)(InUseEntry + 1) + PrevSize + TailPart,
+ AddedSize,
+ ARENA_INUSE_FILLER);
+ }
+ }
+
+ /* Fill the new tail */
+ if (Heap->Flags & HEAP_TAIL_CHECKING_ENABLED)
+ {
+ RtlFillMemory((PCHAR)(InUseEntry + 1) + Size,
+ HEAP_ENTRY_SIZE,
+ HEAP_TAIL_FILL);
+ }
+
/* Copy user settable flags */
InUseEntry->Flags &= ~HEAP_ENTRY_SETTABLE_FLAGS;
InUseEntry->Flags |= ((Flags & HEAP_SETTABLE_USER_FLAGS) >> 4);
-
- /* Properly "zero out" (and fill!) the space */
- if (Flags & HEAP_ZERO_MEMORY)
- {
- RtlZeroMemory((PCHAR)(InUseEntry + 1) + PrevSize, Size - PrevSize);
- }
- else if (Heap->Flags & HEAP_FREE_CHECKING_ENABLED)
- {
- /* Calculate tail part which we need to fill */
- TailPart = PrevSize & (sizeof(ULONG) - 1);
-
- /* "Invert" it as usual */
- if (TailPart) TailPart = 4 - TailPart;
-
- if (Size > (PrevSize + TailPart))
- AddedSize = (Size - (PrevSize + TailPart)) & ~(sizeof(ULONG) - 1);
-
- if (AddedSize)
- {
- RtlFillMemoryUlong((PCHAR)(InUseEntry + 1) + PrevSize + TailPart,
- AddedSize,
- ARENA_INUSE_FILLER);
- }
- }
-
- /* Fill the new tail */
- if (Heap->Flags & HEAP_TAIL_CHECKING_ENABLED)
- {
- RtlFillMemory((PCHAR)(InUseEntry + 1) + Size,
- HEAP_ENTRY_SIZE,
- HEAP_TAIL_FILL);
- }
/* Return success */
return TRUE;
@@ -3728,7 +3761,7 @@
PHEAP Heap = (PHEAP)HeapHandle;
PHEAP_ENTRY HeapEntry;
PHEAP_ENTRY_EXTRA Extra;
- BOOLEAN HeapLocked = FALSE;
+ BOOLEAN HeapLocked = FALSE, ValueSet = FALSE;
/* Force flags */
Flags |= Heap->Flags;
@@ -3765,13 +3798,16 @@
/* Use extra to store the value */
Extra = RtlpGetExtraStuffPointer(HeapEntry);
Extra->Settable = (ULONG_PTR)UserValue;
+
+ /* Indicate that value was set */
+ ValueSet = TRUE;
}
/* Release the heap lock if it was acquired */
if (HeapLocked)
RtlLeaveHeapLock(Heap->LockVariable);
- return TRUE;
+ return ValueSet;
}
/*
Modified: trunk/reactos/lib/rtl/heap.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/heap.h?rev=54434&a…
==============================================================================
--- trunk/reactos/lib/rtl/heap.h [iso-8859-1] (original)
+++ trunk/reactos/lib/rtl/heap.h [iso-8859-1] Sat Nov 19 11:02:24 2011
@@ -31,10 +31,11 @@
#define HEAP_GLOBAL_TAG 0x0800
#define HEAP_PSEUDO_TAG_FLAG 0x8000
#define HEAP_TAG_MASK (HEAP_MAXIMUM_TAG << HEAP_TAG_SHIFT)
+#define HEAP_TAGS_MASK (HEAP_TAG_MASK ^ (0xFF << HEAP_TAG_SHIFT))
#define HEAP_EXTRA_FLAGS_MASK (HEAP_CAPTURE_STACK_BACKTRACES | \
HEAP_SETTABLE_USER_VALUE | \
- (HEAP_TAG_MASK ^ (0xFF << HEAP_TAG_SHIFT)))
+ HEAP_TAGS_MASK)
/* Heap entry flags */
#define HEAP_ENTRY_BUSY 0x01