using Misaki.HighPerformance.Unsafe.Collections; using System.Runtime.InteropServices; namespace Misaki.HighPerformance.Unsafe.Buffer; /// /// A memory management structure that allocates and resets memory blocks with specified alignment. /// public unsafe struct Arena : IDisposable { private byte* _buffer; private uint _size; private uint _offset; private bool _disposed; public Arena(uint size) { _buffer = (byte*)Malloc(size); _size = size; _offset = 0; } /// /// Allocates a block of memory of a specified size with a given alignment. Returns a pointer to the allocated /// memory or null if allocation fails. /// Must use to free the memory. /// /// Specifies the amount of memory to allocate in bytes. /// Defines the alignment requirement for the allocated memory. /// A pointer to the allocated memory block or null if the allocation cannot be fulfilled. /// Thrown if the arena has been disposed. public void* Allocate(uint size, uint alignSize, AllocationOption allocationType) { ObjectDisposedException.ThrowIf(_disposed, this); var offset = (_offset + alignSize - 1) & ~(alignSize - 1); if (offset + size > _size) { return null; } _offset = offset + size; var ptr = _buffer + offset; if (allocationType == AllocationOption.Clear) { MemClear(ptr, size); } return ptr; } /// /// Resets the arena, optionally clearing the allocated memory. /// /// If true, the allocated memory will be cleared; otherwise, it will not be cleared. /// Thrown if the arena has been disposed. public void Reset(bool clear = false) { ObjectDisposedException.ThrowIf(_disposed, this); if (clear) { MemClear(_buffer, _size); } _offset = 0; } public void Dispose() { Free(_buffer); _buffer = null; _size = 0; _offset = 0; _disposed = true; } }