Add UnsafeChunkedList<T> and tests; refactor alloc/util

Introduced high-performance UnsafeChunkedList<T> with parallel-safe add/read, custom enumerator, and chunk management. Added extensive unit tests for all behaviors and concurrency. Refactored AllocationManager zero-replacement logic, improved MemoryUtility alignment methods, and clarified MemoryBlock/UnsafeArray docs. Simplified Program.cs allocation test and updated build constants. Minor cleanups in GGXMipGenerationBenchmark.
This commit is contained in:
2026-05-08 21:53:07 +09:00
parent 30ab3fbefe
commit 99a7e3c4e1
9 changed files with 1473 additions and 36 deletions

View File

@@ -250,6 +250,28 @@ public static unsafe class AllocationManager
private static nuint s_threadLocalStackSize;
private static void ReplaceIfZero(ref AllocationManagerDesc desc, AllocationManagerDesc defaultDesc)
{
desc.ArenaCapacity = desc.ArenaCapacity != 0
? desc.ArenaCapacity
: defaultDesc.ArenaCapacity;
desc.StackCapacity = desc.StackCapacity != 0
? desc.StackCapacity
: defaultDesc.StackCapacity;
desc.FreeListChunkSize = desc.FreeListChunkSize != 0
? desc.FreeListChunkSize
: defaultDesc.FreeListChunkSize;
desc.FreeListDefaultAlignment = desc.FreeListDefaultAlignment != 0
? desc.FreeListDefaultAlignment
: defaultDesc.FreeListDefaultAlignment;
desc.TLSFAlignment = desc.TLSFAlignment != 0
? desc.TLSFAlignment
: defaultDesc.TLSFAlignment;
desc.TLSFInitialChunkSize = desc.TLSFInitialChunkSize != 0
? desc.TLSFInitialChunkSize
: defaultDesc.TLSFInitialChunkSize;
}
public static void Initialize(AllocationManagerDesc desc = default)
{
if (s_initialized)
@@ -262,10 +284,7 @@ public static unsafe class AllocationManager
#endif
var defaultDesc = AllocationManagerDesc.Default;
var spanDesc = MemoryMarshal.AsBytes(MemoryMarshal.CreateSpan(ref desc, 1));
var spanDefault = MemoryMarshal.AsBytes(MemoryMarshal.CreateSpan(ref defaultDesc, 1));
MemoryUtility.ReplaceIfZeros(spanDesc, spanDefault);
ReplaceIfZero(ref desc, defaultDesc);
s_arenaAllocator = new MemoryPool<VirtualArena, VirtualArena.CreationOptions>(new VirtualArena.CreationOptions
{

View File

@@ -8,7 +8,7 @@ public unsafe struct MemoryBlock : IDisposable
{
private void* _buffer;
private nuint _size;
private nuint _alignment;
private readonly nuint _alignment;
#if MHP_ENABLE_SAFETY_CHECKS
private readonly MemoryHandle _memoryHandle;
@@ -69,13 +69,13 @@ public unsafe struct MemoryBlock : IDisposable
/// Initializes an UnsafeArray with a pointer to a buffer and a count of elements. This does not copy the data.
/// </summary>
/// <param name="buffer">A pointer to the memory location that holds the elements of the array.</param>
/// <param name="count">The total size of the data.</param>
/// <param name="size">The total size of the data.</param>
/// <remarks>
/// When using this constructor, the user is responsible for managing the memory pointed to by the buffer.
/// Disposing of the UnsafeArray does not free the memory and only release the reference. The memory should be freed manually when no longer needed.
/// Use <see cref="UnsafeArray(int, Allocator, AllocationOption)"/> constructor and <see cref="MemCpy(void*, void*, nuint)"/> if you are not sure what you are doing.
/// Use <see cref="MemoryBlock(nuint, nuint, AllocationHandle, AllocationOption)"/> constructor and <see cref="MemoryUtility.MemCpy(void*, void*, nuint)"/> if you are not sure what you are doing.
/// </remarks>
public MemoryBlock(void* buffer, uint size)
public MemoryBlock(void* buffer, nuint size)
{
_buffer = buffer;
_size = size;