/*** 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 #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; } }