using System; using System.Linq; using System.Threading.Tasks; using Native = System.UInt32; namespace Cosmos.Core.Memory { /// /// HeapLarge class. Used to alloc and free large memory blocks on the heap. /// unsafe static public class HeapLarge { /// /// Prefix block. Used to store meta information. /// public const Native PrefixBytes = 4 * sizeof(Native); /// /// Init HeapLarge instance. /// /// Empty function static public void Init() { } /// /// Alloc memory block, of a given size. /// /// A size of block to alloc, in bytes. /// Byte pointer to the start of the block. static public byte* Alloc(Native aSize) { Native xPages = (Native)((aSize + PrefixBytes) / RAT.PageSize) + 1; var xPtr = (Native*)RAT.AllocPages(RAT.PageType.HeapLarge, xPages); xPtr[0] = xPages * RAT.PageSize - PrefixBytes; // Allocated data size xPtr[1] = aSize; // Actual data size xPtr[2] = 0; // Ref count xPtr[3] = 0; // Ptr to first return (byte*)xPtr + PrefixBytes; } /// /// Free block. /// /// A pointer to the block. /// Thrown if page type is not found. static public void Free(void* aPtr) { // TODO - Should check the page type before freeing to make sure it is a Large? // or just trust the caller to avoid adding overhead? var xPageIdx = RAT.GetFirstRAT(aPtr); RAT.Free(xPageIdx); } } }