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);
}
}
}