#if MONO using System; using System.Diagnostics.Tracing; using System.Runtime; using System.Runtime.CompilerServices; using System.Security.Permissions; namespace System.Threading { internal static class PlatformHelper { private static volatile int s_processorCount; private static volatile int s_lastProcessorCountRefreshTicks; private const int PROCESSOR_COUNT_REFRESH_INTERVAL_MS = 30000; internal static int ProcessorCount { get { int tickCount = Environment.TickCount; int num = PlatformHelper.s_processorCount; if (num == 0 || tickCount - PlatformHelper.s_lastProcessorCountRefreshTicks >= 30000) { num = (PlatformHelper.s_processorCount = Environment.ProcessorCount); PlatformHelper.s_lastProcessorCountRefreshTicks = tickCount; } return num; } } internal static bool IsSingleProcessor { get { return PlatformHelper.ProcessorCount == 1; } } } internal static class TimeoutHelper { public static uint GetTime() { return (uint)Environment.TickCount; } public static int UpdateTimeOut(uint startTime, int originalWaitMillisecondsTimeout) { uint num = TimeoutHelper.GetTime() - startTime; if (num > 2147483647u) { return 0; } int num2 = originalWaitMillisecondsTimeout - (int)num; if (num2 <= 0) { return 0; } return num2; } } internal struct CancellationCallbackCoreWorkArguments { internal SparselyPopulatedArrayFragment m_currArrayFragment; internal int m_currArrayIndex; [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] public CancellationCallbackCoreWorkArguments(SparselyPopulatedArrayFragment currArrayFragment, int currArrayIndex) { this.m_currArrayFragment = currArrayFragment; this.m_currArrayIndex = currArrayIndex; } } internal class SparselyPopulatedArray where T : class { private readonly SparselyPopulatedArrayFragment m_head; private volatile SparselyPopulatedArrayFragment m_tail; internal SparselyPopulatedArrayFragment Tail { get { return this.m_tail; } } internal SparselyPopulatedArray(int initialSize) { this.m_head = (this.m_tail = new SparselyPopulatedArrayFragment(initialSize)); } internal SparselyPopulatedArrayAddInfo Add(T element) { SparselyPopulatedArrayFragment sparselyPopulatedArrayFragment2; int num2; while (true) { SparselyPopulatedArrayFragment sparselyPopulatedArrayFragment = this.m_tail; while (sparselyPopulatedArrayFragment.m_next != null) { sparselyPopulatedArrayFragment = (this.m_tail = sparselyPopulatedArrayFragment.m_next); } for (sparselyPopulatedArrayFragment2 = sparselyPopulatedArrayFragment; sparselyPopulatedArrayFragment2 != null; sparselyPopulatedArrayFragment2 = sparselyPopulatedArrayFragment2.m_prev) { if (sparselyPopulatedArrayFragment2.m_freeCount < 1) { sparselyPopulatedArrayFragment2.m_freeCount--; } if (sparselyPopulatedArrayFragment2.m_freeCount > 0 || sparselyPopulatedArrayFragment2.m_freeCount < -10) { int length = sparselyPopulatedArrayFragment2.Length; int num = (length - sparselyPopulatedArrayFragment2.m_freeCount) % length; if (num < 0) { num = 0; sparselyPopulatedArrayFragment2.m_freeCount--; } for (int i = 0; i < length; i++) { num2 = (num + i) % length; if (sparselyPopulatedArrayFragment2.m_elements[num2] == null && Interlocked.CompareExchange(ref sparselyPopulatedArrayFragment2.m_elements[num2], element, default(T)) == null) { goto Block_5; } } } } SparselyPopulatedArrayFragment sparselyPopulatedArrayFragment3 = new SparselyPopulatedArrayFragment((sparselyPopulatedArrayFragment.m_elements.Length == 4096) ? 4096 : (sparselyPopulatedArrayFragment.m_elements.Length * 2), sparselyPopulatedArrayFragment); if (Interlocked.CompareExchange>(ref sparselyPopulatedArrayFragment.m_next, sparselyPopulatedArrayFragment3, null) == null) { this.m_tail = sparselyPopulatedArrayFragment3; } } Block_5: int num3 = sparselyPopulatedArrayFragment2.m_freeCount - 1; sparselyPopulatedArrayFragment2.m_freeCount = ((num3 > 0) ? num3 : 0); return new SparselyPopulatedArrayAddInfo(sparselyPopulatedArrayFragment2, num2); } } internal class SparselyPopulatedArrayFragment where T : class { internal readonly T[] m_elements; internal volatile int m_freeCount; internal volatile SparselyPopulatedArrayFragment m_next; internal volatile SparselyPopulatedArrayFragment m_prev; internal T this[int index] { get { return Volatile.Read(ref this.m_elements[index]); } } internal int Length { get { return this.m_elements.Length; } } internal SparselyPopulatedArrayFragment Prev { get { return this.m_prev; } } internal SparselyPopulatedArrayFragment(int size) : this(size, null) { } internal SparselyPopulatedArrayFragment(int size, SparselyPopulatedArrayFragment prev) { this.m_elements = new T[size]; this.m_freeCount = size; this.m_prev = prev; } internal T SafeAtomicRemove(int index, T expectedElement) { T t = Interlocked.CompareExchange(ref this.m_elements[index], default(T), expectedElement); if (t != null) { this.m_freeCount++; } return t; } } internal struct SparselyPopulatedArrayAddInfo where T : class { private SparselyPopulatedArrayFragment m_source; private int m_index; internal SparselyPopulatedArrayFragment Source { get { return this.m_source; } } internal int Index { get { return this.m_index; } } internal SparselyPopulatedArrayAddInfo(SparselyPopulatedArrayFragment source, int index) { this.m_source = source; this.m_index = index; } } /// Represents a callback delegate that has been registered with a . [__DynamicallyInvokable] [HostProtection(SecurityAction.LinkDemand, Synchronization = true, ExternalThreading = true)] public struct CancellationTokenRegistration : IEquatable, IDisposable { private readonly CancellationCallbackInfo m_callbackInfo; private readonly SparselyPopulatedArrayAddInfo m_registrationInfo; [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] internal CancellationTokenRegistration(CancellationCallbackInfo callbackInfo, SparselyPopulatedArrayAddInfo registrationInfo) { this.m_callbackInfo = callbackInfo; this.m_registrationInfo = registrationInfo; } [FriendAccessAllowed] internal bool TryDeregister() { if (this.m_registrationInfo.Source == null) { return false; } CancellationCallbackInfo cancellationCallbackInfo = this.m_registrationInfo.Source.SafeAtomicRemove(this.m_registrationInfo.Index, this.m_callbackInfo); return cancellationCallbackInfo == this.m_callbackInfo; } /// Releases all resources used by the current instance of the class. /// The token source that created this token registration instance has already been disposed. [__DynamicallyInvokable] public void Dispose() { bool flag = this.TryDeregister(); CancellationCallbackInfo callbackInfo = this.m_callbackInfo; if (callbackInfo != null) { CancellationTokenSource cancellationTokenSource = callbackInfo.CancellationTokenSource; if (cancellationTokenSource.IsCancellationRequested && !cancellationTokenSource.IsCancellationCompleted && !flag && cancellationTokenSource.ThreadIDExecutingCallbacks != Thread.CurrentThread.ManagedThreadId) { cancellationTokenSource.WaitForCallbackToComplete(this.m_callbackInfo); } } } /// Determines whether two instances are equal. /// True if the instances are equal; otherwise, false. /// The first instance. /// The second instance. [__DynamicallyInvokable] public static bool operator ==(CancellationTokenRegistration left, CancellationTokenRegistration right) { return left.Equals(right); } /// Determines whether two instances are not equal. /// True if the instances are not equal; otherwise, false. /// The first instance. /// The second instance. [__DynamicallyInvokable] public static bool operator !=(CancellationTokenRegistration left, CancellationTokenRegistration right) { return !left.Equals(right); } /// Determines whether the current instance is equal to the specified . /// True, if both this and are equal. False, otherwise.Two instances are equal if they both refer to the output of a single call to the same Register method of a . /// The other object to which to compare this instance. [__DynamicallyInvokable] public override bool Equals(object obj) { return obj is CancellationTokenRegistration && this.Equals((CancellationTokenRegistration)obj); } /// Determines whether the current instance is equal to the specified . /// True, if both this and are equal. False, otherwise. Two instances are equal if they both refer to the output of a single call to the same Register method of a . /// The other to which to compare this instance. [__DynamicallyInvokable] public bool Equals(CancellationTokenRegistration other) { return this.m_callbackInfo == other.m_callbackInfo && this.m_registrationInfo.Source == other.m_registrationInfo.Source && this.m_registrationInfo.Index == other.m_registrationInfo.Index; } /// Serves as a hash function for a . /// A hash code for the current instance. [__DynamicallyInvokable] public override int GetHashCode() { if (this.m_registrationInfo.Source != null) { return this.m_registrationInfo.Source.GetHashCode() ^ this.m_registrationInfo.Index.GetHashCode(); } return this.m_registrationInfo.Index.GetHashCode(); } } } #endif