mirror of
https://github.com/ToyB-Chan/minimal-heap.git
synced 2026-07-13 21:51:16 +02:00
insane performance improvement(??)
This commit is contained in:
@@ -84,6 +84,7 @@ typedef struct _MIHP_HeapMemoryAreaHeader
|
|||||||
struct _MIHP_HeapMemoryAreaHeader* PreviousArea;
|
struct _MIHP_HeapMemoryAreaHeader* PreviousArea;
|
||||||
|
|
||||||
struct _MIHP_HeapSegmentHeader* FirstSegment;
|
struct _MIHP_HeapSegmentHeader* FirstSegment;
|
||||||
|
struct _MIHP_HeapSegmentHeader* LastSuccessfulAllocationSegment;
|
||||||
|
|
||||||
const struct _MIHP_Heap* InstigatingHeap; // Heap that created this area. May not always be the owning heap (in case of a merge) or safe to deference!
|
const struct _MIHP_Heap* InstigatingHeap; // Heap that created this area. May not always be the owning heap (in case of a merge) or safe to deference!
|
||||||
|
|
||||||
|
|||||||
@@ -118,25 +118,24 @@ void* MIHP_Allocate(MIHP_Heap* heap, size_t size)
|
|||||||
|
|
||||||
MIHP_LockHeap(heap);
|
MIHP_LockHeap(heap);
|
||||||
|
|
||||||
MIHP_HeapMemoryAreaHeader* nextArea = heap->FirstArea;
|
MIHP_HeapMemoryAreaHeader* nextArea = heap->LastSuccessfulAllocationArea;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
MIHP_HeapMemoryAreaHeader* currentArea = nextArea;
|
MIHP_HeapMemoryAreaHeader* currentArea = nextArea;
|
||||||
|
MIHP_ValidateHeapMemoryAreaHeader(heap, currentArea);
|
||||||
nextArea = currentArea->NextArea;
|
nextArea = currentArea->NextArea;
|
||||||
|
|
||||||
if (nextArea == NULL)
|
if (nextArea == NULL)
|
||||||
nextArea = heap->FirstArea;
|
nextArea = heap->FirstArea;
|
||||||
|
|
||||||
MIHP_ValidateHeapMemoryAreaHeader(heap, currentArea);
|
|
||||||
|
|
||||||
if (currentArea->NumOccupiedSegments == currentArea->NumSegments)
|
if (currentArea->NumOccupiedSegments == currentArea->NumSegments)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
size_t numTraversalsPerArea = MIHP_MAX(100, heap->Config.MinTotalTraversalsBeforeHeapExpansion * currentArea->NumSegments) / heap->Stats.NumTotalSegments;
|
size_t numTraversalsPerArea = MIHP_MAX(100, heap->Config.MinTotalTraversalsBeforeHeapExpansion * currentArea->NumSegments) / heap->Stats.NumTotalSegments;
|
||||||
size_t numTraversedAreaSegments = 0;
|
size_t numTraversedAreaSegments = 0;
|
||||||
|
|
||||||
MIHP_HeapSegmentHeader* nextSegment = currentArea->FirstSegment;
|
MIHP_HeapSegmentHeader* nextSegment = currentArea->LastSuccessfulAllocationSegment;
|
||||||
while (nextSegment)
|
do
|
||||||
{
|
{
|
||||||
if (numTraversedAreaSegments > numTraversalsPerArea)
|
if (numTraversedAreaSegments > numTraversalsPerArea)
|
||||||
if (numTraversedAreaSegments * 100 > currentArea->NumSegments * heap->Config.MinHeapTraversalPercentToExpand)
|
if (numTraversedAreaSegments * 100 > currentArea->NumSegments * heap->Config.MinHeapTraversalPercentToExpand)
|
||||||
@@ -146,7 +145,10 @@ void* MIHP_Allocate(MIHP_Heap* heap, size_t size)
|
|||||||
|
|
||||||
MIHP_HeapSegmentHeader* currentSegment = nextSegment;
|
MIHP_HeapSegmentHeader* currentSegment = nextSegment;
|
||||||
MIHP_ValidateHeapSegmentHeader(heap, currentSegment);
|
MIHP_ValidateHeapSegmentHeader(heap, currentSegment);
|
||||||
nextSegment = nextSegment->NextSegment;
|
nextSegment = currentSegment->NextSegment;
|
||||||
|
|
||||||
|
if (nextSegment == NULL)
|
||||||
|
nextSegment = currentArea->FirstSegment;
|
||||||
|
|
||||||
if (currentSegment->OccupiedSize != 0)
|
if (currentSegment->OccupiedSize != 0)
|
||||||
continue;
|
continue;
|
||||||
@@ -165,6 +167,7 @@ void* MIHP_Allocate(MIHP_Heap* heap, size_t size)
|
|||||||
targetSegment->Checksum = MIHP_GenerateHeapSegmentChecksum(heap, targetSegment);
|
targetSegment->Checksum = MIHP_GenerateHeapSegmentChecksum(heap, targetSegment);
|
||||||
|
|
||||||
currentArea->NumOccupiedSegments++;
|
currentArea->NumOccupiedSegments++;
|
||||||
|
currentArea->LastSuccessfulAllocationSegment = currentSegment;
|
||||||
currentArea->Checksum = MIHP_GenerateHeapMemoryAreaChecksum(heap, currentArea);
|
currentArea->Checksum = MIHP_GenerateHeapMemoryAreaChecksum(heap, currentArea);
|
||||||
|
|
||||||
heap->Stats.NumTotalOccupiedSegments++;
|
heap->Stats.NumTotalOccupiedSegments++;
|
||||||
@@ -176,7 +179,7 @@ void* MIHP_Allocate(MIHP_Heap* heap, size_t size)
|
|||||||
MIHP_MEMSET(data, size, heap->Config.AllocationInitialValue);
|
MIHP_MEMSET(data, size, heap->Config.AllocationInitialValue);
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
} while (nextSegment != currentArea->LastSuccessfulAllocationSegment);
|
||||||
} while (nextArea != heap->LastSuccessfulAllocationArea);
|
} while (nextArea != heap->LastSuccessfulAllocationArea);
|
||||||
|
|
||||||
/* No free segment found (in time), allocate new area */
|
/* No free segment found (in time), allocate new area */
|
||||||
@@ -241,11 +244,15 @@ void* MIHP_Reallocate(MIHP_Heap* heap, void* ptr, size_t newSize)
|
|||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (segment->NextSegment && MIHP_MergeHeapSegments(heap, segment, segment->NextSegment))
|
if (segment->NextSegment)
|
||||||
|
{
|
||||||
|
MIHP_ValidateHeapSegmentHeader(heap, segment->NextSegment);
|
||||||
|
if (MIHP_MergeHeapSegments(heap, segment, segment->NextSegment))
|
||||||
{
|
{
|
||||||
MIHP_UnlockHeap(heap);
|
MIHP_UnlockHeap(heap);
|
||||||
return MIHP_Reallocate(heap, ptr, newSize);
|
return MIHP_Reallocate(heap, ptr, newSize);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MIHP_UnlockHeap(heap);
|
MIHP_UnlockHeap(heap);
|
||||||
|
|
||||||
@@ -445,7 +452,7 @@ bool MIHP_IsPointerInHeap(MIHP_Heap* heap, void* ptr)
|
|||||||
while (nextArea)
|
while (nextArea)
|
||||||
{
|
{
|
||||||
MIHP_HeapMemoryAreaHeader* currentArea = nextArea;
|
MIHP_HeapMemoryAreaHeader* currentArea = nextArea;
|
||||||
MIHP_ValidateHeapSegmentHeader(heap, currentArea);
|
MIHP_ValidateHeapMemoryAreaHeader(heap, currentArea);
|
||||||
nextArea = currentArea->NextArea;
|
nextArea = currentArea->NextArea;
|
||||||
|
|
||||||
size_t ptrMin = (size_t)currentArea;
|
size_t ptrMin = (size_t)currentArea;
|
||||||
@@ -529,6 +536,7 @@ MIHP_HeapMemoryAreaHeader* MIHP_CreateHeapMemoryArea(MIHP_Heap* heap, size_t req
|
|||||||
|
|
||||||
size_t headerSize = MIHP_GetHeapAlignedSize(heap, sizeof(MIHP_HeapMemoryAreaHeader));
|
size_t headerSize = MIHP_GetHeapAlignedSize(heap, sizeof(MIHP_HeapMemoryAreaHeader));
|
||||||
area->FirstSegment = MIHP_InitializeHeapSegment(heap, area, (char*)area + headerSize, area->AreaSize - headerSize);
|
area->FirstSegment = MIHP_InitializeHeapSegment(heap, area, (char*)area + headerSize, area->AreaSize - headerSize);
|
||||||
|
area->LastSuccessfulAllocationSegment = area->FirstSegment;
|
||||||
area->FirstSegment->Checksum = MIHP_GenerateHeapSegmentChecksum(heap, area->FirstSegment);
|
area->FirstSegment->Checksum = MIHP_GenerateHeapSegmentChecksum(heap, area->FirstSegment);
|
||||||
|
|
||||||
heap->Stats.NumMemoryAreas++;
|
heap->Stats.NumMemoryAreas++;
|
||||||
@@ -649,6 +657,13 @@ bool MIHP_MergeHeapSegments(MIHP_Heap* heap, MIHP_HeapSegmentHeader* sourceSegme
|
|||||||
sourceSegment->NextSegment->Checksum = MIHP_GenerateHeapSegmentChecksum(heap, sourceSegment->NextSegment);
|
sourceSegment->NextSegment->Checksum = MIHP_GenerateHeapSegmentChecksum(heap, sourceSegment->NextSegment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MIHP_ValidateHeapMemoryAreaHeader(heap, sourceSegment->OwningMemoryArea);
|
||||||
|
if (sourceSegment->OwningMemoryArea->LastSuccessfulAllocationSegment == segmentToAbsorb)
|
||||||
|
{
|
||||||
|
sourceSegment->OwningMemoryArea->LastSuccessfulAllocationSegment = sourceSegment;
|
||||||
|
sourceSegment->OwningMemoryArea->Checksum = MIHP_GenerateHeapMemoryAreaChecksum(heap, sourceSegment->OwningMemoryArea);
|
||||||
|
}
|
||||||
|
|
||||||
sourceSegment->SegmentSize += segmentToAbsorb->SegmentSize;
|
sourceSegment->SegmentSize += segmentToAbsorb->SegmentSize;
|
||||||
MIHP_UninitializeHeapSegment(heap, segmentToAbsorb);
|
MIHP_UninitializeHeapSegment(heap, segmentToAbsorb);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user