92 lines
2.7 KiB
C++
92 lines
2.7 KiB
C++
|
/***
|
||
|
Copyright (C) 2024 Jamie Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||
|
|
||
|
File: AuHeapAlignmentInterface.cpp
|
||
|
File: Heap.hpp
|
||
|
Date: 2024-7-17
|
||
|
Author: Reece
|
||
|
***/
|
||
|
#include <Source/RuntimeInternal.hpp>
|
||
|
#include "AuHeap.hpp"
|
||
|
#include "AuHeapAlignmentInterface.hpp"
|
||
|
|
||
|
namespace Aurora::Memory
|
||
|
{
|
||
|
struct OldHeap
|
||
|
{
|
||
|
HeapAdapterInterface interface;
|
||
|
};
|
||
|
|
||
|
static void *AlignedHeapAllocate(HeapAdapterHandle *pHandle,
|
||
|
AuUInt uLength,
|
||
|
AuUInt uAlignment)
|
||
|
{
|
||
|
auto pInterface = (OldHeap *)pHandle->pReserved[0];
|
||
|
|
||
|
uAlignment = AuNextPow2(uAlignment);
|
||
|
|
||
|
const auto kAlignment = AuMax(uAlignment, sizeof(void *) * 2);
|
||
|
|
||
|
auto pPtr = (AuUInt8 *)pInterface->interface.fAllocate(&pInterface->interface.handle, uLength + (kAlignment * 2), kAlignment);
|
||
|
|
||
|
if (!pPtr)
|
||
|
{
|
||
|
return {};
|
||
|
}
|
||
|
|
||
|
auto pRet = (AuUInt8 *)AuPageRoundUp(AuUInt(pPtr + kAlignment), uAlignment);
|
||
|
auto pSize = pRet - (sizeof(void *) * 2);
|
||
|
auto pDelta = pRet - (sizeof(void *) * 1);
|
||
|
|
||
|
*(AuUInt *)pSize = uLength;
|
||
|
*(AuUInt *)pDelta = AuUInt(pPtr);
|
||
|
return pRet;
|
||
|
}
|
||
|
|
||
|
static void AlignedHeapFree(HeapAdapterHandle *pHandle,
|
||
|
void *pPointer)
|
||
|
{
|
||
|
auto pInterface = (OldHeap *)pHandle->pReserved[0];
|
||
|
|
||
|
auto pRet = (AuUInt8 *)pPointer;
|
||
|
auto pDelta = pRet - (sizeof(void *) * 1);
|
||
|
|
||
|
pInterface->interface.fFree(&pInterface->interface.handle, *(void **)pDelta);
|
||
|
}
|
||
|
|
||
|
static AuUInt AlignedHeapGetBlockSize(HeapAdapterHandle *pHandle,
|
||
|
void *pPointer)
|
||
|
{
|
||
|
auto pRet = (AuUInt8 *)pPointer;
|
||
|
auto pSize = pRet - (sizeof(void *) * 2);
|
||
|
return *(AuUInt *)pSize;
|
||
|
}
|
||
|
|
||
|
static void AlignedHeapDestroy(HeapAdapterHandle *pHandle)
|
||
|
{
|
||
|
auto pInterface = (OldHeap *)pHandle->pReserved[0];
|
||
|
if (pInterface->interface.fHeapDestroy)
|
||
|
{
|
||
|
pInterface->interface.fHeapDestroy(&pInterface->interface.handle);
|
||
|
}
|
||
|
delete pInterface;
|
||
|
}
|
||
|
|
||
|
bool MakeHeapInterfaceOfStricterAlignment(HeapAdapterInterface *pInterface)
|
||
|
{
|
||
|
auto pNew = _new OldHeap();
|
||
|
if (!pNew)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
pNew->interface = *pInterface;
|
||
|
|
||
|
pInterface->handle.pReserved[0] = pNew;
|
||
|
pInterface->fHeapDestroy = AlignedHeapDestroy;
|
||
|
pInterface->fGetBlockSize = AlignedHeapGetBlockSize;
|
||
|
pInterface->fFree = AlignedHeapFree;
|
||
|
pInterface->fAllocate = AlignedHeapAllocate;
|
||
|
return true;
|
||
|
}
|
||
|
}
|