Centralize memory ops via MemoryUtility, add VM support
Refactor all memory allocation/deallocation to use MemoryUtility, replacing direct calls with unified methods. Introduce cross-platform virtual memory management (Mmap, Munmap, Decommit, Recommit). Switch to NativeMemory for standard allocations. Enhance FreeList with global free buckets and thread safety. Standardize alignment/size calculations. Remove global usings for memory utils. Bump version to 1.6.24. Includes minor cleanups and improved docs.
This commit is contained in:
@@ -132,8 +132,8 @@ public unsafe struct HashMapHelper<TKey> : IDisposable
|
||||
_capacity = CalcCapacityCeilPow2(capacity);
|
||||
_bucketCapacity = _capacity * 2;
|
||||
|
||||
var alignOfKey = (int)AlignOf<TKey>();
|
||||
var alignOfInt = (int)AlignOf<int>();
|
||||
var alignOfKey = (int)MemoryUtility.AlignOf<TKey>();
|
||||
var alignOfInt = (int)MemoryUtility.AlignOf<int>();
|
||||
var maxDataAlign = Math.Max(Math.Max(alignOfTValue, alignOfKey), alignOfInt);
|
||||
|
||||
_alignment = maxDataAlign;
|
||||
@@ -276,7 +276,7 @@ public unsafe struct HashMapHelper<TKey> : IDisposable
|
||||
for (var idx = oldBuckets[i]; idx != -1; idx = oldNext[idx])
|
||||
{
|
||||
var newIdx = Add(oldKeys[idx]);
|
||||
MemCpy(_buffer + _sizeOfTValue * newIdx, oldBuffer + _sizeOfTValue * idx, (nuint)_sizeOfTValue);
|
||||
MemoryUtility.MemCpy(_buffer + _sizeOfTValue * newIdx, oldBuffer + _sizeOfTValue * idx, (nuint)_sizeOfTValue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -684,8 +684,8 @@ public unsafe struct HashMapHelper<TKey> : IDisposable
|
||||
{
|
||||
ThrowIfNotCreated();
|
||||
|
||||
MemSet(_buckets, 0xff, (nuint)_bucketCapacity * sizeof(int));
|
||||
MemSet(_next, 0xff, (nuint)_capacity * sizeof(int));
|
||||
MemoryUtility.MemSet(_buckets, 0xff, (nuint)_bucketCapacity * sizeof(int));
|
||||
MemoryUtility.MemSet(_next, 0xff, (nuint)_capacity * sizeof(int));
|
||||
|
||||
_count = 0;
|
||||
_firstFreeIndex = -1;
|
||||
|
||||
@@ -136,7 +136,7 @@ public unsafe struct UnsafeArray<T> : IUnsafeCollection<T>
|
||||
{
|
||||
ArgumentOutOfRangeException.ThrowIfNegative(count);
|
||||
|
||||
_buffer = (T*)handle.Alloc((nuint)(count * sizeof(T)), AlignOf<T>(), allocationOption);
|
||||
_buffer = (T*)handle.Alloc((nuint)(count * sizeof(T)), MemoryUtility.AlignOf<T>(), allocationOption);
|
||||
#if MHP_ENABLE_SAFETY_CHECKS
|
||||
_memoryHandle = MemoryHandle.Create(_buffer, (nuint)(count * sizeof(T)));
|
||||
#endif
|
||||
@@ -221,11 +221,11 @@ public unsafe struct UnsafeArray<T> : IUnsafeCollection<T>
|
||||
return;
|
||||
}
|
||||
|
||||
var elemSize = SizeOf<T>();
|
||||
_buffer = (T*)_allocationHandle.Realloc(_buffer, (nuint)Count * elemSize, (nuint)newSize * elemSize, AlignOf<T>(), option);
|
||||
var elemSize = sizeof(T);
|
||||
_buffer = (T*)_allocationHandle.Realloc(_buffer, (nuint)(_count * elemSize), (nuint)(newSize * elemSize), MemoryUtility.AlignOf<T>(), option);
|
||||
_count = newSize;
|
||||
#if MHP_ENABLE_SAFETY_CHECKS
|
||||
_memoryHandle.Update(_buffer, (nuint)newSize * elemSize);
|
||||
_memoryHandle.Update(_buffer, (nuint)(newSize * elemSize));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -234,7 +234,7 @@ public unsafe struct UnsafeArray<T> : IUnsafeCollection<T>
|
||||
public readonly void Clear()
|
||||
{
|
||||
ThrowIfNotCreated();
|
||||
MemClear(_buffer, (nuint)(Count * sizeof(T)));
|
||||
MemoryUtility.MemClear(_buffer, (nuint)_count * MemoryUtility.SizeOf<T>());
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -292,7 +292,7 @@ public unsafe struct UnsafeArray<T> : IUnsafeCollection<T>
|
||||
var size = Math.Min(destination.Length, Count);
|
||||
fixed (T* pDest = destination)
|
||||
{
|
||||
MemCpy(pDest, _buffer, (uint)(size * sizeof(T)));
|
||||
MemoryUtility.MemCpy(pDest, _buffer, (nuint)(size * sizeof(T)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,7 +313,7 @@ public unsafe struct UnsafeArray<T> : IUnsafeCollection<T>
|
||||
|
||||
fixed (T* pDest = destination)
|
||||
{
|
||||
MemCpy(pDest + destinationIndex, _buffer + sourceIndex, (nuint)(length * sizeof(T)));
|
||||
MemoryUtility.MemCpy(pDest + destinationIndex, _buffer + sourceIndex, (nuint)(length * sizeof(T)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -330,7 +330,7 @@ public unsafe struct UnsafeArray<T> : IUnsafeCollection<T>
|
||||
|
||||
fixed (T* pSrc = source)
|
||||
{
|
||||
MemCpy(_buffer, pSrc, (nuint)(source.Length * sizeof(T)));
|
||||
MemoryUtility.MemCpy(_buffer, pSrc, (nuint)(source.Length * sizeof(T)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -356,7 +356,7 @@ public unsafe struct UnsafeArray<T> : IUnsafeCollection<T>
|
||||
|
||||
fixed (T* pSrc = source)
|
||||
{
|
||||
MemCpy(_buffer + destinationIndex, pSrc + sourceIndex, (nuint)(length * sizeof(T)));
|
||||
MemoryUtility.MemCpy(_buffer + destinationIndex, pSrc + sourceIndex, (nuint)(length * sizeof(T)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ public unsafe struct UnsafeHashMap<TKey, TValue> : IUnsafeHashCollection<KeyValu
|
||||
|
||||
public UnsafeHashMap(int capacity, AllocationHandle handle, AllocationOption allocationOption = AllocationOption.None)
|
||||
{
|
||||
_helper = new HashMapHelper<TKey>(capacity, sizeof(TValue), (int)AlignOf<TValue>(), HashMapHelper<TKey>.MINIMAL_CAPACITY, handle, allocationOption);
|
||||
_helper = new HashMapHelper<TKey>(capacity, sizeof(TValue), (int)MemoryUtility.AlignOf<TValue>(), HashMapHelper<TKey>.MINIMAL_CAPACITY, handle, allocationOption);
|
||||
}
|
||||
|
||||
[Obsolete("Use AllocationHandle instead.")]
|
||||
|
||||
@@ -145,7 +145,7 @@ public unsafe struct UnsafeList<T> : IUnsafeCollection<T>
|
||||
|
||||
fixed (T* pCollection = collection)
|
||||
{
|
||||
MemCpy(UnsafeUtility.ReadArrayElementUnsafe<T>(listData->_array.GetUnsafePtr(), index), pCollection, (uint)(count * sizeof(T)));
|
||||
MemoryUtility.MemCpy(UnsafeUtility.ReadArrayElementUnsafe<T>(listData->_array.GetUnsafePtr(), index), pCollection, (uint)(count * sizeof(T)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -342,7 +342,7 @@ public unsafe struct UnsafeList<T> : IUnsafeCollection<T>
|
||||
|
||||
fixed (T* ptr = values)
|
||||
{
|
||||
MemCpy(UnsafeUtility.ReadArrayElementUnsafe<T>(_array.GetUnsafePtr(), _count), ptr, (uint)(values.Length * sizeof(T)));
|
||||
MemoryUtility.MemCpy(UnsafeUtility.ReadArrayElementUnsafe<T>(_array.GetUnsafePtr(), _count), ptr, (uint)(values.Length * sizeof(T)));
|
||||
}
|
||||
|
||||
_count += values.Length;
|
||||
@@ -361,7 +361,7 @@ public unsafe struct UnsafeList<T> : IUnsafeCollection<T>
|
||||
Resize(Capacity + count);
|
||||
}
|
||||
|
||||
MemCpy(UnsafeUtility.ReadArrayElementUnsafe<T>(_array.GetUnsafePtr(), _count), ptr, (uint)(count * sizeof(T)));
|
||||
MemoryUtility.MemCpy(UnsafeUtility.ReadArrayElementUnsafe<T>(_array.GetUnsafePtr(), _count), ptr, (uint)(count * sizeof(T)));
|
||||
_count += count;
|
||||
}
|
||||
|
||||
@@ -375,7 +375,7 @@ public unsafe struct UnsafeList<T> : IUnsafeCollection<T>
|
||||
|
||||
fixed (T* pCollection = collection)
|
||||
{
|
||||
MemCpy(UnsafeUtility.ReadArrayElementUnsafe<T>(_array.GetUnsafePtr(), _count), pCollection, (uint)(collection.Length * sizeof(T)));
|
||||
MemoryUtility.MemCpy(UnsafeUtility.ReadArrayElementUnsafe<T>(_array.GetUnsafePtr(), _count), pCollection, (uint)(collection.Length * sizeof(T)));
|
||||
}
|
||||
|
||||
_count += collection.Length;
|
||||
@@ -390,7 +390,7 @@ public unsafe struct UnsafeList<T> : IUnsafeCollection<T>
|
||||
{
|
||||
CheckNoResizeCapacity(count);
|
||||
|
||||
MemCpy(UnsafeUtility.ReadArrayElementUnsafe<T>(_array.GetUnsafePtr(), _count), ptr, (uint)(count * sizeof(T)));
|
||||
MemoryUtility.MemCpy(UnsafeUtility.ReadArrayElementUnsafe<T>(_array.GetUnsafePtr(), _count), ptr, (uint)(count * sizeof(T)));
|
||||
_count += count;
|
||||
}
|
||||
|
||||
@@ -409,7 +409,7 @@ public unsafe struct UnsafeList<T> : IUnsafeCollection<T>
|
||||
}
|
||||
|
||||
var copyFrom = Math.Min(start + length, _count);
|
||||
MemCpy(UnsafeUtility.ReadArrayElementUnsafe<T>(_array.GetUnsafePtr(), start),
|
||||
MemoryUtility.MemCpy(UnsafeUtility.ReadArrayElementUnsafe<T>(_array.GetUnsafePtr(), start),
|
||||
UnsafeUtility.ReadArrayElementUnsafe<T>(_array.GetUnsafePtr(), copyFrom),
|
||||
(uint)((_count - copyFrom) * sizeof(T))
|
||||
);
|
||||
@@ -444,7 +444,7 @@ public unsafe struct UnsafeList<T> : IUnsafeCollection<T>
|
||||
|
||||
if (numToCopy > 0)
|
||||
{
|
||||
MemCpy(UnsafeUtility.ReadArrayElementUnsafe<T>(_array.GetUnsafePtr(), start),
|
||||
MemoryUtility.MemCpy(UnsafeUtility.ReadArrayElementUnsafe<T>(_array.GetUnsafePtr(), start),
|
||||
UnsafeUtility.ReadArrayElementUnsafe<T>(_array.GetUnsafePtr(), copyFrom),
|
||||
(uint)((_count - copyFrom) * sizeof(T)));
|
||||
}
|
||||
@@ -519,7 +519,7 @@ public unsafe struct UnsafeList<T> : IUnsafeCollection<T>
|
||||
var size = Math.Min(destination.Length, Count);
|
||||
fixed (T* pDest = destination)
|
||||
{
|
||||
MemCpy(pDest, _array.GetUnsafePtr(), (uint)(size * sizeof(T)));
|
||||
MemoryUtility.MemCpy(pDest, _array.GetUnsafePtr(), (uint)(size * sizeof(T)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -540,7 +540,7 @@ public unsafe struct UnsafeList<T> : IUnsafeCollection<T>
|
||||
|
||||
fixed (T* pDest = destination)
|
||||
{
|
||||
MemCpy(pDest + destinationIndex, (byte*)_array.GetUnsafePtr() + sourceIndex * sizeof(T), (nuint)(length * sizeof(T)));
|
||||
MemoryUtility.MemCpy(pDest + destinationIndex, (byte*)_array.GetUnsafePtr() + sourceIndex * sizeof(T), (nuint)(length * sizeof(T)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -557,7 +557,7 @@ public unsafe struct UnsafeList<T> : IUnsafeCollection<T>
|
||||
|
||||
fixed (T* pSrc = source)
|
||||
{
|
||||
MemCpy(_array.GetUnsafePtr(), pSrc, (nuint)(source.Length * sizeof(T)));
|
||||
MemoryUtility.MemCpy(_array.GetUnsafePtr(), pSrc, (nuint)(source.Length * sizeof(T)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -583,7 +583,7 @@ public unsafe struct UnsafeList<T> : IUnsafeCollection<T>
|
||||
|
||||
fixed (T* pSrc = source)
|
||||
{
|
||||
MemCpy((byte*)_array.GetUnsafePtr() + destinationIndex * sizeof(T), pSrc + sourceIndex, (nuint)(length * sizeof(T)));
|
||||
MemoryUtility.MemCpy((byte*)_array.GetUnsafePtr() + destinationIndex * sizeof(T), pSrc + sourceIndex, (nuint)(length * sizeof(T)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ public unsafe struct UnsafeMultiHashMap<TKey, TValue> : IUnsafeHashCollection<Ke
|
||||
|
||||
public UnsafeMultiHashMap(int capacity, AllocationHandle handle, AllocationOption allocationOption = AllocationOption.None)
|
||||
{
|
||||
_helper = new HashMapHelper<TKey>(capacity, sizeof(TValue), (int)AlignOf<TValue>(), HashMapHelper<TKey>.MINIMAL_CAPACITY, handle, allocationOption);
|
||||
_helper = new HashMapHelper<TKey>(capacity, sizeof(TValue), (int)MemoryUtility.AlignOf<TValue>(), HashMapHelper<TKey>.MINIMAL_CAPACITY, handle, allocationOption);
|
||||
}
|
||||
|
||||
[Obsolete("Use AllocationHandle instead.")]
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Misaki.HighPerformance.LowLevel.Buffer;
|
||||
using Misaki.HighPerformance.LowLevel.Utilities;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
@@ -88,7 +89,7 @@ public unsafe struct UnsafeParallelQueue<T> : IDisposable
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static DisposablePtr<UnsafeParallelQueue<T>> Allocate(int capacityPerChunk, AllocationHandle handle, AllocationOption allocationOption = AllocationOption.None)
|
||||
{
|
||||
var pQueue = (UnsafeParallelQueue<T>*)handle.Alloc(SizeOf<DisposablePtr<UnsafeParallelQueue<T>>>(), AlignOf<DisposablePtr<UnsafeParallelQueue<T>>>(), AllocationOption.None);
|
||||
var pQueue = (UnsafeParallelQueue<T>*)handle.Alloc(MemoryUtility.SizeOf<DisposablePtr<UnsafeParallelQueue<T>>>(), MemoryUtility.AlignOf<DisposablePtr<UnsafeParallelQueue<T>>>(), AllocationOption.None);
|
||||
*pQueue = new UnsafeParallelQueue<T>(capacityPerChunk, handle, allocationOption);
|
||||
return new DisposablePtr<UnsafeParallelQueue<T>>(pQueue);
|
||||
}
|
||||
@@ -278,7 +279,7 @@ public unsafe struct UnsafeParallelQueue<T> : IDisposable
|
||||
free->consumedSlots = 0;
|
||||
|
||||
var slots = (ChunkSlot*)(free + 1);
|
||||
MemClear(slots, (uint)(_chunkCapacity * sizeof(ChunkSlot)));
|
||||
MemoryUtility.MemClear(slots, (uint)(_chunkCapacity * sizeof(ChunkSlot)));
|
||||
return free;
|
||||
}
|
||||
}
|
||||
@@ -289,7 +290,7 @@ public unsafe struct UnsafeParallelQueue<T> : IDisposable
|
||||
private readonly ChunkHeader* AllocateNewChunk()
|
||||
{
|
||||
nuint byteSize = (nuint)sizeof(ChunkHeader) + (nuint)(_chunkCapacity * sizeof(ChunkSlot));
|
||||
ChunkHeader* block = (ChunkHeader*)_allocHandle.Alloc(byteSize, AlignOf<int>(), _allocOption);
|
||||
ChunkHeader* block = (ChunkHeader*)_allocHandle.Alloc(byteSize, MemoryUtility.AlignOf<int>(), _allocOption);
|
||||
|
||||
block->next = null;
|
||||
block->nextFree = null;
|
||||
@@ -299,7 +300,7 @@ public unsafe struct UnsafeParallelQueue<T> : IDisposable
|
||||
block->consumedSlots = 0;
|
||||
|
||||
var slots = (ChunkSlot*)(block + 1);
|
||||
MemClear(slots, (uint)(_chunkCapacity * sizeof(ChunkSlot)));
|
||||
MemoryUtility.MemClear(slots, (uint)(_chunkCapacity * sizeof(ChunkSlot)));
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
@@ -184,7 +184,7 @@ public unsafe struct UnsafeQueue<T> : IUnsafeCollection<T>
|
||||
{
|
||||
// No wrap-around, single copy
|
||||
var sizeToCopy = (uint)(_count * sizeof(T));
|
||||
MemCpy(newArray.GetUnsafePtr(), (byte*)_array.GetUnsafePtr() + _offset * sizeof(T), sizeToCopy);
|
||||
MemoryUtility.MemCpy(newArray.GetUnsafePtr(), (byte*)_array.GetUnsafePtr() + _offset * sizeof(T), sizeToCopy);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -193,10 +193,10 @@ public unsafe struct UnsafeQueue<T> : IUnsafeCollection<T>
|
||||
var secondPartElements = _count - firstPartElements;
|
||||
|
||||
// Copy from _offset to the end of the old array
|
||||
MemCpy(newArray.GetUnsafePtr(), (byte*)_array.GetUnsafePtr() + _offset * sizeof(T), (uint)(firstPartElements * sizeof(T)));
|
||||
MemoryUtility.MemCpy(newArray.GetUnsafePtr(), (byte*)_array.GetUnsafePtr() + _offset * sizeof(T), (uint)(firstPartElements * sizeof(T)));
|
||||
|
||||
// Copy from the start of the old array to the remaining count
|
||||
MemCpy((byte*)newArray.GetUnsafePtr() + firstPartElements * sizeof(T), _array.GetUnsafePtr(), (uint)(secondPartElements * sizeof(T)));
|
||||
MemoryUtility.MemCpy((byte*)newArray.GetUnsafePtr() + firstPartElements * sizeof(T), _array.GetUnsafePtr(), (uint)(secondPartElements * sizeof(T)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user