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&r1=54433&r2=54434&view=diff
==============================================================================
--- 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&r1=54433&r2=54434&view=diff
==============================================================================
--- 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


Reply via email to