Refactor TLSFAllocator locking, update AddRange signatures

Refactored TLSFAllocator to use a static lock instead of per-instance GCHandle-based locking, removing the Dispose method and related code. Updated allocation methods to use the static lock for thread safety. Removed Dispose call on s_pTLSFAllocator. In UnsafeChunkedList, removed an unused using directive and replaced explicit int types with var in AddRange. Changed UnsafeList<T>.AddRange to accept ReadOnlySpan<T> for broader compatibility. Bumped assembly version to 1.6.25.
This commit is contained in:
2026-05-10 13:06:32 +09:00
parent 99a7e3c4e1
commit 4b9d93ec65
4 changed files with 10 additions and 22 deletions

View File

@@ -141,10 +141,11 @@ public static unsafe class AllocationManager
} }
// TODO: Lock-free implementation // TODO: Lock-free implementation
internal struct TLSFAllocator : IAllocator, IDisposable internal struct TLSFAllocator : IAllocator
{ {
private static readonly Lock s_lock = new Lock();
private TLSF _tlsf; private TLSF _tlsf;
private GCHandle _lock;
private AllocationHandle _handle; private AllocationHandle _handle;
public readonly AllocationHandle Handle => _handle; public readonly AllocationHandle Handle => _handle;
@@ -152,18 +153,14 @@ public static unsafe class AllocationManager
public void Init(nuint alignment, nuint initialChunkSize) public void Init(nuint alignment, nuint initialChunkSize)
{ {
_tlsf = new TLSF(alignment, initialChunkSize); _tlsf = new TLSF(alignment, initialChunkSize);
#pragma warning disable CS9216 // A value of type 'System.Threading.Lock' converted to a different type will use likely unintended monitor-based locking in 'lock' statement.
_lock = GCHandle.Alloc(new Lock(), GCHandleType.Normal);
#pragma warning restore CS9216 // A value of type 'System.Threading.Lock' converted to a different type will use likely unintended monitor-based locking in 'lock' statement.
_handle = new AllocationHandle(Unsafe.AsPointer(in this), &Allocate, &Reallocate, &Free); _handle = new AllocationHandle(Unsafe.AsPointer(in this), &Allocate, &Reallocate, &Free);
} }
private static void* Allocate(void* state, nuint size, nuint alignment, AllocationOption allocationOption) private static void* Allocate(void* state, nuint size, nuint alignment, AllocationOption allocationOption)
{ {
var allocator = (TLSFAllocator*)state; var allocator = (TLSFAllocator*)state;
var locker = (Lock)allocator->_lock.Target!;
lock (locker) lock (s_lock)
{ {
return allocator->_tlsf.Allocate(size, alignment, allocationOption); return allocator->_tlsf.Allocate(size, alignment, allocationOption);
} }
@@ -172,9 +169,8 @@ public static unsafe class AllocationManager
private static void* Reallocate(void* state, void* ptr, nuint oldSize, nuint newSize, nuint alignment, AllocationOption allocationOption) private static void* Reallocate(void* state, void* ptr, nuint oldSize, nuint newSize, nuint alignment, AllocationOption allocationOption)
{ {
var allocator = (TLSFAllocator*)state; var allocator = (TLSFAllocator*)state;
var locker = (Lock)allocator->_lock.Target!;
lock (locker) lock (s_lock)
{ {
return allocator->_tlsf.Reallocate(ptr, oldSize, newSize, alignment, allocationOption); return allocator->_tlsf.Reallocate(ptr, oldSize, newSize, alignment, allocationOption);
} }
@@ -183,18 +179,12 @@ public static unsafe class AllocationManager
private static void Free(void* state, void* ptr) private static void Free(void* state, void* ptr)
{ {
var allocator = (TLSFAllocator*)state; var allocator = (TLSFAllocator*)state;
var locker = (Lock)allocator->_lock.Target!;
lock (locker) lock (s_lock)
{ {
allocator->_tlsf.Free(ptr); allocator->_tlsf.Free(ptr);
} }
} }
public void Dispose()
{
_lock.Free();
}
} }
private class ThreadLocalStackPool private class ThreadLocalStackPool
@@ -513,7 +503,6 @@ public static unsafe class AllocationManager
if (s_pTLSFAllocator != null) if (s_pTLSFAllocator != null)
{ {
s_pTLSFAllocator->Dispose();
NativeMemory.Free(s_pTLSFAllocator); NativeMemory.Free(s_pTLSFAllocator);
s_pTLSFAllocator = null; s_pTLSFAllocator = null;
} }

View File

@@ -1,7 +1,6 @@
using Misaki.HighPerformance.LowLevel.Buffer; using Misaki.HighPerformance.LowLevel.Buffer;
using Misaki.HighPerformance.LowLevel.Collections.Contracts; using Misaki.HighPerformance.LowLevel.Collections.Contracts;
using Misaki.HighPerformance.LowLevel.Utilities; using Misaki.HighPerformance.LowLevel.Utilities;
using System.Collections;
using System.Diagnostics; using System.Diagnostics;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
@@ -148,9 +147,9 @@ public unsafe struct UnsafeChunkedList<T> : IUnsafeCollection<T>
fixed (T* pCollection = collection) fixed (T* pCollection = collection)
{ {
int remaining = count; var remaining = count;
T* srcPtr = pCollection; T* srcPtr = pCollection;
int currentIndex = index; var currentIndex = index;
while (remaining > 0) while (remaining > 0)
{ {

View File

@@ -332,7 +332,7 @@ public unsafe struct UnsafeList<T> : IUnsafeCollection<T>
/// Adds a range of elements to the collection. /// Adds a range of elements to the collection.
/// </summary> /// </summary>
/// <param name="values">A span containing the elements to add.</param> /// <param name="values">A span containing the elements to add.</param>
public void AddRange(Span<T> values) public void AddRange(ReadOnlySpan<T> values)
{ {
var newSize = _count + values.Length; var newSize = _count + values.Length;
if (newSize > Capacity) if (newSize > Capacity)

View File

@@ -7,7 +7,7 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>Misaki</Authors> <Authors>Misaki</Authors>
<AssemblyVersion>1.6.24</AssemblyVersion> <AssemblyVersion>1.6.25</AssemblyVersion>
<Version>$(AssemblyVersion)</Version> <Version>$(AssemblyVersion)</Version>
<PackageProjectUrl>https://git.personalnas.com/Misaki/Misaki.HighPerformance.git</PackageProjectUrl> <PackageProjectUrl>https://git.personalnas.com/Misaki/Misaki.HighPerformance.git</PackageProjectUrl>
<RepositoryUrl>https://git.personalnas.com/Misaki/Misaki.HighPerformance.git</RepositoryUrl> <RepositoryUrl>https://git.personalnas.com/Misaki/Misaki.HighPerformance.git</RepositoryUrl>