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:
2026-05-07 21:34:25 +09:00
parent f8b11182a9
commit d2c165bbe5
21 changed files with 382 additions and 111 deletions

View File

@@ -1,6 +1,7 @@
#if MHP_ENABLE_SAFETY_CHECKS
using Misaki.HighPerformance.Collections;
#endif
using Misaki.HighPerformance.LowLevel.Utilities;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@@ -101,7 +102,7 @@ public static unsafe class AllocationManager
private static void* Allocate(void* _, nuint size, nuint alignment, AllocationOption allocationOption)
{
var ptr = AlignedAlloc(size, alignment);
var ptr = MemoryUtility.AlignedAlloc(size, alignment);
if (ptr == null)
{
return null;
@@ -109,7 +110,7 @@ public static unsafe class AllocationManager
if (allocationOption.HasOption(AllocationOption.Clear))
{
MemClear(ptr, size);
MemoryUtility.MemClear(ptr, size);
}
return ptr;
@@ -117,7 +118,7 @@ public static unsafe class AllocationManager
private static void* Reallocate(void* _, void* ptr, nuint oldSize, nuint newSize, nuint alignment, AllocationOption allocationOption)
{
var newPtr = AlignedRealloc(ptr, newSize, alignment);
var newPtr = MemoryUtility.AlignedRealloc(ptr, newSize, alignment);
if (newPtr == null)
{
return null;
@@ -127,7 +128,7 @@ public static unsafe class AllocationManager
{
var offset = (byte*)newPtr + oldSize;
var clearSize = newSize - oldSize;
MemClear(offset, clearSize);
MemoryUtility.MemClear(offset, clearSize);
}
return newPtr;
@@ -135,7 +136,7 @@ public static unsafe class AllocationManager
private static void Free(void* _, void* ptr)
{
AlignedFree(ptr);
MemoryUtility.AlignedFree(ptr);
}
}
@@ -264,7 +265,7 @@ public static unsafe class AllocationManager
var spanDesc = MemoryMarshal.AsBytes(MemoryMarshal.CreateSpan(ref desc, 1));
var spanDefault = MemoryMarshal.AsBytes(MemoryMarshal.CreateSpan(ref defaultDesc, 1));
ReplaceIfZeros(spanDesc, spanDefault);
MemoryUtility.ReplaceIfZeros(spanDesc, spanDefault);
s_arenaAllocator = new MemoryPool<VirtualArena, VirtualArena.CreationOptions>(new VirtualArena.CreationOptions
{
@@ -277,10 +278,10 @@ public static unsafe class AllocationManager
chunkSize = desc.FreeListChunkSize
});
s_pHeapAllocator = (HeapAllocator*)Malloc((nuint)sizeof(HeapAllocator));
s_pHeapAllocator = (HeapAllocator*)NativeMemory.Alloc((nuint)sizeof(HeapAllocator));
s_pHeapAllocator->Init();
s_pTLSFAllocator = (TLSFAllocator*)Malloc((nuint)sizeof(TLSFAllocator));
s_pTLSFAllocator = (TLSFAllocator*)NativeMemory.Alloc((nuint)sizeof(TLSFAllocator));
s_pTLSFAllocator->Init(desc.TLSFAlignment, desc.TLSFInitialChunkSize);
s_threadLocalStackSize = desc.StackCapacity;
@@ -487,14 +488,14 @@ public static unsafe class AllocationManager
if (s_pHeapAllocator != null)
{
Free(s_pHeapAllocator);
NativeMemory.Free(s_pHeapAllocator);
s_pHeapAllocator = null;
}
if (s_pTLSFAllocator != null)
{
s_pTLSFAllocator->Dispose();
Free(s_pTLSFAllocator);
NativeMemory.Free(s_pTLSFAllocator);
s_pTLSFAllocator = null;
}
}

View File

@@ -40,7 +40,7 @@ public unsafe struct Arena : IMemoryAllocator<Arena, Arena.CreationOptions>
return;
}
_buffer = (byte*)Malloc(size);
_buffer = (byte*)NativeMemory.Alloc(size);
_size = size;
_offset = 0;
}
@@ -91,7 +91,7 @@ public unsafe struct Arena : IMemoryAllocator<Arena, Arena.CreationOptions>
var ptr = _buffer + alignedOffset;
if (allocationOption.HasOption(AllocationOption.Clear))
{
MemClear(ptr, size);
MemoryUtility.MemClear(ptr, size);
}
return ptr;
@@ -120,7 +120,7 @@ public unsafe struct Arena : IMemoryAllocator<Arena, Arena.CreationOptions>
{
if (allocationOption.HasOption(AllocationOption.Clear) && additionalSize > 0)
{
MemClear((byte*)ptr + oldSize, additionalSize);
MemoryUtility.MemClear((byte*)ptr + oldSize, additionalSize);
}
return ptr;
@@ -134,7 +134,7 @@ public unsafe struct Arena : IMemoryAllocator<Arena, Arena.CreationOptions>
return null;
}
MemCpy(newPtr, ptr, Math.Min(oldSize, newSize));
MemoryUtility.MemCpy(newPtr, ptr, Math.Min(oldSize, newSize));
return newPtr;
}
@@ -165,6 +165,6 @@ public unsafe struct Arena : IMemoryAllocator<Arena, Arena.CreationOptions>
_size = 0;
_offset = 0;
MemoryUtility.Free(ptr);
NativeMemory.Free(ptr);
}
}

View File

@@ -44,7 +44,7 @@ public unsafe struct DynamicArena : IMemoryAllocator<DynamicArena, DynamicArena.
public DynamicArena(nuint initialSize)
{
_initialSize = initialSize;
_root = (ArenaNode*)Malloc(SizeOf<ArenaNode>());
_root = (ArenaNode*)NativeMemory.Alloc((nuint)sizeof(ArenaNode));
_root->arena = new Arena(initialSize);
_root->next = null;
_current = _root;
@@ -70,7 +70,7 @@ public unsafe struct DynamicArena : IMemoryAllocator<DynamicArena, DynamicArena.
return true;
}
var newNode = (ArenaNode*)Malloc(SizeOf<ArenaNode>());
var newNode = (ArenaNode*)NativeMemory.Alloc((nuint)sizeof(ArenaNode));
try
{
newNode->arena = new Arena(size);
@@ -85,7 +85,7 @@ public unsafe struct DynamicArena : IMemoryAllocator<DynamicArena, DynamicArena.
}
catch
{
Free(newNode);
NativeMemory.Free(newNode);
return false;
}
}
@@ -151,7 +151,7 @@ public unsafe struct DynamicArena : IMemoryAllocator<DynamicArena, DynamicArena.
if (newPtr != ptr)
{
MemCpy(newPtr, ptr, Math.Min(oldSize, newSize));
MemoryUtility.MemCpy(newPtr, ptr, Math.Min(oldSize, newSize));
}
return newPtr;
@@ -194,7 +194,7 @@ public unsafe struct DynamicArena : IMemoryAllocator<DynamicArena, DynamicArena.
{
var next = current->next;
current->arena.Dispose();
MemoryUtility.Free(current);
NativeMemory.Free(current);
current = next;
}
}

View File

@@ -93,6 +93,10 @@ public unsafe struct FreeList : IMemoryAllocator<FreeList, FreeList.CreationOpti
public int isDisposed;
public ThreadCache* headCache;
public ThreadCache* inactiveCacheHead;
// nint is not allowed in fixed buffer, use long instead for 64-bit/32-bit pointers
public fixed long globalFreeBuckets[_MAX_BUCKETS];
public fixed int globalFreeLocks[_MAX_BUCKETS];
}
private class CacheReclaimer
@@ -123,6 +127,7 @@ public unsafe struct FreeList : IMemoryAllocator<FreeList, FreeList.CreationOpti
}
private const byte _MAX_BUCKETS = 16;
private const int _MAX_CACHED_BLOCKS_PER_BUCKET = 256;
private const int _DEFAULT_MAX_CONCURRENCY_LEVEL = 1;
private const int _OVERFLOW_CACHE_INDEX = 0;
private const nuint _MIN_BLOCK_SIZE = 32;
@@ -179,11 +184,17 @@ public unsafe struct FreeList : IMemoryAllocator<FreeList, FreeList.CreationOpti
try
{
var state = (SharedState*)Malloc((nuint)sizeof(SharedState));
var state = (SharedState*)NativeMemory.Alloc((nuint)sizeof(SharedState));
state->isDisposed = 0;
state->headCache = null;
state->inactiveCacheHead = null;
for (var i = 0; i < _MAX_BUCKETS; i++)
{
state->globalFreeBuckets[i] = 0;
state->globalFreeLocks[i] = 0;
}
_instanceId = state;
_chunks = null;
@@ -196,7 +207,7 @@ public unsafe struct FreeList : IMemoryAllocator<FreeList, FreeList.CreationOpti
{
if (_instanceId != null)
{
MemoryUtility.Free(_instanceId);
NativeMemory.Free(_instanceId);
_instanceId = null;
}
@@ -250,7 +261,7 @@ public unsafe struct FreeList : IMemoryAllocator<FreeList, FreeList.CreationOpti
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private ThreadCache* CreateCacheForThread(int threadId)
{
var cache = (ThreadCache*)_chunkArena.Allocate(SizeOf<ThreadCache>(), AlignOf<ThreadCache>(), AllocationOption.Clear);
var cache = (ThreadCache*)_chunkArena.Allocate(MemoryUtility.SizeOf<ThreadCache>(), MemoryUtility.AlignOf<ThreadCache>(), AllocationOption.Clear);
if (cache == null)
{
return null;
@@ -279,6 +290,92 @@ public unsafe struct FreeList : IMemoryAllocator<FreeList, FreeList.CreationOpti
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private readonly void* TryPopFromGlobalQueue(byte bucketIndex, ThreadCache* cache, nuint alignment)
{
var state = (SharedState*)_instanceId;
FreeNode* node = null;
var spinWait = new SpinWait();
while (Interlocked.CompareExchange(ref state->globalFreeLocks[bucketIndex], 1, 0) != 0)
{
spinWait.SpinOnce();
}
try
{
var globalHead = state->globalFreeBuckets[bucketIndex];
if (globalHead != 0)
{
node = (FreeNode*)(nint)globalHead;
state->globalFreeBuckets[bucketIndex] = (long)(nint)node->next;
}
}
finally
{
Volatile.Write(ref state->globalFreeLocks[bucketIndex], 0);
}
if (node == null)
{
return null;
}
var userPtr = (byte*)(((nuint)node + (nuint)sizeof(BlockHeader) + alignment - 1) & ~(alignment - 1));
var header = (BlockHeader*)userPtr - 1;
AssignBlockHeader(header, node, node->ownerChunk, bucketIndex, cache);
return userPtr;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private readonly void* TryScavengeFromSleepingThreads(byte bucketIndex, ThreadCache* currentCache, nuint alignment)
{
var state = (SharedState*)_instanceId;
var cacheToScavenge = state->headCache;
while (cacheToScavenge != null)
{
if (cacheToScavenge != currentCache && Volatile.Read(ref cacheToScavenge->remoteFreeHead) != 0)
{
var stolenHead = (FreeNode*)Interlocked.Exchange(ref cacheToScavenge->remoteFreeHead, 0);
if (stolenHead != null)
{
// Push all stolen blocks except one to the current cache
var node = stolenHead;
void* result = null;
while (node != null)
{
var next = node->next;
if (node->bucketIndex == bucketIndex && result == null)
{
var userPtr = (byte*)(((nuint)node + (nuint)sizeof(BlockHeader) + alignment - 1) & ~(alignment - 1));
var header = (BlockHeader*)userPtr - 1;
AssignBlockHeader(header, node, node->ownerChunk, bucketIndex, currentCache);
result = userPtr;
}
else
{
PushToBucket(currentCache, node->bucketIndex, node, node->ownerChunk);
}
node = next;
}
if (result != null)
{
return result;
}
}
}
cacheToScavenge = cacheToScavenge->next;
}
return null; // Return null specifically if scavenging didn't produce the desired block size.
}
private ThreadCache* RegisterThreadCache()
{
if (_instanceId == null || _disposed != 0)
@@ -387,6 +484,29 @@ public unsafe struct FreeList : IMemoryAllocator<FreeList, FreeList.CreationOpti
var node = (FreeNode*)ptr;
node->ownerChunk = ownerChunk;
node->bucketIndex = bucketIndex;
if (bucket->freeCount >= _MAX_CACHED_BLOCKS_PER_BUCKET)
{
var state = (SharedState*)_instanceId;
var spinWait = new SpinWait();
while (Interlocked.CompareExchange(ref state->globalFreeLocks[bucketIndex], 1, 0) != 0)
{
spinWait.SpinOnce();
}
try
{
var globalHead = state->globalFreeBuckets[bucketIndex];
node->next = (FreeNode*)(nint)globalHead;
state->globalFreeBuckets[bucketIndex] = (long)(nint)node;
}
finally
{
Volatile.Write(ref state->globalFreeLocks[bucketIndex], 0);
}
return;
}
node->next = (FreeNode*)bucket->freeHead;
bucket->freeHead = (nint)node;
bucket->freeCount++;
@@ -479,14 +599,14 @@ public unsafe struct FreeList : IMemoryAllocator<FreeList, FreeList.CreationOpti
}
var newChunkSize = Math.Max(_chunkSize, size); // 默认保底 64KB
var newMemory = (byte*)AlignedAlloc(newChunkSize, alignment);
var newMemory = (byte*)NativeMemory.AlignedAlloc(newChunkSize, alignment);
if (newMemory == null)
{
ownerChunk = null;
return null;
}
var newChunk = (MemoryChunk*)_chunkArena.Allocate(SizeOf<MemoryChunk>(), AlignOf<MemoryChunk>(), AllocationOption.None);
var newChunk = (MemoryChunk*)_chunkArena.Allocate(MemoryUtility.SizeOf<MemoryChunk>(), MemoryUtility.AlignOf<MemoryChunk>(), AllocationOption.None);
newChunk->memory = newMemory;
newChunk->size = newChunkSize;
newChunk->used = size;
@@ -544,18 +664,28 @@ public unsafe struct FreeList : IMemoryAllocator<FreeList, FreeList.CreationOpti
if (userPtr == null)
{
DrainRemoteFrees(cache);
userPtr = TryPopFromBucket(cache, bucketIndex, alignment);
if (userPtr == null && TryCreateBlocksForBucket(cache, bucketIndex))
if (userPtr == null)
{
userPtr = TryPopFromBucket(cache, bucketIndex, alignment);
userPtr = TryPopFromGlobalQueue(bucketIndex, cache, alignment);
if (userPtr == null)
{
userPtr = TryScavengeFromSleepingThreads(bucketIndex, cache, alignment);
if (userPtr == null && TryCreateBlocksForBucket(cache, bucketIndex))
{
userPtr = TryPopFromBucket(cache, bucketIndex, alignment);
}
}
}
}
}
else
{
// Oversized block: Bypass chunk linking entirely and go straight to the OS
void* ptr = AlignedAlloc(totalSize, alignment);
var ptr = NativeMemory.AlignedAlloc(totalSize, alignment);
if (ptr != null)
{
userPtr = (byte*)(((nuint)ptr + (nuint)sizeof(BlockHeader) + alignment - 1) & ~(alignment - 1));
@@ -572,7 +702,7 @@ public unsafe struct FreeList : IMemoryAllocator<FreeList, FreeList.CreationOpti
if (allocationOption.HasOption(AllocationOption.Clear))
{
MemClear(userPtr, alignedSize);
MemoryUtility.MemClear(userPtr, alignedSize);
}
return userPtr;
@@ -594,7 +724,7 @@ public unsafe struct FreeList : IMemoryAllocator<FreeList, FreeList.CreationOpti
if (newPtr != null && ptr != null)
{
var copySize = Math.Min(oldSize, newSize);
MemCpy(newPtr, ptr, copySize);
MemoryUtility.MemCpy(newPtr, ptr, copySize);
Free(ptr);
}
@@ -630,7 +760,7 @@ public unsafe struct FreeList : IMemoryAllocator<FreeList, FreeList.CreationOpti
// This is an oversized allocation. It doesn't belong to a bucket or a chunk.
// Erase the magic number for safety and instantly yield it back to the OS.
header->magicNumber = 0;
AlignedFree(blockStartPtr);
NativeMemory.AlignedFree(blockStartPtr);
return;
}
@@ -679,7 +809,7 @@ public unsafe struct FreeList : IMemoryAllocator<FreeList, FreeList.CreationOpti
current = current->next;
}
MemoryUtility.Free(_instanceId);
NativeMemory.Free(_instanceId);
_instanceId = null;
}
@@ -690,7 +820,7 @@ public unsafe struct FreeList : IMemoryAllocator<FreeList, FreeList.CreationOpti
while (chunk != null)
{
var next = chunk->next;
AlignedFree(chunk->memory);
NativeMemory.AlignedFree(chunk->memory);
chunk = next;
}

View File

@@ -114,7 +114,7 @@ public unsafe struct MemoryBlock : IDisposable
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly void Clear()
{
MemClear(_buffer, _size);
MemoryUtility.MemClear(_buffer, _size);
}
/// <inheritdoc/>
@@ -141,7 +141,7 @@ public unsafe struct MemoryBlock : IDisposable
fixed (T* pDest = destination)
{
MemCpy(pDest, _buffer, _size);
MemoryUtility.MemCpy(pDest, _buffer, _size);
}
}
@@ -165,7 +165,7 @@ public unsafe struct MemoryBlock : IDisposable
fixed (T* pDest = destination)
{
MemCpy(pDest + destinationIndex, (byte*)_buffer + sourceOffset, length * sizeOfElement);
MemoryUtility.MemCpy(pDest + destinationIndex, (byte*)_buffer + sourceOffset, length * sizeOfElement);
}
}
@@ -187,7 +187,7 @@ public unsafe struct MemoryBlock : IDisposable
fixed (T* pSrc = source)
{
MemCpy(_buffer, pSrc, sourceSize);
MemoryUtility.MemCpy(_buffer, pSrc, sourceSize);
}
}
@@ -211,7 +211,7 @@ public unsafe struct MemoryBlock : IDisposable
fixed (T* pSrc = source)
{
MemCpy((byte*)_buffer + destinationOffset, pSrc + sourceIndex, length * sizeOfElement);
MemoryUtility.MemCpy((byte*)_buffer + destinationOffset, pSrc + sourceIndex, length * sizeOfElement);
}
}

View File

@@ -1,5 +1,6 @@
using Misaki.HighPerformance.LowLevel.Utilities;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Misaki.HighPerformance.LowLevel.Buffer;
@@ -16,7 +17,7 @@ public unsafe struct MemoryPool<TAllocator, TOpts> : IDisposable
{
var allocator = TAllocator.Create(opts);
_pAllocator = (TAllocator*)Malloc((nuint)sizeof(TAllocator));
_pAllocator = (TAllocator*)NativeMemory.Alloc((nuint)sizeof(TAllocator));
*_pAllocator = allocator;
_allocationHandle = new AllocationHandle(_pAllocator, &Allocate, &Reallocate, &Free);
@@ -46,7 +47,7 @@ public unsafe struct MemoryPool<TAllocator, TOpts> : IDisposable
_pAllocator->Dispose();
MemoryUtility.Free(_pAllocator);
NativeMemory.Free(_pAllocator);
_pAllocator = null;
_allocationHandle = default;

View File

@@ -1,5 +1,6 @@
using Misaki.HighPerformance.LowLevel.Utilities;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Misaki.HighPerformance.LowLevel.Buffer;
@@ -60,7 +61,7 @@ public unsafe partial struct Stack : IMemoryAllocator<Stack, Stack.CreationOptio
{
ArgumentOutOfRangeException.ThrowIfNegative(size);
_buffer = (byte*)Malloc(size);
_buffer = (byte*)NativeMemory.Alloc(size);
_size = size;
_offset = 0;
}
@@ -113,7 +114,7 @@ public unsafe partial struct Stack : IMemoryAllocator<Stack, Stack.CreationOptio
if (allocationOption.HasOption(AllocationOption.Clear))
{
MemClear(ptr, size);
MemoryUtility.MemClear(ptr, size);
}
return ptr;
@@ -140,7 +141,7 @@ public unsafe partial struct Stack : IMemoryAllocator<Stack, Stack.CreationOptio
_offset += diff;
if (allocationOption.HasOption(AllocationOption.Clear))
{
MemClear(_buffer + _offset - diff, diff);
MemoryUtility.MemClear(_buffer + _offset - diff, diff);
}
}
@@ -153,7 +154,7 @@ public unsafe partial struct Stack : IMemoryAllocator<Stack, Stack.CreationOptio
return null;
}
MemCpy(newPtr, ptr, Math.Min(oldSize, newSize));
MemoryUtility.MemCpy(newPtr, ptr, Math.Min(oldSize, newSize));
return newPtr;
}
@@ -184,6 +185,6 @@ public unsafe partial struct Stack : IMemoryAllocator<Stack, Stack.CreationOptio
_offset = 0;
_size = 0;
MemoryUtility.Free(ptr);
NativeMemory.Free(ptr);
}
}

View File

@@ -113,8 +113,8 @@ public unsafe struct TLSF : IMemoryAllocator<TLSF, TLSF.CreationOptions>
var slSize = 64 * (nuint)sizeof(uint);
var blocksSize = 64 * 32 * (nuint)sizeof(BlockHeader*);
_slBitmaps = (uint*)Calloc(slSize);
_blocks = (BlockHeader**)Calloc(blocksSize);
_slBitmaps = (uint*)NativeMemory.AllocZeroed(slSize);
_blocks = (BlockHeader**)NativeMemory.AllocZeroed(blocksSize);
AddChunk(_chunkSize);
}
@@ -140,7 +140,7 @@ public unsafe struct TLSF : IMemoryAllocator<TLSF, TLSF.CreationOptions>
private void AddChunk(nuint size)
{
var totalSize = size + (nuint)sizeof(MemoryChunk);
var mem = (byte*)AlignedAlloc(totalSize, _alignment);
var mem = (byte*)NativeMemory.AlignedAlloc(totalSize, _alignment);
MemoryChunk* chunk = (MemoryChunk*)mem;
chunk->next = _chunks;
@@ -313,7 +313,7 @@ public unsafe struct TLSF : IMemoryAllocator<TLSF, TLSF.CreationOptions>
void* userPtr = (byte*)block + 16;
if (allocationOption.HasOption(AllocationOption.Clear))
{
MemClear(userPtr, block->Size - 16);
MemoryUtility.MemClear(userPtr, block->Size - 16);
}
return userPtr;
@@ -458,7 +458,7 @@ public unsafe struct TLSF : IMemoryAllocator<TLSF, TLSF.CreationOptions>
if (newPtr != null)
{
var copySize = oldSize < newSize ? oldSize : newSize;
MemCpy(newPtr, ptr, copySize);
MemoryUtility.MemCpy(newPtr, ptr, copySize);
Free(ptr);
}
return newPtr;
@@ -468,13 +468,13 @@ public unsafe struct TLSF : IMemoryAllocator<TLSF, TLSF.CreationOptions>
{
if (_blocks != null)
{
MemoryUtility.Free(_blocks);
NativeMemory.Free(_blocks);
_blocks = null;
}
if (_slBitmaps != null)
{
MemoryUtility.Free(_slBitmaps);
NativeMemory.Free(_slBitmaps);
_slBitmaps = null;
}
@@ -484,7 +484,7 @@ public unsafe struct TLSF : IMemoryAllocator<TLSF, TLSF.CreationOptions>
while (chunk != null)
{
MemoryChunk* next = chunk->next;
AlignedFree(chunk->memory);
NativeMemory.AlignedFree(chunk->memory);
chunk = next;
}
}

View File

@@ -38,7 +38,7 @@ public unsafe struct VirtualArena : IMemoryAllocator<VirtualArena, VirtualArena.
_committedSize = 0;
_allocatedOffset = 0;
_baseAddress = (byte*)Mmap(null, _reserveCapacity, VirtualAllocationFlags.Reserve);
_baseAddress = (byte*)MemoryUtility.Mmap(null, _reserveCapacity, VirtualAllocationFlags.Reserve);
if (_baseAddress == null)
{
@@ -87,7 +87,7 @@ public unsafe struct VirtualArena : IMemoryAllocator<VirtualArena, VirtualArena.
if (allocationOption.HasOption(AllocationOption.Clear))
{
MemClear(ptr, size);
MemoryUtility.MemClear(ptr, size);
}
return ptr;
@@ -113,7 +113,7 @@ public unsafe struct VirtualArena : IMemoryAllocator<VirtualArena, VirtualArena.
sizeToCommit = (sizeToCommit + _PAGE_SIZE - 1) & ~(_PAGE_SIZE - 1);
var commitAddress = _baseAddress + currentCommitted;
var result = Mmap(commitAddress, sizeToCommit, VirtualAllocationFlags.Commit);
var result = MemoryUtility.Mmap(commitAddress, sizeToCommit, VirtualAllocationFlags.Commit);
if (result == null)
{
@@ -177,7 +177,7 @@ public unsafe struct VirtualArena : IMemoryAllocator<VirtualArena, VirtualArena.
sizeToCommit = (sizeToCommit + _PAGE_SIZE - 1) & ~(_PAGE_SIZE - 1);
var commitAddress = _baseAddress + currentCommitted;
var result = Mmap(commitAddress, sizeToCommit, VirtualAllocationFlags.Commit);
var result = MemoryUtility.Mmap(commitAddress, sizeToCommit, VirtualAllocationFlags.Commit);
if (result == null)
{
@@ -199,7 +199,7 @@ public unsafe struct VirtualArena : IMemoryAllocator<VirtualArena, VirtualArena.
// Safe to clear: we own the space between oldSize and newOffset
if (allocationOption.HasOption(AllocationOption.Clear) && additionalSize > 0)
{
MemClear((byte*)ptr + oldSize, additionalSize);
MemoryUtility.MemClear((byte*)ptr + oldSize, additionalSize);
}
return ptr;
@@ -212,7 +212,7 @@ public unsafe struct VirtualArena : IMemoryAllocator<VirtualArena, VirtualArena.
return null;
}
MemCpy(newPtr, ptr, oldSize);
MemoryUtility.MemCpy(newPtr, ptr, oldSize);
return newPtr;
}
@@ -244,6 +244,6 @@ public unsafe struct VirtualArena : IMemoryAllocator<VirtualArena, VirtualArena.
_committedSize = 0;
_reserveCapacity = 0;
Munmap(ptr, _reserveCapacity);
MemoryUtility.Munmap(ptr, _reserveCapacity);
}
}

View File

@@ -58,7 +58,7 @@ public unsafe struct VirtualStack : IMemoryAllocator<VirtualStack, VirtualStack.
_committedSize = 0;
_allocatedOffset = 0;
_baseAddress = (byte*)Mmap(null, _reserveCapacity, VirtualAllocationFlags.Reserve);
_baseAddress = (byte*)MemoryUtility.Mmap(null, _reserveCapacity, VirtualAllocationFlags.Reserve);
}
/// <summary>
@@ -115,7 +115,7 @@ public unsafe struct VirtualStack : IMemoryAllocator<VirtualStack, VirtualStack.
sizeToCommit = (sizeToCommit + _PAGE_SIZE - 1) & ~(_PAGE_SIZE - 1);
var commitAddress = _baseAddress + _committedSize;
var result = Mmap(commitAddress, sizeToCommit, VirtualAllocationFlags.Commit);
var result = MemoryUtility.Mmap(commitAddress, sizeToCommit, VirtualAllocationFlags.Commit);
if (result == null)
{
@@ -130,7 +130,7 @@ public unsafe struct VirtualStack : IMemoryAllocator<VirtualStack, VirtualStack.
if (option.HasOption(AllocationOption.Clear))
{
MemClear(userPtr, size);
MemoryUtility.MemClear(userPtr, size);
}
return userPtr;
@@ -166,7 +166,7 @@ public unsafe struct VirtualStack : IMemoryAllocator<VirtualStack, VirtualStack.
sizeToCommit = (sizeToCommit + _PAGE_SIZE - 1) & ~(_PAGE_SIZE - 1);
var commitAddress = _baseAddress + _committedSize;
var result = Mmap(commitAddress, sizeToCommit, VirtualAllocationFlags.Commit);
var result = MemoryUtility.Mmap(commitAddress, sizeToCommit, VirtualAllocationFlags.Commit);
if (result == null)
{
@@ -178,7 +178,7 @@ public unsafe struct VirtualStack : IMemoryAllocator<VirtualStack, VirtualStack.
if (allocationOption.HasOption(AllocationOption.Clear))
{
MemClear(_baseAddress + _allocatedOffset - diff, diff);
MemoryUtility.MemClear(_baseAddress + _allocatedOffset - diff, diff);
}
return ptr;
@@ -190,7 +190,7 @@ public unsafe struct VirtualStack : IMemoryAllocator<VirtualStack, VirtualStack.
return null;
}
MemCpy(newPtr, ptr, Math.Min(oldSize, newSize));
MemoryUtility.MemCpy(newPtr, ptr, Math.Min(oldSize, newSize));
return newPtr;
}
@@ -224,6 +224,6 @@ public unsafe struct VirtualStack : IMemoryAllocator<VirtualStack, VirtualStack.
_committedSize = 0;
_reserveCapacity = 0;
Munmap(ptr, size);
MemoryUtility.Munmap(ptr, size);
}
}