Fixed capacity stack improvements to make sure that each thread gets its own instance.

This commit is contained in:
mlemanczyk committed 2025-12-12 14:43:49 +01:00
1 parent 8a5a8a7bb5
commit 8b0d09cc9c
2 files changed
+30 -12

No files matched your search

@@ -3,14 +3,23 @@ using System.Runtime.CompilerServices;
namespace PerfectNumbers.Core;
public sealed class ConcurrentFixedCapacityStack<T>(int capacity)
public sealed class ConcurrentFixedCapacityStack<T>
{
private static readonly FixedCapacityArrayPool<T> _arrayPool = FixedCapacityPools<T>.ExclusiveArray;
[ThreadStatic]
private static FixedCapacityArrayPool<T>? _arrayPool;
private readonly T[] _items = _arrayPool.Rent(capacity);
private readonly int _capacity = capacity;
private readonly T[] _items;
private readonly int _capacity;
private int _count = 0;
public ConcurrentFixedCapacityStack(int capacity)
{
_arrayPool ??= FixedCapacityPools<T>.ExclusiveArray;
_items = _arrayPool.Value.Rent(capacity);
_capacity = capacity;
}
public int Count
{
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
@@ -68,13 +77,13 @@ public sealed class ConcurrentFixedCapacityStack<T>(int capacity)
}
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static void Return(in T[] items) => _arrayPool.Return(items);
public static void Return(in T[] items) => _arrayPool!.Value.Return(items);
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public T[] ToArray()
{
int count = Volatile.Read(ref _count);
T[] result = _arrayPool.Rent(count);
T[] result = _arrayPool!.Value.Rent(count);
Array.Copy(_items, result, count);
return result;
}
+15 -6
View File
@@ -2,14 +2,23 @@ using System.Runtime.CompilerServices;
namespace PerfectNumbers.Core;
public sealed class FixedCapacityStack<T>(int capacity)
public sealed class FixedCapacityStack<T>
{
private static readonly FixedCapacityArrayPool<T> _arrayPool = FixedCapacityPools<T>.ExclusiveArray;
[ThreadStatic]
private static FixedCapacityArrayPool<T>? _arrayPool;
public int Count = 0;
private T[] _items = _arrayPool.Rent(capacity);
private T[] _items;
private int _capacity;
public FixedCapacityStack(int capacity)
{
_arrayPool ??= new(PerfectNumberConstants.DefaultPoolCapacity);
_items = _arrayPool.Value.Rent(capacity);
_capacity = capacity;
}
private int _capacity = capacity;
public int Capacity
{
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
@@ -20,8 +29,8 @@ public sealed class FixedCapacityStack<T>(int capacity)
{
if (value < _capacity)
{
_arrayPool.Return(_items);
_items = _arrayPool.Rent(value);
_arrayPool!.Value.Return(_items);
_items = _arrayPool.Value.Rent(value);
_capacity = value;
}
}