mirror of
https://github.com/ToyB-Chan/minimal-heap.git
synced 2026-07-13 21:51:16 +02:00
free
This commit is contained in:
@@ -77,13 +77,13 @@ void* MIHP_Allocate(MIHP_HeapInfo* heap, size_t size)
|
|||||||
if (currentSegment->OccupiedSize != 0)
|
if (currentSegment->OccupiedSize != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
size_t headerSize = MIHP_GetHeapAlignedSize(heap, sizeof(MIHP_HeapSegmentHeader));
|
size_t segmentHeaderSize = MIHP_GetHeapAlignedSize(heap, sizeof(MIHP_HeapSegmentHeader));
|
||||||
size_t minimalPayloadSize = heap->Config.AllocationAlignment;
|
size_t minimalPayloadSize = heap->Config.AllocationAlignment;
|
||||||
MIHP_HeapSegmentHeader* targetSegment = NULL;
|
MIHP_HeapSegmentHeader* targetSegment = NULL;
|
||||||
|
|
||||||
if (currentSegment->SegmentSize >= 2 * headerSize + size + minimalPayloadSize)
|
if (currentSegment->SegmentSize >= 2 * segmentHeaderSize + size + minimalPayloadSize)
|
||||||
MIHP_SplitHeapSegment(currentSegment, headerSize + size, &targetSegment);
|
MIHP_SplitHeapSegment(currentSegment, segmentHeaderSize + size, &targetSegment);
|
||||||
else if (currentSegment->SegmentSize >= headerSize + size)
|
else if (currentSegment->SegmentSize >= segmentHeaderSize + size)
|
||||||
targetSegment = currentSegment;
|
targetSegment = currentSegment;
|
||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
@@ -91,9 +91,12 @@ void* MIHP_Allocate(MIHP_HeapInfo* heap, size_t size)
|
|||||||
targetSegment->OccupiedSize = size;
|
targetSegment->OccupiedSize = size;
|
||||||
targetSegment->Checksum = MIHP_GenerateHeapSegmentChecksum(targetSegment);
|
targetSegment->Checksum = MIHP_GenerateHeapSegmentChecksum(targetSegment);
|
||||||
|
|
||||||
|
currentArea->NumOccupiedSegments++;
|
||||||
|
heap->Stats.NumTotalOccupiedSegments++;
|
||||||
|
|
||||||
MIHP_UNLOCK_HEAP(&heap->HeapLock);
|
MIHP_UNLOCK_HEAP(&heap->HeapLock);
|
||||||
|
|
||||||
void* data = (char*)targetSegment + headerSize;
|
void* data = (char*)targetSegment + segmentHeaderSize;
|
||||||
|
|
||||||
#if MIHP_ZERO_OUT_ALLOCATIONS
|
#if MIHP_ZERO_OUT_ALLOCATIONS
|
||||||
for (size_t i = 0; i < size; ++i)
|
for (size_t i = 0; i < size; ++i)
|
||||||
@@ -110,6 +113,9 @@ void* MIHP_Allocate(MIHP_HeapInfo* heap, size_t size)
|
|||||||
newAreaSize = MIHP_MIN(heap->Config.MaximalMemoryAreaSize, newAreaSize * 2);
|
newAreaSize = MIHP_MIN(heap->Config.MaximalMemoryAreaSize, newAreaSize * 2);
|
||||||
|
|
||||||
MIHP_HeapMemoryAreaHeader* newArea = MIHP_CreateHeapMemoryArea(heap, newAreaSize);
|
MIHP_HeapMemoryAreaHeader* newArea = MIHP_CreateHeapMemoryArea(heap, newAreaSize);
|
||||||
|
if (newArea == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
newArea->NextArea = heap->FirstArea;
|
newArea->NextArea = heap->FirstArea;
|
||||||
heap->FirstArea->PreviousArea = newArea;
|
heap->FirstArea->PreviousArea = newArea;
|
||||||
heap->FirstArea->Checksum = MIHP_GenerateHeapMemoryAreaChecksum(heap->FirstArea);
|
heap->FirstArea->Checksum = MIHP_GenerateHeapMemoryAreaChecksum(heap->FirstArea);
|
||||||
@@ -126,13 +132,75 @@ void* MIHP_Realloc(MIHP_HeapInfo* heap, void* ptr, size_t newSize)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MIHP_Free(MIHP_HeapInfo* heap, void* ptr)
|
bool MIHP_Free(MIHP_HeapInfo* heap, void* ptr)
|
||||||
{
|
{
|
||||||
if (heap == NULL)
|
if (heap == NULL)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
if (ptr == NULL)
|
if (ptr == NULL)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
|
if (!MIHP_IsPointerInHeap(heap, ptr))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
MIHP_LOCK_HEAP(&heap->HeapLock);
|
||||||
|
|
||||||
|
size_t segmentHeaderSize = MIHP_GetHeapAlignedSize(heap, sizeof(MIHP_HeapSegmentHeader));
|
||||||
|
MIHP_HeapSegmentHeader* segment = (char*)ptr - segmentHeaderSize;
|
||||||
|
MIHP_ValidateHeapSegmentHeader(segment);
|
||||||
|
|
||||||
|
MIHP_HeapMemoryAreaHeader* area = segment->OwningMemoryArea;
|
||||||
|
MIHP_ValidateHeapMemoryAreaHeader(area);
|
||||||
|
|
||||||
|
segment->OccupiedSize = 0;
|
||||||
|
area->NumOccupiedSegments--;
|
||||||
|
heap->Stats.NumTotalOccupiedSegments--;
|
||||||
|
segment->Checksum = MIHP_GenerateHeapSegmentChecksum(segment);
|
||||||
|
|
||||||
|
if (area->NumOccupiedSegments == 0 && heap->Stats.NumMemoryAreas > 1)
|
||||||
|
{
|
||||||
|
MIHP_HeapMemoryAreaHeader* prevArea = area->PreviousArea;
|
||||||
|
MIHP_HeapMemoryAreaHeader* nextArea = area->NextArea;
|
||||||
|
|
||||||
|
if (MIHP_DestroyHeapMemoryArea(heap, area))
|
||||||
|
{
|
||||||
|
if (prevArea)
|
||||||
|
{
|
||||||
|
MIHP_ValidateHeapMemoryAreaHeader(prevArea);
|
||||||
|
prevArea->NextArea = nextArea;
|
||||||
|
prevArea->Checksum = MIHP_GenerateHeapMemoryAreaChecksum(prevArea->NextArea);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
heap->FirstArea = nextArea;
|
||||||
|
|
||||||
|
if (nextArea)
|
||||||
|
{
|
||||||
|
MIHP_ValidateHeapMemoryAreaHeader(nextArea);
|
||||||
|
nextArea->PreviousArea = prevArea;
|
||||||
|
nextArea->Checksum = MIHP_GenerateHeapMemoryAreaChecksum(nextArea);
|
||||||
|
}
|
||||||
|
|
||||||
|
MIHP_UNLOCK_HEAP(&heap->HeapLock);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (segment->NextSegment)
|
||||||
|
{
|
||||||
|
MIHP_ValidateHeapSegmentHeader(segment->NextSegment);
|
||||||
|
if (segment->NextSegment->OccupiedSize == 0)
|
||||||
|
MIHP_MergeHeapSegments(segment, segment->NextSegment);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (segment->PreviousSegment)
|
||||||
|
{
|
||||||
|
MIHP_ValidateHeapSegmentHeader(segment->PreviousSegment);
|
||||||
|
if (segment->PreviousSegment->OccupiedSize == 0)
|
||||||
|
MIHP_MergeHeapSegments(segment->PreviousSegment, segment);
|
||||||
|
}
|
||||||
|
|
||||||
|
MIHP_UNLOCK_HEAP(&heap->HeapLock);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MIHP_IsPointerInHeap(MIHP_HeapInfo* heap, void* ptr)
|
bool MIHP_IsPointerInHeap(MIHP_HeapInfo* heap, void* ptr)
|
||||||
@@ -166,6 +234,21 @@ bool MIHP_IsPointerInHeap(MIHP_HeapInfo* heap, void* ptr)
|
|||||||
|
|
||||||
void MIHP_ValidateHeap(MIHP_HeapInfo* heap)
|
void MIHP_ValidateHeap(MIHP_HeapInfo* heap)
|
||||||
{
|
{
|
||||||
|
MIHP_HeapMemoryAreaHeader* nextArea = heap->FirstArea;
|
||||||
|
while (nextArea)
|
||||||
|
{
|
||||||
|
MIHP_HeapMemoryAreaHeader* currentArea = nextArea;
|
||||||
|
MIHP_ValidateHeapMemoryAreaHeader(currentArea);
|
||||||
|
nextArea = currentArea->NextArea;
|
||||||
|
|
||||||
|
MIHP_HeapSegmentHeader* nextSegment = currentArea->FirstSegment;
|
||||||
|
while (nextSegment)
|
||||||
|
{
|
||||||
|
MIHP_HeapSegmentHeader* currentSegment = nextSegment;
|
||||||
|
MIHP_ValidateHeapSegmentHeader(currentSegment);
|
||||||
|
nextSegment = currentSegment->NextSegment;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MIHP_HeapMemoryAreaHeader* MIHP_CreateHeapMemoryArea(MIHP_HeapInfo* heap, size_t requestedSize)
|
MIHP_HeapMemoryAreaHeader* MIHP_CreateHeapMemoryArea(MIHP_HeapInfo* heap, size_t requestedSize)
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ MIHP_HeapInfo* MIHP_CreateHeap(MIHP_HeapConfig config);
|
|||||||
bool MIHP_DestroyHeap(MIHP_HeapInfo* heap, bool force);
|
bool MIHP_DestroyHeap(MIHP_HeapInfo* heap, bool force);
|
||||||
void* MIHP_Allocate(MIHP_HeapInfo* heap, size_t size);
|
void* MIHP_Allocate(MIHP_HeapInfo* heap, size_t size);
|
||||||
void* MIHP_Realloc(MIHP_HeapInfo* heap, void* ptr, size_t newSize);
|
void* MIHP_Realloc(MIHP_HeapInfo* heap, void* ptr, size_t newSize);
|
||||||
void MIHP_Free(MIHP_HeapInfo* heap, void* ptr);
|
bool MIHP_Free(MIHP_HeapInfo* heap, void* ptr);
|
||||||
|
|
||||||
bool MIHP_IsPointerInHeap(MIHP_HeapInfo* heap, void* ptr);
|
bool MIHP_IsPointerInHeap(MIHP_HeapInfo* heap, void* ptr);
|
||||||
void MIHP_ValidateHeap(MIHP_HeapInfo* heap);
|
void MIHP_ValidateHeap(MIHP_HeapInfo* heap);
|
||||||
|
|||||||
Reference in New Issue
Block a user