299 lines · 13.5 KB · C#
RawDownload
#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<CancellationCallbackInfo> m_currArrayFragment;        internal int m_currArrayIndex;        [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]        public CancellationCallbackCoreWorkArguments(SparselyPopulatedArrayFragment<CancellationCallbackInfo> currArrayFragment, int currArrayIndex)        {            this.m_currArrayFragment = currArrayFragment;            this.m_currArrayIndex = currArrayIndex;        }    }     internal class SparselyPopulatedArray<T> where T : class    {        private readonly SparselyPopulatedArrayFragment<T> m_head;        private volatile SparselyPopulatedArrayFragment<T> m_tail;        internal SparselyPopulatedArrayFragment<T> Tail        {            get            {                return this.m_tail;            }        }        internal SparselyPopulatedArray(int initialSize)        {            this.m_head = (this.m_tail = new SparselyPopulatedArrayFragment<T>(initialSize));        }        internal SparselyPopulatedArrayAddInfo<T> Add(T element)        {            SparselyPopulatedArrayFragment<T> sparselyPopulatedArrayFragment2;            int num2;            while (true)            {                SparselyPopulatedArrayFragment<T> 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<T>(ref sparselyPopulatedArrayFragment2.m_elements[num2], element, default(T)) == null)                            {                                goto Block_5;                            }                        }                    }                }                SparselyPopulatedArrayFragment<T> sparselyPopulatedArrayFragment3 = new SparselyPopulatedArrayFragment<T>((sparselyPopulatedArrayFragment.m_elements.Length == 4096) ? 4096 : (sparselyPopulatedArrayFragment.m_elements.Length * 2), sparselyPopulatedArrayFragment);                if (Interlocked.CompareExchange<SparselyPopulatedArrayFragment<T>>(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<T>(sparselyPopulatedArrayFragment2, num2);        }    }     internal class SparselyPopulatedArrayFragment<T> where T : class    {        internal readonly T[] m_elements;        internal volatile int m_freeCount;        internal volatile SparselyPopulatedArrayFragment<T> m_next;        internal volatile SparselyPopulatedArrayFragment<T> m_prev;        internal T this[int index]        {            get            {                return Volatile.Read<T>(ref this.m_elements[index]);            }        }        internal int Length        {            get            {                return this.m_elements.Length;            }        }        internal SparselyPopulatedArrayFragment<T> Prev        {            get            {                return this.m_prev;            }        }         internal SparselyPopulatedArrayFragment(int size)            : this(size, null)        {        }        internal SparselyPopulatedArrayFragment(int size, SparselyPopulatedArrayFragment<T> 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<T>(ref this.m_elements[index], default(T), expectedElement);            if (t != null)            {                this.m_freeCount++;            }            return t;        }    }     internal struct SparselyPopulatedArrayAddInfo<T> where T : class    {        private SparselyPopulatedArrayFragment<T> m_source;        private int m_index;        internal SparselyPopulatedArrayFragment<T> Source        {            get            {                return this.m_source;            }        }        internal int Index        {            get            {                return this.m_index;            }        }         internal SparselyPopulatedArrayAddInfo(SparselyPopulatedArrayFragment<T> source, int index)        {            this.m_source = source;            this.m_index = index;        }    }     /// <summary>Represents a callback delegate that has been registered with a <see cref="T:System.Threading.CancellationToken" />. </summary>    [__DynamicallyInvokable]    [HostProtection(SecurityAction.LinkDemand, Synchronization = true, ExternalThreading = true)]    public struct CancellationTokenRegistration : IEquatable<CancellationTokenRegistration>, IDisposable    {        private readonly CancellationCallbackInfo m_callbackInfo;        private readonly SparselyPopulatedArrayAddInfo<CancellationCallbackInfo> m_registrationInfo;        [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]        internal CancellationTokenRegistration(CancellationCallbackInfo callbackInfo, SparselyPopulatedArrayAddInfo<CancellationCallbackInfo> 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;        }        /// <summary>Releases all resources used by the current instance of the <see cref="T:System.Threading.CancellationTokenRegistration" /> class.</summary>        /// <exception cref="T:System.ObjectDisposedException">The token source that created this token registration instance has already been disposed.</exception>        [__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);                }            }        }        /// <summary>Determines whether two <see cref="T:System.Threading.CancellationTokenRegistration" /> instances are equal.</summary>        /// <returns>True if the instances are equal; otherwise, false.</returns>        /// <param name="left">The first instance.</param>        /// <param name="right">The second instance.</param>        [__DynamicallyInvokable]        public static bool operator ==(CancellationTokenRegistration left, CancellationTokenRegistration right)        {            return left.Equals(right);        }        /// <summary>Determines whether two <see cref="T:System.Threading.CancellationTokenRegistration" /> instances are not equal.</summary>        /// <returns>True if the instances are not equal; otherwise, false.</returns>        /// <param name="left">The first instance.</param>        /// <param name="right">The second instance.</param>        [__DynamicallyInvokable]        public static bool operator !=(CancellationTokenRegistration left, CancellationTokenRegistration right)        {            return !left.Equals(right);        }        /// <summary>Determines whether the current <see cref="T:System.Threading.CancellationTokenRegistration" /> instance is equal to the specified <see cref="T:System.Threading.CancellationTokenRegistration" />.</summary>        /// <returns>True, if both this and <paramref name="obj" /> are equal. False, otherwise.Two <see cref="T:System.Threading.CancellationTokenRegistration" /> instances are equal if they both refer to the output of a single call to the same Register method of a <see cref="T:System.Threading.CancellationToken" />.</returns>        /// <param name="obj">The other object to which to compare this instance.</param>        [__DynamicallyInvokable]        public override bool Equals(object obj)        {            return obj is CancellationTokenRegistration && this.Equals((CancellationTokenRegistration)obj);        }        /// <summary>Determines whether the current <see cref="T:System.Threading.CancellationTokenRegistration" /> instance is equal to the specified <see cref="T:System.Threading.CancellationTokenRegistration" />.</summary>        /// <returns>True, if both this and <paramref name="other" /> are equal. False, otherwise. Two <see cref="T:System.Threading.CancellationTokenRegistration" /> instances are equal if they both refer to the output of a single call to the same Register method of a <see cref="T:System.Threading.CancellationToken" />.</returns>        /// <param name="other">The other <see cref="T:System.Threading.CancellationTokenRegistration" /> to which to compare this instance.</param>        [__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;        }        /// <summary>Serves as a hash function for a <see cref="T:System.Threading.CancellationTokenRegistration" />.</summary>        /// <returns>A hash code for the current <see cref="T:System.Threading.CancellationTokenRegistration" /> instance.</returns>        [__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

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t