142 lines · 5.6 KB · C#
RawDownload
#if MONOusing System;using System.Runtime;using System.Security.Permissions; namespace System.Threading{	/// <summary>Provides support for spin-based waiting.</summary>	[__DynamicallyInvokable]	[HostProtection(SecurityAction.LinkDemand, Synchronization = true, ExternalThreading = true)]	public struct SpinWait	{		internal const int YIELD_THRESHOLD = 10;		internal const int SLEEP_0_EVERY_HOW_MANY_TIMES = 5;		internal const int SLEEP_1_EVERY_HOW_MANY_TIMES = 20;		private int m_count;		/// <summary>Gets the number of times <see cref="M:System.Threading.SpinWait.SpinOnce" /> has been called on this instance.</summary>		/// <returns>Returns an integer that represents the number of times <see cref="M:System.Threading.SpinWait.SpinOnce" /> has been called on this instance.</returns>		[__DynamicallyInvokable]		public int Count		{			[__DynamicallyInvokable]			get			{				return this.m_count;			}		}		/// <summary>Gets whether the next call to <see cref="M:System.Threading.SpinWait.SpinOnce" /> will yield the processor, triggering a forced context switch.</summary>		/// <returns>Whether the next call to <see cref="M:System.Threading.SpinWait.SpinOnce" /> will yield the processor, triggering a forced context switch.</returns>		[__DynamicallyInvokable]		public bool NextSpinWillYield		{			[__DynamicallyInvokable]			get			{				return this.m_count > 10 || PlatformHelper.IsSingleProcessor;			}		}		/// <summary>Performs a single spin.</summary>		[__DynamicallyInvokable]		public void SpinOnce()		{			if (this.NextSpinWillYield)			{				//CdsSyncEtwBCLProvider.Log.SpinWait_NextSpinWillYield();				int num = (this.m_count >= 10) ? (this.m_count - 10) : this.m_count;				if (num % 20 == 19)				{					Thread.Sleep(1);				}				else				{                    Thread.Sleep(0);                    //if (num % 5 == 4)                    //{                    //    Thread.Sleep(0);                    //}                    //else                    //{                    //    Thread.Sleep(0);                    //}				}			}			else			{				Thread.SpinWait(4 << this.m_count);			}			this.m_count = ((this.m_count == 2147483647) ? 10 : (this.m_count + 1));		}		/// <summary>Resets the spin counter.</summary>		[__DynamicallyInvokable]		public void Reset()		{			this.m_count = 0;		}		/// <summary>Spins until the specified condition is satisfied.</summary>		/// <param name="condition">A delegate to be executed over and over until it returns true.</param>		/// <exception cref="T:System.ArgumentNullException">The <paramref name="condition" /> argument is null.</exception>		[__DynamicallyInvokable]		public static void SpinUntil(Func<bool> condition)		{			SpinWait.SpinUntil(condition, -1);		}		/// <summary>Spins until the specified condition is satisfied or until the specified timeout is expired.</summary>		/// <returns>True if the condition is satisfied within the timeout; otherwise, false</returns>		/// <param name="condition">A delegate to be executed over and over until it returns true.</param>		/// <param name="timeout">A <see cref="T:System.TimeSpan" /> that represents the number of milliseconds to wait, or a TimeSpan that represents -1 milliseconds to wait indefinitely.</param>		/// <exception cref="T:System.ArgumentNullException">The <paramref name="condition" /> argument is null.</exception>		/// <exception cref="T:System.ArgumentOutOfRangeException">		///   <paramref name="timeout" /> is a negative number other than -1 milliseconds, which represents an infinite time-out -or- timeout is greater than <see cref="F:System.Int32.MaxValue" />.</exception>		[__DynamicallyInvokable]		public static bool SpinUntil(Func<bool> condition, TimeSpan timeout)		{			long num = (long)timeout.TotalMilliseconds;			if (num < -1L || num > 2147483647L)			{				throw new ArgumentOutOfRangeException("timeout", timeout, "SpinWait_SpinUntil_TimeoutWrong");			}			return SpinWait.SpinUntil(condition, (int)timeout.TotalMilliseconds);		}		/// <summary>Spins until the specified condition is satisfied or until the specified timeout is expired.</summary>		/// <returns>True if the condition is satisfied within the timeout; otherwise, false</returns>		/// <param name="condition">A delegate to be executed over and over until it returns true.</param>		/// <param name="millisecondsTimeout">The number of milliseconds to wait, or <see cref="F:System.Threading.Timeout.Infinite" /> (-1) to wait indefinitely.</param>		/// <exception cref="T:System.ArgumentNullException">The <paramref name="condition" /> argument is null.</exception>		/// <exception cref="T:System.ArgumentOutOfRangeException">		///   <paramref name="millisecondsTimeout" /> is a negative number other than -1, which represents an infinite time-out.</exception>		[__DynamicallyInvokable]		public static bool SpinUntil(Func<bool> condition, int millisecondsTimeout)		{			if (millisecondsTimeout < -1)			{				throw new ArgumentOutOfRangeException("millisecondsTimeout", millisecondsTimeout, "SpinWait_SpinUntil_TimeoutWrong");			}			if (condition == null)			{				throw new ArgumentNullException("condition", "SpinWait_SpinUntil_ArgumentNull");			}			uint num = 0u;			if (millisecondsTimeout != 0 && millisecondsTimeout != -1)			{				num = TimeoutHelper.GetTime();			}			SpinWait spinWait = default(SpinWait);			while (!condition())			{				if (millisecondsTimeout == 0)				{					return false;				}				spinWait.SpinOnce();				if (millisecondsTimeout != -1 && spinWait.NextSpinWillYield && (long)millisecondsTimeout <= (long)((ulong)(TimeoutHelper.GetTime() - num)))				{					return false;				}			}			return true;		}	}} #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