[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