mirror of
https://github.com/ToyB-Chan/minimal-heap.git
synced 2026-07-13 21:51:16 +02:00
changed all things to function ptr
This commit is contained in:
@@ -16,7 +16,6 @@
|
|||||||
#define MIHP_HEAP_STRUCTURE_VALIDATION_TYPE_CHECKSUM 2
|
#define MIHP_HEAP_STRUCTURE_VALIDATION_TYPE_CHECKSUM 2
|
||||||
|
|
||||||
/* Defines to be configured by the library user */
|
/* Defines to be configured by the library user */
|
||||||
|
|
||||||
#ifndef MIHP_HEAP_STRUCTURE_VALIDATION_TYPE
|
#ifndef MIHP_HEAP_STRUCTURE_VALIDATION_TYPE
|
||||||
#define MIHP_HEAP_STRUCTURE_VALIDATION_TYPE MIHP_HEAP_STRUCTURE_VALIDATION_TYPE_CHECKSUM
|
#define MIHP_HEAP_STRUCTURE_VALIDATION_TYPE MIHP_HEAP_STRUCTURE_VALIDATION_TYPE_CHECKSUM
|
||||||
#endif
|
#endif
|
||||||
@@ -33,31 +32,38 @@
|
|||||||
#define MIHP_ASSERT(Condition) while(1) { if (Condition) break; *(volatile char*)(0x0) = 0; }
|
#define MIHP_ASSERT(Condition) while(1) { if (Condition) break; *(volatile char*)(0x0) = 0; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MIHP_HEAP_LOCK_TYPE
|
#ifndef MIHP_MEMSET
|
||||||
#define MIHP_HEAP_LOCK_TYPE bool // Does NOT have to be reentred safe
|
#define MIHP_MEMSET(Ptr, Size, Val) for(size_t i = 0; i < Size; ++i) *((char*)Ptr + i) = Val;
|
||||||
#define MIHP_LOCK_HEAP(LockVarPtr) {}
|
|
||||||
#define MIHP_UNLOCK_HEAP(LockVarPtr) {}
|
|
||||||
#endif
|
#endif
|
||||||
/* */
|
/* */
|
||||||
|
|
||||||
/* Hooks to be implemented by the library user */
|
typedef void*(MIHP_PlatformReqeustMemoryFn)(const struct _MIHP_Heap* heap, size_t minRequestedSize, size_t* outActualSize);
|
||||||
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
|
typedef bool (MIHP_PlatformFreeMemoryFn)(const struct _MIHP_Heap* heap, void* ptr, size_t actualSize);
|
||||||
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
|
#define MIHP_HEAP_CORRUPTION_TYPE_MEMORY_AREA_CHECKSUM_MISMATCH 0
|
||||||
#define MIHP_HEAP_CORRUPTION_TYPE_SEGMENT_CHECKSUM_MISMATCH 1
|
#define MIHP_HEAP_CORRUPTION_TYPE_SEGMENT_CHECKSUM_MISMATCH 1
|
||||||
#define MIHP_HEAP_CORRUPTION_TYPE_DOUBLE_FREE 2
|
#define MIHP_HEAP_CORRUPTION_TYPE_DOUBLE_FREE 2
|
||||||
|
|
||||||
|
typedef void (MIHP_OnHeapCorruptionDetectedFn)(const struct _MIHP_Heap* heap, struct _MIHP_HeapCorruptionInfo);
|
||||||
|
|
||||||
|
typedef void(MIHIP_LockHeapFn)(const struct _MIHP_Heap* heap, void* heapLock);
|
||||||
|
typedef void(MIHIP_UnlockHeapFn)(const struct _MIHP_Heap* heap, void* heapLock);
|
||||||
|
|
||||||
typedef struct _MIHP_HeapConfig
|
typedef struct _MIHP_HeapConfig
|
||||||
{
|
{
|
||||||
size_t AllocationAlignment; // Must be power of two and at least sizeof(size_t)
|
MIHP_PlatformReqeustMemoryFn* PlatformRequestMemoryFn; // Alignment must at least be alignment of size_t, outActualSize must at least be minRequestedSize
|
||||||
|
MIHP_PlatformFreeMemoryFn* PlatformFreeMemoryFn; // Can return false if the memory cannot be freed
|
||||||
|
MIHP_OnHeapCorruptionDetectedFn* OnHeapCorruptionDetectedFn; // Can be NULL
|
||||||
|
|
||||||
size_t MinimalMemoryAreaSize; // Must be a multiple of AllocationAlignment
|
size_t MinimalMemoryAreaSize; // Must be a multiple of AllocationAlignment
|
||||||
size_t MaximalMemoryAreaSize; // Must be a multiple of AllocationAlignment
|
size_t MaximalMemoryAreaSize; // Must be a multiple of AllocationAlignment
|
||||||
|
|
||||||
char AllocationInitialValue;
|
size_t AllocationAlignment; // Must be power of two and at least sizeof(size_t)
|
||||||
|
char AllocationInitialValue; // Initial value the returned blocks are to be filled with
|
||||||
|
|
||||||
|
void* HeapLock; // Does not need to be reentred safe, can be NULL to disable locking
|
||||||
|
MIHIP_LockHeapFn* LockHeapFn; // Can be NULL if HeapLock is NULL
|
||||||
|
MIHIP_LockHeapFn* UnlockHeapFn; // Can be NULL if HeapLock is NULL
|
||||||
} MIHP_HeapConfig;
|
} MIHP_HeapConfig;
|
||||||
|
|
||||||
typedef struct _MIHP_HeapStats
|
typedef struct _MIHP_HeapStats
|
||||||
@@ -114,8 +120,6 @@ typedef struct _MIHP_Heap
|
|||||||
MIHP_HeapStats Stats;
|
MIHP_HeapStats Stats;
|
||||||
MIHP_HeapMemoryAreaHeader* FirstArea;
|
MIHP_HeapMemoryAreaHeader* FirstArea;
|
||||||
MIHP_HeapMemoryAreaHeader* LastSuccessfulAllocationArea;
|
MIHP_HeapMemoryAreaHeader* LastSuccessfulAllocationArea;
|
||||||
|
|
||||||
MIHP_HEAP_LOCK_TYPE HeapLock;
|
|
||||||
} MIHP_Heap;
|
} MIHP_Heap;
|
||||||
|
|
||||||
/* API Interface */
|
/* API Interface */
|
||||||
@@ -133,6 +137,9 @@ void MIHP_ValidateHeap(MIHP_Heap* heap);
|
|||||||
/* */
|
/* */
|
||||||
|
|
||||||
/* Internals */
|
/* Internals */
|
||||||
|
void MIHP_LockHeap(MIHP_Heap* heap);
|
||||||
|
void MIHP_UnlockHeap(MIHP_Heap* heap);
|
||||||
|
|
||||||
MIHP_HeapMemoryAreaHeader* MIHP_CreateHeapMemoryArea(MIHP_Heap* heap, size_t requestedSize);
|
MIHP_HeapMemoryAreaHeader* MIHP_CreateHeapMemoryArea(MIHP_Heap* heap, size_t requestedSize);
|
||||||
bool MIHP_DestroyHeapMemoryArea(MIHP_Heap* heap, MIHP_HeapMemoryAreaHeader* area);
|
bool MIHP_DestroyHeapMemoryArea(MIHP_Heap* heap, MIHP_HeapMemoryAreaHeader* area);
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
#define MIHP_MIN(A, B) (A) < (B) ? (A) : (B)
|
#define MIHP_MIN(A, B) (A) < (B) ? (A) : (B)
|
||||||
#define MIHP_MAX(A, B) (A) > (B) ? (A) : (B)
|
#define MIHP_MAX(A, B) (A) > (B) ? (A) : (B)
|
||||||
|
|
||||||
#define MIHP_MEMSET(Ptr, Size, Val) for(size_t i = 0; i < Size; ++i) *((char*)Ptr + i) = Val;
|
|
||||||
|
|
||||||
#define MIHP_IS_PO2(Val) (Val != 0 && (Val & (Val - 1)) == 0)
|
#define MIHP_IS_PO2(Val) (Val != 0 && (Val & (Val - 1)) == 0)
|
||||||
|
|
||||||
bool MIHP_InitializeHeap(MIHP_Heap* heap, MIHP_HeapConfig config)
|
bool MIHP_InitializeHeap(MIHP_Heap* heap, MIHP_HeapConfig config)
|
||||||
@@ -13,6 +11,12 @@ bool MIHP_InitializeHeap(MIHP_Heap* heap, MIHP_HeapConfig config)
|
|||||||
if (MIHP_IsHeapInitialized(heap))
|
if (MIHP_IsHeapInitialized(heap))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (config.PlatformRequestMemoryFn == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (config.PlatformFreeMemoryFn == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (config.AllocationAlignment < sizeof(size_t))
|
if (config.AllocationAlignment < sizeof(size_t))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -25,6 +29,15 @@ bool MIHP_InitializeHeap(MIHP_Heap* heap, MIHP_HeapConfig config)
|
|||||||
if (config.MaximalMemoryAreaSize % config.AllocationAlignment != 0)
|
if (config.MaximalMemoryAreaSize % config.AllocationAlignment != 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (config.HeapLock != NULL)
|
||||||
|
{
|
||||||
|
if (config.LockHeapFn == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (config.UnlockHeapFn == NULL)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
MIHP_MEMSET(heap, sizeof(MIHP_Heap), 0);
|
MIHP_MEMSET(heap, sizeof(MIHP_Heap), 0);
|
||||||
|
|
||||||
heap->Config = config;
|
heap->Config = config;
|
||||||
@@ -79,7 +92,7 @@ void* MIHP_Allocate(MIHP_Heap* heap, size_t size)
|
|||||||
if (size > heap->Config.MaximalMemoryAreaSize)
|
if (size > heap->Config.MaximalMemoryAreaSize)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
MIHP_LOCK_HEAP(&heap->HeapLock);
|
MIHP_LockHeap(heap);
|
||||||
|
|
||||||
MIHP_HeapMemoryAreaHeader* nextArea = heap->FirstArea;
|
MIHP_HeapMemoryAreaHeader* nextArea = heap->FirstArea;
|
||||||
do
|
do
|
||||||
@@ -133,7 +146,7 @@ void* MIHP_Allocate(MIHP_Heap* heap, size_t size)
|
|||||||
heap->Stats.NumTotalOccupiedSegments++;
|
heap->Stats.NumTotalOccupiedSegments++;
|
||||||
heap->LastSuccessfulAllocationArea = currentArea;
|
heap->LastSuccessfulAllocationArea = currentArea;
|
||||||
|
|
||||||
MIHP_UNLOCK_HEAP(&heap->HeapLock);
|
MIHP_UnlockHeap(heap);
|
||||||
|
|
||||||
void* data = MIHP_GetSegmentPayloadPtr(heap, targetSegment);
|
void* data = MIHP_GetSegmentPayloadPtr(heap, targetSegment);
|
||||||
MIHP_MEMSET(data, size, heap->Config.AllocationInitialValue);
|
MIHP_MEMSET(data, size, heap->Config.AllocationInitialValue);
|
||||||
@@ -152,7 +165,7 @@ void* MIHP_Allocate(MIHP_Heap* heap, size_t size)
|
|||||||
MIHP_HeapMemoryAreaHeader* newArea = MIHP_CreateHeapMemoryArea(heap, newAreaSize);
|
MIHP_HeapMemoryAreaHeader* newArea = MIHP_CreateHeapMemoryArea(heap, newAreaSize);
|
||||||
if (newArea == NULL)
|
if (newArea == NULL)
|
||||||
{
|
{
|
||||||
MIHP_UNLOCK_HEAP(&heap->HeapLock);
|
MIHP_UnlockHeap(heap);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,7 +177,7 @@ void* MIHP_Allocate(MIHP_Heap* heap, size_t size)
|
|||||||
heap->LastSuccessfulAllocationArea = newArea;
|
heap->LastSuccessfulAllocationArea = newArea;
|
||||||
newArea->Checksum = MIHP_GenerateHeapMemoryAreaChecksum(newArea);
|
newArea->Checksum = MIHP_GenerateHeapMemoryAreaChecksum(newArea);
|
||||||
|
|
||||||
MIHP_UNLOCK_HEAP(&heap->HeapLock);
|
MIHP_UnlockHeap(heap);
|
||||||
return MIHP_Allocate(heap, size);
|
return MIHP_Allocate(heap, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,7 +198,7 @@ void* MIHP_Reallocate(MIHP_Heap* heap, void* ptr, size_t newSize)
|
|||||||
if (!MIHP_IsPointerInHeap(heap, ptr))
|
if (!MIHP_IsPointerInHeap(heap, ptr))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
MIHP_LOCK_HEAP(&heap->HeapLock);
|
MIHP_LockHeap(heap);
|
||||||
|
|
||||||
MIHP_HeapSegmentHeader* segment = MIHP_GetSegmentHeaderPtr(heap, ptr);
|
MIHP_HeapSegmentHeader* segment = MIHP_GetSegmentHeaderPtr(heap, ptr);
|
||||||
MIHP_ValidateHeapSegmentHeader(heap, segment);
|
MIHP_ValidateHeapSegmentHeader(heap, segment);
|
||||||
@@ -200,17 +213,17 @@ void* MIHP_Reallocate(MIHP_Heap* heap, void* ptr, size_t newSize)
|
|||||||
segment->OccupiedSize = newSize;
|
segment->OccupiedSize = newSize;
|
||||||
segment->Checksum = MIHP_GenerateHeapSegmentChecksum(segment);
|
segment->Checksum = MIHP_GenerateHeapSegmentChecksum(segment);
|
||||||
|
|
||||||
MIHP_UNLOCK_HEAP(&heap->HeapLock);
|
MIHP_UnlockHeap(heap);
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (segment->NextSegment && MIHP_MergeHeapSegments(segment, segment->NextSegment))
|
if (segment->NextSegment && MIHP_MergeHeapSegments(segment, segment->NextSegment))
|
||||||
{
|
{
|
||||||
MIHP_UNLOCK_HEAP(&heap->HeapLock);
|
MIHP_UnlockHeap(heap);
|
||||||
return MIHP_Reallocate(heap, ptr, newSize);
|
return MIHP_Reallocate(heap, ptr, newSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
MIHP_UNLOCK_HEAP(&heap->HeapLock);
|
MIHP_UnlockHeap(heap);
|
||||||
|
|
||||||
void* newPtr = MIHP_Allocate(heap, newSize);
|
void* newPtr = MIHP_Allocate(heap, newSize);
|
||||||
if (!newPtr)
|
if (!newPtr)
|
||||||
@@ -238,11 +251,11 @@ void* MIHP_Reallocate(MIHP_Heap* heap, void* ptr, size_t newSize)
|
|||||||
MIHP_MergeHeapSegments(newSpittedSegment, newSpittedSegment->NextSegment);
|
MIHP_MergeHeapSegments(newSpittedSegment, newSpittedSegment->NextSegment);
|
||||||
}
|
}
|
||||||
|
|
||||||
MIHP_UNLOCK_HEAP(&heap->HeapLock);
|
MIHP_UnlockHeap(heap);
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
MIHP_UNLOCK_HEAP(&heap->HeapLock);
|
MIHP_UnlockHeap(heap);
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -257,7 +270,7 @@ bool MIHP_Free(MIHP_Heap* heap, void* ptr)
|
|||||||
if (!MIHP_IsPointerInHeap(heap, ptr))
|
if (!MIHP_IsPointerInHeap(heap, ptr))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
MIHP_LOCK_HEAP(&heap->HeapLock);
|
MIHP_LockHeap(heap);
|
||||||
|
|
||||||
MIHP_HeapSegmentHeader* segment = MIHP_GetSegmentHeaderPtr(heap, ptr);
|
MIHP_HeapSegmentHeader* segment = MIHP_GetSegmentHeaderPtr(heap, ptr);
|
||||||
MIHP_ValidateHeapSegmentHeader(heap, segment);
|
MIHP_ValidateHeapSegmentHeader(heap, segment);
|
||||||
@@ -271,7 +284,8 @@ bool MIHP_Free(MIHP_Heap* heap, void* ptr)
|
|||||||
corruptionInfo.Type = MIHP_HEAP_CORRUPTION_TYPE_DOUBLE_FREE;
|
corruptionInfo.Type = MIHP_HEAP_CORRUPTION_TYPE_DOUBLE_FREE;
|
||||||
corruptionInfo.Ptr = ptr;
|
corruptionInfo.Ptr = ptr;
|
||||||
|
|
||||||
MIHP_PlatformOnHeapCorruptionDetected(heap, corruptionInfo);
|
if (heap->Config.OnHeapCorruptionDetectedFn != NULL)
|
||||||
|
heap->Config.OnHeapCorruptionDetectedFn(heap, corruptionInfo);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,7 +324,7 @@ bool MIHP_Free(MIHP_Heap* heap, void* ptr)
|
|||||||
if (heap->LastSuccessfulAllocationArea == area)
|
if (heap->LastSuccessfulAllocationArea == area)
|
||||||
heap->LastSuccessfulAllocationArea = nextArea;
|
heap->LastSuccessfulAllocationArea = nextArea;
|
||||||
|
|
||||||
MIHP_UNLOCK_HEAP(&heap->HeapLock);
|
MIHP_UnlockHeap(heap);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -329,7 +343,7 @@ bool MIHP_Free(MIHP_Heap* heap, void* ptr)
|
|||||||
MIHP_MergeHeapSegments(segment->PreviousSegment, segment);
|
MIHP_MergeHeapSegments(segment->PreviousSegment, segment);
|
||||||
}
|
}
|
||||||
|
|
||||||
MIHP_UNLOCK_HEAP(&heap->HeapLock);
|
MIHP_UnlockHeap(heap);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,7 +352,7 @@ bool MIHP_IsPointerInHeap(MIHP_Heap* heap, void* ptr)
|
|||||||
if (heap == NULL)
|
if (heap == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
MIHP_LOCK_HEAP(&heap->HeapLock);
|
MIHP_LockHeap(heap);
|
||||||
|
|
||||||
size_t searchingPtr = (size_t)ptr;
|
size_t searchingPtr = (size_t)ptr;
|
||||||
|
|
||||||
@@ -346,6 +360,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);
|
||||||
nextArea = currentArea->NextArea;
|
nextArea = currentArea->NextArea;
|
||||||
|
|
||||||
size_t ptrMin = (size_t)currentArea;
|
size_t ptrMin = (size_t)currentArea;
|
||||||
@@ -353,12 +368,12 @@ bool MIHP_IsPointerInHeap(MIHP_Heap* heap, void* ptr)
|
|||||||
|
|
||||||
if (searchingPtr >= ptrMin && searchingPtr <= ptrMax)
|
if (searchingPtr >= ptrMin && searchingPtr <= ptrMax)
|
||||||
{
|
{
|
||||||
MIHP_UNLOCK_HEAP(&heap->HeapLock);
|
MIHP_UnlockHeap(heap);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MIHP_UNLOCK_HEAP(&heap->HeapLock);
|
MIHP_UnlockHeap(heap);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -367,7 +382,7 @@ size_t MIHP_GetPtrAllocationSize(MIHP_Heap* heap, void* ptr)
|
|||||||
if (!MIHP_IsPointerInHeap(heap, ptr))
|
if (!MIHP_IsPointerInHeap(heap, ptr))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
MIHP_LOCK_HEAP(&heap->HeapLock);
|
MIHP_LockHeap(heap);
|
||||||
|
|
||||||
size_t segmentHeaderSize = MIHP_GetHeapAlignedSize(heap, sizeof(MIHP_HeapSegmentHeader));
|
size_t segmentHeaderSize = MIHP_GetHeapAlignedSize(heap, sizeof(MIHP_HeapSegmentHeader));
|
||||||
MIHP_HeapSegmentHeader* segment = (MIHP_HeapSegmentHeader*)((char*)ptr - segmentHeaderSize);
|
MIHP_HeapSegmentHeader* segment = (MIHP_HeapSegmentHeader*)((char*)ptr - segmentHeaderSize);
|
||||||
@@ -395,6 +410,18 @@ void MIHP_ValidateHeap(MIHP_Heap* heap)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MIHP_LockHeap(MIHP_Heap* heap)
|
||||||
|
{
|
||||||
|
if (heap->Config.HeapLock)
|
||||||
|
heap->Config.LockHeapFn(heap, heap->Config.HeapLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MIHP_UnlockHeap(MIHP_Heap* heap)
|
||||||
|
{
|
||||||
|
if (heap->Config.HeapLock)
|
||||||
|
heap->Config.UnlockHeapFn(heap, heap->Config.HeapLock);
|
||||||
|
}
|
||||||
|
|
||||||
MIHP_HeapMemoryAreaHeader* MIHP_CreateHeapMemoryArea(MIHP_Heap* heap, size_t requestedSize)
|
MIHP_HeapMemoryAreaHeader* MIHP_CreateHeapMemoryArea(MIHP_Heap* heap, size_t requestedSize)
|
||||||
{
|
{
|
||||||
MIHP_ASSERT(heap);
|
MIHP_ASSERT(heap);
|
||||||
@@ -404,7 +431,7 @@ MIHP_HeapMemoryAreaHeader* MIHP_CreateHeapMemoryArea(MIHP_Heap* heap, size_t req
|
|||||||
effectiveSize = MIHP_MIN(effectiveSize, heap->Config.MaximalMemoryAreaSize);
|
effectiveSize = MIHP_MIN(effectiveSize, heap->Config.MaximalMemoryAreaSize);
|
||||||
|
|
||||||
size_t actualSize = 0;
|
size_t actualSize = 0;
|
||||||
MIHP_HeapMemoryAreaHeader* area = (MIHP_HeapMemoryAreaHeader*)MIHP_PlatformRequestMemory(heap, effectiveSize, &actualSize);
|
MIHP_HeapMemoryAreaHeader* area = (MIHP_HeapMemoryAreaHeader*)heap->Config.PlatformRequestMemoryFn(heap, effectiveSize, &actualSize);
|
||||||
if (area == NULL)
|
if (area == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@@ -434,7 +461,7 @@ bool MIHP_DestroyHeapMemoryArea(MIHP_Heap* heap, MIHP_HeapMemoryAreaHeader* memo
|
|||||||
size_t areaNumOccupiedSegments = memoryArea->NumOccupiedSegments;
|
size_t areaNumOccupiedSegments = memoryArea->NumOccupiedSegments;
|
||||||
size_t areaSize = memoryArea->AreaSize;
|
size_t areaSize = memoryArea->AreaSize;
|
||||||
|
|
||||||
if (!MIHP_PlatformFreeMemory(heap, memoryArea, memoryArea->AreaSize))
|
if (!heap->Config.PlatformFreeMemoryFn(heap, memoryArea, memoryArea->AreaSize))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
heap->Stats.NumTotalSegments -= areaNumSegments;
|
heap->Stats.NumTotalSegments -= areaNumSegments;
|
||||||
@@ -620,6 +647,9 @@ uint32_t MIHP_GenerateHeapSegmentChecksum(const MIHP_HeapSegmentHeader* segment)
|
|||||||
|
|
||||||
void MIHP_ValidateHeapMemoryAreaHeader(const MIHP_Heap* heap, const MIHP_HeapMemoryAreaHeader* area)
|
void MIHP_ValidateHeapMemoryAreaHeader(const MIHP_Heap* heap, const MIHP_HeapMemoryAreaHeader* area)
|
||||||
{
|
{
|
||||||
|
if (heap->Config.OnHeapCorruptionDetectedFn == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
uint32_t newChecksum;
|
uint32_t newChecksum;
|
||||||
|
|
||||||
#if MIHP_HEAP_STRUCTURE_VALIDATION_TYPE == MIHP_HEAP_STRUCTURE_VALIDATION_TYPE_NONE
|
#if MIHP_HEAP_STRUCTURE_VALIDATION_TYPE == MIHP_HEAP_STRUCTURE_VALIDATION_TYPE_NONE
|
||||||
@@ -640,12 +670,15 @@ void MIHP_ValidateHeapMemoryAreaHeader(const MIHP_Heap* heap, const MIHP_HeapMem
|
|||||||
corruptionInfo.ExpectedValue = area->Checksum;
|
corruptionInfo.ExpectedValue = area->Checksum;
|
||||||
corruptionInfo.ActualValue = newChecksum;
|
corruptionInfo.ActualValue = newChecksum;
|
||||||
|
|
||||||
MIHP_PlatformOnHeapCorruptionDetected(heap, corruptionInfo);
|
heap->Config.OnHeapCorruptionDetectedFn(heap, corruptionInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MIHP_ValidateHeapSegmentHeader(const MIHP_Heap* heap, const MIHP_HeapSegmentHeader* segment)
|
void MIHP_ValidateHeapSegmentHeader(const MIHP_Heap* heap, const MIHP_HeapSegmentHeader* segment)
|
||||||
{
|
{
|
||||||
|
if (heap->Config.OnHeapCorruptionDetectedFn == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
uint32_t newChecksum;
|
uint32_t newChecksum;
|
||||||
|
|
||||||
#if MIHP_HEAP_STRUCTURE_VALIDATION_TYPE == MIHP_HEAP_STRUCTURE_VALIDATION_TYPE_NONE
|
#if MIHP_HEAP_STRUCTURE_VALIDATION_TYPE == MIHP_HEAP_STRUCTURE_VALIDATION_TYPE_NONE
|
||||||
@@ -666,7 +699,7 @@ void MIHP_ValidateHeapSegmentHeader(const MIHP_Heap* heap, const MIHP_HeapSegmen
|
|||||||
corruptionInfo.ExpectedValue = segment->Checksum;
|
corruptionInfo.ExpectedValue = segment->Checksum;
|
||||||
corruptionInfo.ActualValue = newChecksum;
|
corruptionInfo.ActualValue = newChecksum;
|
||||||
|
|
||||||
MIHP_PlatformOnHeapCorruptionDetected(heap, corruptionInfo);
|
heap->Config.OnHeapCorruptionDetectedFn(heap, corruptionInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,19 +9,19 @@
|
|||||||
|
|
||||||
//#define MIHP_ValidateHeap(x)
|
//#define MIHP_ValidateHeap(x)
|
||||||
|
|
||||||
void* MIHP_PlatformRequestMemory(const MIHP_Heap* heap, size_t minRequestedSize, size_t* outActualSize)
|
void* RequestMemory(const MIHP_Heap* heap, size_t minRequestedSize, size_t* outActualSize)
|
||||||
{
|
{
|
||||||
*outActualSize = minRequestedSize;
|
*outActualSize = minRequestedSize;
|
||||||
return malloc(minRequestedSize);
|
return malloc(minRequestedSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MIHP_PlatformFreeMemory(const MIHP_Heap* heap, void* ptr, size_t actualSize)
|
bool FreeMemory(const MIHP_Heap* heap, void* ptr, size_t actualSize)
|
||||||
{
|
{
|
||||||
free(ptr);
|
free(ptr);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MIHP_PlatformOnHeapCorruptionDetected(const MIHP_Heap* heap, MIHP_HeapCorruptionInfo info)
|
void OnHeapCorruptionDetectedCallback(const MIHP_Heap* heap, MIHP_HeapCorruptionInfo info)
|
||||||
{
|
{
|
||||||
__debugbreak();
|
__debugbreak();
|
||||||
}
|
}
|
||||||
@@ -33,6 +33,11 @@ void* myptrs[NUM_ALLOCATIONS] = { 0 };
|
|||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
MIHP_HeapConfig config = {0};
|
MIHP_HeapConfig config = {0};
|
||||||
|
|
||||||
|
config.PlatformRequestMemoryFn = RequestMemory;
|
||||||
|
config.PlatformFreeMemoryFn = FreeMemory;
|
||||||
|
config.OnHeapCorruptionDetectedFn = OnHeapCorruptionDetectedCallback;
|
||||||
|
|
||||||
config.AllocationInitialValue = 0xbe;
|
config.AllocationInitialValue = 0xbe;
|
||||||
config.AllocationAlignment = 16;
|
config.AllocationAlignment = 16;
|
||||||
config.MinimalMemoryAreaSize = 4096 * 32;
|
config.MinimalMemoryAreaSize = 4096 * 32;
|
||||||
@@ -54,6 +59,8 @@ int main()
|
|||||||
|
|
||||||
__debugbreak();
|
__debugbreak();
|
||||||
|
|
||||||
|
MIHP_MEMSET(myptrs[5], 5000, 0x75);
|
||||||
|
|
||||||
for (int i = 0; i < NUM_ALLOCATIONS; i++)
|
for (int i = 0; i < NUM_ALLOCATIONS; i++)
|
||||||
{
|
{
|
||||||
if (rand() % 3 == 0)
|
if (rand() % 3 == 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user