From dd925017539ebba0f69379cd578e618f47b41af7 Mon Sep 17 00:00:00 2001 From: ToyB-Chan Date: Mon, 8 Jun 2026 21:52:22 +0200 Subject: [PATCH] outsourced lifetime of MIHP_Heap, gave heap ptr as identifier to platform functions --- minimal_heap.h | 15 ++++----- minimal_heap_implementation.inl | 57 ++++++++++++++++----------------- minimal_heap_test.c | 26 ++++++++------- 3 files changed, 48 insertions(+), 50 deletions(-) diff --git a/minimal_heap.h b/minimal_heap.h index 40a17f9..f67ea30 100644 --- a/minimal_heap.h +++ b/minimal_heap.h @@ -32,9 +32,9 @@ /* */ /* Hooks to be implemented by the library user */ -void* MIHP_PlatformRequestMemory(size_t minRequestedSize, size_t* outActualSize); // Alignment must at least be alignment of size_t, outActualSize must at least be minRequestedSize -bool MIHP_PlatformFreeMemory(void* ptr, size_t actualSize); -void MIHP_PlatformOnHeapCorruptionDetected(struct _MIHP_HeapCorruptionInfo info); +void* MIHP_PlatformRequestMemory(const struct _MIHP_Heap* heap, size_t minRequestedSize, size_t* outActualSize); // Alignment must at least be alignment of size_t, outActualSize must at least be minRequestedSize +bool MIHP_PlatformFreeMemory(const struct _MIHP_Heap* heap, void* ptr, size_t actualSize); +void MIHP_PlatformOnHeapCorruptionDetected(const struct _MIHP_Heap* heap, struct _MIHP_HeapCorruptionInfo info); /* */ #define MIHP_HEAP_CORRUPTION_TYPE_MEMORY_AREA_CHECKSUM_MISMATCH 0 @@ -94,7 +94,6 @@ typedef struct _MIHP_HeapSegmentHeader typedef struct _MIHP_HeapCorruptionInfo { - const struct _MIHP_Heap* Heap; uint8_t Type; const void* Ptr; uint32_t ExpectedValue; @@ -108,14 +107,14 @@ typedef struct _MIHP_Heap MIHP_HeapMemoryAreaHeader* FirstArea; MIHP_HeapMemoryAreaHeader* LastSuccessfulAllocationArea; - size_t HeapStructureAllocationSize; - MIHP_HEAP_LOCK_TYPE HeapLock; } MIHP_Heap; /* API Interface */ -MIHP_Heap* MIHP_CreateHeap(MIHP_HeapConfig config); -bool MIHP_DestroyHeap(MIHP_Heap* heap, bool force); +bool MIHP_InitializeHeap(MIHP_Heap* heap, MIHP_HeapConfig config); +bool MIHP_IsHeapInitialized(const MIHP_Heap* heap); +bool MIHP_UninitializeHeap(MIHP_Heap* heap, bool force); + void* MIHP_Allocate(MIHP_Heap* heap, size_t size); void* MIHP_Realloc(MIHP_Heap* heap, void* ptr, size_t newSize); bool MIHP_Free(MIHP_Heap* heap, void* ptr); diff --git a/minimal_heap_implementation.inl b/minimal_heap_implementation.inl index 9d25b12..ac92e16 100644 --- a/minimal_heap_implementation.inl +++ b/minimal_heap_implementation.inl @@ -5,49 +5,49 @@ #define MIHP_IS_PO2(Val) (Val != 0 && (Val & (Val - 1)) == 0) -MIHP_Heap* MIHP_CreateHeap(MIHP_HeapConfig config) +bool MIHP_InitializeHeap(MIHP_Heap* heap, MIHP_HeapConfig config) { + if (MIHP_IsHeapInitialized(heap)) + return false; + if (config.AllocationAlignment < sizeof(size_t)) - return NULL; + return false; if (!MIHP_IS_PO2(config.AllocationAlignment)) - return NULL; + return false; if (config.MinimalMemoryAreaSize % config.AllocationAlignment != 0) - return NULL; + return false; if (config.MaximalMemoryAreaSize % config.AllocationAlignment != 0) - return NULL; + return false; - size_t actualHeapStructAllocSize = 0; - MIHP_Heap* heap = (MIHP_Heap*)MIHP_PlatformRequestMemory(sizeof(MIHP_Heap), &actualHeapStructAllocSize); - if (heap == NULL) - return NULL; - - MIHP_ASSERT(actualHeapStructAllocSize >= sizeof(MIHP_Heap)); MIHP_MEMSET(heap, sizeof(MIHP_Heap), 0); heap->Config = config; - heap->HeapStructureAllocationSize = actualHeapStructAllocSize; - heap->FirstArea = MIHP_CreateHeapMemoryArea(heap, actualHeapStructAllocSize); + heap->FirstArea = MIHP_CreateHeapMemoryArea(heap, config.MinimalMemoryAreaSize); heap->LastSuccessfulAllocationArea = heap->FirstArea; - if (heap->FirstArea == NULL) - { - MIHP_PlatformFreeMemory(heap, heap->HeapStructureAllocationSize); - return NULL; - } - heap->FirstArea->Checksum = MIHP_GenerateHeapMemoryAreaChecksum(heap->FirstArea); - return heap; } -bool MIHP_DestroyHeap(MIHP_Heap* heap, bool force) +bool MIHP_IsHeapInitialized(const MIHP_Heap* heap) { if (heap == NULL) return false; + return heap->FirstArea != NULL; +} + +bool MIHP_UninitializeHeap(MIHP_Heap* heap, bool force) +{ + if (!MIHP_IsHeapInitialized(heap)) + return false; + + if (heap == NULL) + return false; + if (!force && heap->Stats.NumTotalOccupiedSegments > 0) return false; @@ -61,7 +61,7 @@ bool MIHP_DestroyHeap(MIHP_Heap* heap, bool force) MIHP_DestroyHeapMemoryArea(heap, currentArea); } - MIHP_PlatformFreeMemory(heap, heap->HeapStructureAllocationSize); + MIHP_MEMSET(heap, sizeof(MIHP_Heap), 0); return true; } @@ -260,11 +260,10 @@ bool MIHP_Free(MIHP_Heap* heap, void* ptr) if (segment->OccupiedSize == 0) { MIHP_HeapCorruptionInfo corruptionInfo = {0}; - corruptionInfo.Heap = heap; corruptionInfo.Type = MIHP_HEAP_CORRUPTION_TYPE_DOUBLE_FREE; corruptionInfo.Ptr = ptr; - MIHP_PlatformOnHeapCorruptionDetected(corruptionInfo); + MIHP_PlatformOnHeapCorruptionDetected(heap, corruptionInfo); return false; } @@ -393,7 +392,7 @@ MIHP_HeapMemoryAreaHeader* MIHP_CreateHeapMemoryArea(MIHP_Heap* heap, size_t req effectiveSize = MIHP_MIN(effectiveSize, heap->Config.MaximalMemoryAreaSize); size_t actualSize = 0; - MIHP_HeapMemoryAreaHeader* area = (MIHP_HeapMemoryAreaHeader*)MIHP_PlatformRequestMemory(effectiveSize, &actualSize); + MIHP_HeapMemoryAreaHeader* area = (MIHP_HeapMemoryAreaHeader*)MIHP_PlatformRequestMemory(heap, effectiveSize, &actualSize); if (area == NULL) return NULL; @@ -423,7 +422,7 @@ bool MIHP_DestroyHeapMemoryArea(MIHP_Heap* heap, MIHP_HeapMemoryAreaHeader* memo size_t areaNumOccupiedSegments = memoryArea->NumOccupiedSegments; size_t areaSize = memoryArea->AreaSize; - if (!MIHP_PlatformFreeMemory(memoryArea, memoryArea->AreaSize)) + if (!MIHP_PlatformFreeMemory(heap, memoryArea, memoryArea->AreaSize)) return false; heap->Stats.NumTotalSegments -= areaNumSegments; @@ -608,13 +607,12 @@ void MIHP_ValidateHeapMemoryAreaHeader(const MIHP_Heap* heap, const MIHP_HeapMem if (area->Checksum != newChecksum) { MIHP_HeapCorruptionInfo corruptionInfo; - corruptionInfo.Heap = heap; corruptionInfo.Type = MIHP_HEAP_CORRUPTION_TYPE_MEMORY_AREA_CHECKSUM_MISMATCH; corruptionInfo.Ptr = area; corruptionInfo.ExpectedValue = area->Checksum; corruptionInfo.ActualValue = newChecksum; - MIHP_PlatformOnHeapCorruptionDetected(corruptionInfo); + MIHP_PlatformOnHeapCorruptionDetected(heap, corruptionInfo); } } @@ -635,13 +633,12 @@ void MIHP_ValidateHeapSegmentHeader(const MIHP_Heap* heap, const MIHP_HeapSegmen if (segment->Checksum != newChecksum) { MIHP_HeapCorruptionInfo corruptionInfo; - corruptionInfo.Heap = heap; corruptionInfo.Type = MIHP_HEAP_CORRUPTION_TYPE_SEGMENT_CHECKSUM_MISMATCH; corruptionInfo.Ptr = segment; corruptionInfo.ExpectedValue = segment->Checksum; corruptionInfo.ActualValue = newChecksum; - MIHP_PlatformOnHeapCorruptionDetected(corruptionInfo); + MIHP_PlatformOnHeapCorruptionDetected(heap, corruptionInfo); } } diff --git a/minimal_heap_test.c b/minimal_heap_test.c index d8405cb..1f6f4af 100644 --- a/minimal_heap_test.c +++ b/minimal_heap_test.c @@ -9,19 +9,19 @@ #define MIHP_ValidateHeap(x) -void* MIHP_PlatformRequestMemory(size_t minRequestedSize, size_t* outActualSize) +void* MIHP_PlatformRequestMemory(const MIHP_Heap* heap, size_t minRequestedSize, size_t* outActualSize) { *outActualSize = minRequestedSize; return malloc(minRequestedSize); } -bool MIHP_PlatformFreeMemory(void* ptr, size_t actualSize) +bool MIHP_PlatformFreeMemory(const MIHP_Heap* heap, void* ptr, size_t actualSize) { free(ptr); return true; } -void MIHP_PlatformOnHeapCorruptionDetected(MIHP_HeapCorruptionInfo info) +void MIHP_PlatformOnHeapCorruptionDetected(const MIHP_Heap* heap, MIHP_HeapCorruptionInfo info) { __debugbreak(); } @@ -37,7 +37,9 @@ int main() config.AllocationAlignment = 16; config.MinimalMemoryAreaSize = 4096 * 32; config.MaximalMemoryAreaSize = 4096ull * 4096ull * 4096ull; - MIHP_Heap* myHeap = MIHP_CreateHeap(config); + + MIHP_Heap myHeap = { 0 }; + MIHP_InitializeHeap(&myHeap, config); for (int i = 0; i < NUM_ALLOCATIONS; i++) { @@ -45,8 +47,8 @@ int main() #if USE_MALLOC myptrs[i] = malloc(size); #else - myptrs[i] = MIHP_Allocate(myHeap, size); - MIHP_ValidateHeap(myHeap); + myptrs[i] = MIHP_Allocate(&myHeap, size); + MIHP_ValidateHeap(&myHeap); #endif } @@ -59,8 +61,8 @@ int main() #if USE_MALLOC free(myptrs[i]); #else - MIHP_Free(myHeap, myptrs[i]); - MIHP_ValidateHeap(myHeap); + MIHP_Free(&myHeap, myptrs[i]); + MIHP_ValidateHeap(&myHeap); #endif myptrs[i] = NULL; @@ -79,8 +81,8 @@ int main() #if USE_MALLOC myptrs[i] = realloc(myptrs[i], size); #else - myptrs[i] = MIHP_Realloc(myHeap, myptrs[i], size); - MIHP_ValidateHeap(myHeap); + myptrs[i] = MIHP_Realloc(&myHeap, myptrs[i], size); + MIHP_ValidateHeap(&myHeap); #endif @@ -96,8 +98,8 @@ int main() #if USE_MALLOC free(myptrs[i]); #else - MIHP_Free(myHeap, myptrs[i]); - MIHP_ValidateHeap(myHeap); + MIHP_Free(&myHeap, myptrs[i]); + MIHP_ValidateHeap(&myHeap); #endif myptrs[i] = NULL;