#if MONO
using System;
using System.Runtime;
using System.Security.Permissions;
namespace System.Threading
{
/// Provides support for spin-based waiting.
[__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;
/// Gets the number of times has been called on this instance.
/// Returns an integer that represents the number of times has been called on this instance.
[__DynamicallyInvokable]
public int Count
{
[__DynamicallyInvokable]
get
{
return this.m_count;
}
}
/// Gets whether the next call to will yield the processor, triggering a forced context switch.
/// Whether the next call to will yield the processor, triggering a forced context switch.
[__DynamicallyInvokable]
public bool NextSpinWillYield
{
[__DynamicallyInvokable]
get
{
return this.m_count > 10 || PlatformHelper.IsSingleProcessor;
}
}
/// Performs a single spin.
[__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));
}
/// Resets the spin counter.
[__DynamicallyInvokable]
public void Reset()
{
this.m_count = 0;
}
/// Spins until the specified condition is satisfied.
/// A delegate to be executed over and over until it returns true.
/// The argument is null.
[__DynamicallyInvokable]
public static void SpinUntil(Func condition)
{
SpinWait.SpinUntil(condition, -1);
}
/// Spins until the specified condition is satisfied or until the specified timeout is expired.
/// True if the condition is satisfied within the timeout; otherwise, false
/// A delegate to be executed over and over until it returns true.
/// A that represents the number of milliseconds to wait, or a TimeSpan that represents -1 milliseconds to wait indefinitely.
/// The argument is null.
///
/// is a negative number other than -1 milliseconds, which represents an infinite time-out -or- timeout is greater than .
[__DynamicallyInvokable]
public static bool SpinUntil(Func 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);
}
/// Spins until the specified condition is satisfied or until the specified timeout is expired.
/// True if the condition is satisfied within the timeout; otherwise, false
/// A delegate to be executed over and over until it returns true.
/// The number of milliseconds to wait, or (-1) to wait indefinitely.
/// The argument is null.
///
/// is a negative number other than -1, which represents an infinite time-out.
[__DynamicallyInvokable]
public static bool SpinUntil(Func 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