[ros-diffs] [jgardou] 52340: [RTL] - do not use RtlpCoalesceFreeBlocks to reinsert a block resulting from a split. This bad idea was mine, introduced in r51757

jgardou at svn.reactos.org jgardou at svn.reactos.org
Sat Jun 18 14:47:51 UTC 2011


Author: jgardou
Date: Sat Jun 18 14:47:51 2011
New Revision: 52340

URL: http://svn.reactos.org/svn/reactos?rev=52340&view=rev
Log:
[RTL]
  - do not use RtlpCoalesceFreeBlocks to reinsert a block resulting from a split.
This bad idea was mine, introduced in r51757

Modified:
    trunk/reactos/lib/rtl/heap.c

Modified: trunk/reactos/lib/rtl/heap.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/rtl/heap.c?rev=52340&r1=52339&r2=52340&view=diff
==============================================================================
--- trunk/reactos/lib/rtl/heap.c [iso-8859-1] (original)
+++ trunk/reactos/lib/rtl/heap.c [iso-8859-1] Sat Jun 18 14:47:51 2011
@@ -1749,7 +1749,7 @@
                SIZE_T Index,
                SIZE_T Size)
 {
-    PHEAP_FREE_ENTRY SplitBlock;
+    PHEAP_FREE_ENTRY SplitBlock, SplitBlock2;
     UCHAR FreeFlags;
     PHEAP_ENTRY InUseEntry;
     SIZE_T FreeSize;
@@ -1791,12 +1791,63 @@
             SplitBlock->SegmentOffset = InUseEntry->SegmentOffset;
             SplitBlock->Size = FreeSize;
             SplitBlock->PreviousSize = Index;
-            
-            /* Coalesce it with the next entry */
-            SplitBlock = RtlpCoalesceFreeBlocks(Heap, SplitBlock, &FreeSize, FALSE);
-            RtlpInsertFreeBlock(Heap, SplitBlock, FreeSize);
-            
-            /* Reset the flag */
+
+            /* Check if it's the last entry */
+            if (FreeFlags & HEAP_ENTRY_LAST_ENTRY)
+            {
+                /* Insert it to the free list if it's the last entry */
+                RtlpInsertFreeBlockHelper(Heap, SplitBlock, FreeSize, FALSE);
+                Heap->TotalFreeSize += FreeSize;
+            }
+            else
+            {
+                /* Not so easy - need to update next's previous size too */
+                SplitBlock2 = (PHEAP_FREE_ENTRY)((PHEAP_ENTRY)SplitBlock + FreeSize);
+
+                if (SplitBlock2->Flags & HEAP_ENTRY_BUSY)
+                {
+                    SplitBlock2->PreviousSize = (USHORT)FreeSize;
+                    RtlpInsertFreeBlockHelper(Heap, SplitBlock, FreeSize, FALSE);
+                    Heap->TotalFreeSize += FreeSize;
+                }
+                else
+                {
+                    /* Even more complex - the next entry is free, so we can merge them into one! */
+                    SplitBlock->Flags = SplitBlock2->Flags;
+
+                    /* Remove that next entry */
+                    RtlpRemoveFreeBlock(Heap, SplitBlock2, FALSE, FALSE);
+
+                    /* Update sizes */
+                    FreeSize += SplitBlock2->Size;
+                    Heap->TotalFreeSize -= SplitBlock2->Size;
+
+                    if (FreeSize <= HEAP_MAX_BLOCK_SIZE)
+                    {
+                        /* Insert it back */
+                        SplitBlock->Size = FreeSize;
+
+                        /* Don't forget to update previous size of the next entry! */
+                        if (!(SplitBlock->Flags & HEAP_ENTRY_LAST_ENTRY))
+                        {
+                            ((PHEAP_FREE_ENTRY)((PHEAP_ENTRY)SplitBlock + FreeSize))->PreviousSize = FreeSize;
+                        }
+
+                        /* Actually insert it */
+                        RtlpInsertFreeBlockHelper(Heap, SplitBlock, (USHORT)FreeSize, FALSE);
+
+                        /* Update total size */
+                        Heap->TotalFreeSize += FreeSize;
+                    }
+                    else
+                    {
+                        /* Resulting block is quite big */
+                        RtlpInsertFreeBlock(Heap, SplitBlock, FreeSize);
+                    }
+                }
+            }
+
+            /* Reset flags of the free entry */
             FreeFlags = 0;
         }
     }
@@ -2645,7 +2696,7 @@
     {
         RtlEnterHeapLock(Heap->LockVariable);
         HeapLocked = TRUE;
-        Flags ^= HEAP_NO_SERIALIZE;
+        Flags &= ~HEAP_NO_SERIALIZE;
     }
 
     /* Get the pointer to the in-use entry */




More information about the Ros-diffs mailing list