mirror of
https://github.com/ToyB-Chan/minimal-heap.git
synced 2026-07-13 21:51:16 +02:00
fixed some bugs
This commit is contained in:
@@ -17,7 +17,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MIHP_MEMSET
|
#ifndef MIHP_MEMSET
|
||||||
#define MIHP_MEMSET(Ptr, Size, Val) for(size_t i = 0; i < Size; ++i) *((char*)Ptr + i) = Val;
|
#define MIHP_MEMSET(Ptr, Size, Val) do { for(size_t i = 0; i < Size; ++i) *((char*)Ptr + i) = Val; } while(0);
|
||||||
#endif
|
#endif
|
||||||
/* */
|
/* */
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ typedef struct _MIHP_HeapConfig
|
|||||||
|
|
||||||
void* HeapLock; // Does not need to be reentred safe, can be NULL to disable locking
|
void* HeapLock; // Does not need to be reentred safe, can be NULL to disable locking
|
||||||
MIHP_LockHeapFn* LockHeapFn; // Can be NULL if HeapLock is NULL
|
MIHP_LockHeapFn* LockHeapFn; // Can be NULL if HeapLock is NULL
|
||||||
MIHP_LockHeapFn* UnlockHeapFn; // Can be NULL if HeapLock is NULL
|
MIHP_UnlockHeapFn* UnlockHeapFn; // Can be NULL if HeapLock is NULL
|
||||||
} MIHP_HeapConfig;
|
} MIHP_HeapConfig;
|
||||||
|
|
||||||
typedef struct _MIHP_HeapStats
|
typedef struct _MIHP_HeapStats
|
||||||
@@ -73,7 +73,6 @@ typedef struct _MIHP_HeapStats
|
|||||||
size_t TotalSize;
|
size_t TotalSize;
|
||||||
} MIHP_HeapStats;
|
} MIHP_HeapStats;
|
||||||
|
|
||||||
// This structs size must be multiple of 8
|
|
||||||
typedef struct _MIHP_HeapMemoryAreaHeader
|
typedef struct _MIHP_HeapMemoryAreaHeader
|
||||||
{
|
{
|
||||||
size_t AreaSize;
|
size_t AreaSize;
|
||||||
@@ -86,6 +85,7 @@ typedef struct _MIHP_HeapMemoryAreaHeader
|
|||||||
struct _MIHP_HeapSegmentHeader* FirstSegment;
|
struct _MIHP_HeapSegmentHeader* FirstSegment;
|
||||||
struct _MIHP_HeapSegmentHeader* LastSuccessfulAllocationSegment;
|
struct _MIHP_HeapSegmentHeader* LastSuccessfulAllocationSegment;
|
||||||
|
|
||||||
|
// TODO: Change this to an InstigatingHeapUuid (opaque ptr)
|
||||||
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!
|
||||||
|
|
||||||
uint32_t Checksum; // Checksum must be the last member !
|
uint32_t Checksum; // Checksum must be the last member !
|
||||||
@@ -96,7 +96,6 @@ typedef struct _MIHP_AllocationCustomMetadata
|
|||||||
uint8_t data[16];
|
uint8_t data[16];
|
||||||
} MIHP_AllocationCustomMetadata;
|
} MIHP_AllocationCustomMetadata;
|
||||||
|
|
||||||
// This structs size must be multiple of 8
|
|
||||||
typedef struct _MIHP_HeapSegmentHeader
|
typedef struct _MIHP_HeapSegmentHeader
|
||||||
{
|
{
|
||||||
size_t SegmentSize;
|
size_t SegmentSize;
|
||||||
@@ -109,7 +108,6 @@ typedef struct _MIHP_HeapSegmentHeader
|
|||||||
struct _MIHP_AllocationCustomMetadata CustomMetadata;
|
struct _MIHP_AllocationCustomMetadata CustomMetadata;
|
||||||
|
|
||||||
uint32_t Checksum; // Checksum must be the last member !
|
uint32_t Checksum; // Checksum must be the last member !
|
||||||
|
|
||||||
} MIHP_HeapSegmentHeader;
|
} MIHP_HeapSegmentHeader;
|
||||||
|
|
||||||
typedef struct _MIHP_HeapCorruptionInfo
|
typedef struct _MIHP_HeapCorruptionInfo
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#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_IS_PO2(Val) (Val != 0 && (Val & (Val - 1)) == 0)
|
#define MIHP_IS_PO2(Val) (Val != 0 && (Val & (Val - 1)) == 0)
|
||||||
|
|
||||||
@@ -66,6 +66,9 @@ bool MIHP_InitializeHeap(MIHP_Heap* heap, MIHP_HeapConfig config)
|
|||||||
|
|
||||||
heap->Config = config;
|
heap->Config = config;
|
||||||
heap->FirstArea = MIHP_CreateHeapMemoryArea(heap, config.MinMemoryAreaSize);
|
heap->FirstArea = MIHP_CreateHeapMemoryArea(heap, config.MinMemoryAreaSize);
|
||||||
|
if (heap->FirstArea == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
heap->LastSuccessfulAllocationArea = heap->FirstArea;
|
heap->LastSuccessfulAllocationArea = heap->FirstArea;
|
||||||
|
|
||||||
heap->FirstArea->Checksum = MIHP_GenerateHeapMemoryAreaChecksum(heap, heap->FirstArea);
|
heap->FirstArea->Checksum = MIHP_GenerateHeapMemoryAreaChecksum(heap, heap->FirstArea);
|
||||||
@@ -185,7 +188,7 @@ void* MIHP_Allocate(MIHP_Heap* heap, size_t size)
|
|||||||
///
|
///
|
||||||
/// No free segment found (in time), allocate new area
|
/// No free segment found (in time), allocate new area
|
||||||
///
|
///
|
||||||
|
|
||||||
size_t newAreaSize = heap->Stats.TotalSize / 4; // growth-rate of 1.25
|
size_t newAreaSize = heap->Stats.TotalSize / 4; // growth-rate of 1.25
|
||||||
|
|
||||||
while (newAreaSize < size)
|
while (newAreaSize < size)
|
||||||
@@ -309,18 +312,20 @@ bool MIHP_Free(MIHP_Heap* heap, void* ptr)
|
|||||||
|
|
||||||
if (segment->OccupiedSize == 0)
|
if (segment->OccupiedSize == 0)
|
||||||
{
|
{
|
||||||
MIHP_HeapCorruptionInfo corruptionInfo = {0};
|
MIHP_HeapCorruptionInfo corruptionInfo = { 0 };
|
||||||
corruptionInfo.Type = MIHP_HCE_DoubleFree;
|
corruptionInfo.Type = MIHP_HCE_DoubleFree;
|
||||||
corruptionInfo.Ptr = ptr;
|
corruptionInfo.Ptr = ptr;
|
||||||
|
|
||||||
if (heap->Config.OnHeapCorruptionDetectedFn != NULL)
|
if (heap->Config.OnHeapCorruptionDetectedFn != NULL)
|
||||||
heap->Config.OnHeapCorruptionDetectedFn(heap, corruptionInfo);
|
heap->Config.OnHeapCorruptionDetectedFn(heap, corruptionInfo);
|
||||||
|
|
||||||
|
MIHP_UnlockHeap(heap);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
segment->OccupiedSize = 0;
|
segment->OccupiedSize = 0;
|
||||||
segment->Checksum = MIHP_GenerateHeapSegmentChecksum(heap, segment);
|
segment->Checksum = MIHP_GenerateHeapSegmentChecksum(heap, segment);
|
||||||
|
|
||||||
area->NumOccupiedSegments--;
|
area->NumOccupiedSegments--;
|
||||||
area->Checksum = MIHP_GenerateHeapMemoryAreaChecksum(heap, area);
|
area->Checksum = MIHP_GenerateHeapMemoryAreaChecksum(heap, area);
|
||||||
|
|
||||||
@@ -468,7 +473,7 @@ bool MIHP_IsPointerInHeap(MIHP_Heap* heap, void* ptr)
|
|||||||
MIHP_HeapMemoryAreaHeader* currentArea = nextArea;
|
MIHP_HeapMemoryAreaHeader* currentArea = nextArea;
|
||||||
MIHP_ValidateHeapMemoryAreaHeader(heap, currentArea);
|
MIHP_ValidateHeapMemoryAreaHeader(heap, currentArea);
|
||||||
nextArea = currentArea->NextArea;
|
nextArea = currentArea->NextArea;
|
||||||
|
|
||||||
uintptr_t ptrMin = (uintptr_t)currentArea;
|
uintptr_t ptrMin = (uintptr_t)currentArea;
|
||||||
uintptr_t ptrMax = (uintptr_t)currentArea + currentArea->AreaSize;
|
uintptr_t ptrMax = (uintptr_t)currentArea + currentArea->AreaSize;
|
||||||
|
|
||||||
@@ -494,6 +499,7 @@ size_t MIHP_GetPtrAllocationSize(MIHP_Heap* heap, void* ptr)
|
|||||||
MIHP_HeapSegmentHeader* segment = (MIHP_HeapSegmentHeader*)((char*)ptr - segmentHeaderSize);
|
MIHP_HeapSegmentHeader* segment = (MIHP_HeapSegmentHeader*)((char*)ptr - segmentHeaderSize);
|
||||||
MIHP_ValidateHeapSegmentHeader(heap, segment);
|
MIHP_ValidateHeapSegmentHeader(heap, segment);
|
||||||
|
|
||||||
|
MIHP_UnlockHeap(heap);
|
||||||
return segment->OccupiedSize;
|
return segment->OccupiedSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -672,7 +678,7 @@ bool MIHP_SplitHeapSegment(MIHP_Heap* heap, MIHP_HeapSegmentHeader* sourceSegmen
|
|||||||
|
|
||||||
if (sourceResultingSegmentSize < MIHP_GetMinimalPayloadSize(heap) + headerSize)
|
if (sourceResultingSegmentSize < MIHP_GetMinimalPayloadSize(heap) + headerSize)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (sourceResultingSegmentSize < sourceSegment->OccupiedSize + headerSize)
|
if (sourceResultingSegmentSize < sourceSegment->OccupiedSize + headerSize)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|||||||
@@ -74,8 +74,6 @@ int main()
|
|||||||
memcpy(&returnPtr, &outMetadata.data, sizeof(void*));
|
memcpy(&returnPtr, &outMetadata.data, sizeof(void*));
|
||||||
|
|
||||||
MIHP_ASSERT(ptr == returnPtr);
|
MIHP_ASSERT(ptr == returnPtr);
|
||||||
|
|
||||||
__debugbreak();
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user