Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 31 additions & 3 deletions src/Orleans.Serialization/Invocation/Pools/ConcurrentObjectPool.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading;
using Microsoft.Extensions.ObjectPool;

Expand All @@ -14,17 +16,36 @@ public ConcurrentObjectPool() : base(new())

internal class ConcurrentObjectPool<T, TPoolPolicy> : ObjectPool<T> where T : class where TPoolPolicy : IPooledObjectPolicy<T>
{
private readonly ThreadLocal<Stack<T>> _objects = new(() => new());
private static int NextPoolId = -1;

private readonly int _poolId = Interlocked.Increment(ref NextPoolId);
private readonly TPoolPolicy _policy;

public ConcurrentObjectPool(TPoolPolicy policy) => _policy = policy;

public int MaxPoolSize { get; set; } = int.MaxValue;

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private Stack<T> GetStack()
{
var poolId = _poolId;
var stacks = PerThreadStack.Stacks;
if (stacks is null)
{
stacks = PerThreadStack.Stacks = new Stack<T>[poolId + 1];
}
else if ((uint)poolId >= (uint)stacks.Length)
{
Array.Resize(ref stacks, Math.Max(poolId + 1, stacks.Length * 2));
PerThreadStack.Stacks = stacks;
}

return stacks[poolId] ??= new();
Comment on lines +19 to +43
}

public override T Get()
{
var stack = _objects.Value;
var stack = GetStack();
if (stack.TryPop(out var result))
{
return result;
Expand All @@ -37,12 +58,19 @@ public override void Return(T obj)
{
if (_policy.Return(obj))
{
var stack = _objects.Value;
var stack = GetStack();
if (stack.Count < MaxPoolSize)
{
stack.Push(obj);
}
}
}

// Thread-static stacks are indexed by pool instance to avoid sharing state between pools with different policies.
private static class PerThreadStack
{
[ThreadStatic]
internal static Stack<T>[] Stacks;
}
}
}
Loading