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:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user