// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
using System;
using System.Net;
using System.Threading;
namespace FASTER.core
{
///
/// Fast implementation of instance-thread-local variables
///
///
internal class FastThreadLocal
{
// Max instances supported
private const int kMaxInstances = 128;
[ThreadStatic]
private static T[] tl_values;
[ThreadStatic]
private static int[] tl_iid;
private readonly int offset;
private readonly int iid;
private static readonly int[] instances = new int[kMaxInstances];
private static int instanceId = 0;
public FastThreadLocal()
{
iid = Interlocked.Increment(ref instanceId);
for (int i = 0; i < kMaxInstances; i++)
{
if (0 == Interlocked.CompareExchange(ref instances[i], iid, 0))
{
offset = i;
return;
}
}
throw new Exception("Unsupported number of simultaneous instances");
}
public void InitializeThread()
{
if (tl_values == null)
{
tl_values = new T[kMaxInstances];
tl_iid = new int[kMaxInstances];
}
if (tl_iid[offset] != iid)
{
tl_iid[offset] = iid;
tl_values[offset] = default(T);
}
}
public void DisposeThread()
{
tl_values[offset] = default(T);
tl_iid[offset] = 0;
}
///
/// Dispose instance for all threads
///
public void Dispose()
{
instances[offset] = 0;
}
public T Value
{
get => tl_values[offset];
set => tl_values[offset] = value;
}
public bool IsInitializedForThread => (tl_values != null) && (iid == tl_iid[offset]);
}
}