// 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]); } }