Skip to content

Commit

Permalink
Add SpinWait (#136)
Browse files Browse the repository at this point in the history
  • Loading branch information
josesimoes authored May 13, 2021
1 parent 061edcf commit 2a0e1ee
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 2 deletions.
1 change: 1 addition & 0 deletions nanoFramework.CoreLibrary/CoreLibrary.nfproj
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@
<Compile Include="System\Threading\ThreadStart.cs" />
<Compile Include="System\Threading\ThreadState.cs" />
<Compile Include="System\Threading\Timeout.cs" />
<Compile Include="System\Threading\SpinWait.cs" />
<Compile Include="System\Threading\Timer.cs" />
<Compile Include="System\Threading\WaitHandle.cs" />
<Compile Include="System\TimeSpan.cs" />
Expand Down
2 changes: 1 addition & 1 deletion nanoFramework.CoreLibrary/System/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@
[assembly: AssemblyProduct(".NET nanoFramework mscorlib")]
[assembly: AssemblyCopyright("Copyright (c) .NET Foundation and Contributors")]

[assembly: AssemblyNativeVersion("100.5.0.7")]
[assembly: AssemblyNativeVersion("100.5.0.8")]
68 changes: 68 additions & 0 deletions nanoFramework.CoreLibrary/System/Threading/SpinWait.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
//
// Copyright (c) .NET Foundation and Contributors
// Portions Copyright (c) Microsoft Corporation. All rights reserved.
// See LICENSE file in the project root for full license information.
//

namespace System.Threading
{
using System;
using Runtime.CompilerServices;

/// <summary>
/// Provides support for spin-based waiting.
/// </summary>
/// <remarks>
/// <para>
/// <see cref="SpinWait"/> encapsulates common spinning logic. On single-processor machines, yields are
/// always used instead of busy waits, and on computers with Intel™ processors employing Hyper-Threading™
/// technology, it helps to prevent hardware thread starvation. SpinWait encapsulates a good mixture of
/// spinning and true yielding.
/// </para>
/// <para>
/// <see cref="SpinWait"/> is a value type, which means that low-level code can utilize SpinWait without
/// fear of unnecessary allocation overheads. SpinWait is not generally useful for ordinary applications.
/// In most cases, you should use the synchronization classes provided by the .NET Framework, such as
/// <see cref="System.Threading.Monitor"/>. For most purposes where spin waiting is required, however,
/// the <see cref="SpinWait"/> type should be preferred over the <see
/// cref="Thread.SpinWait"/> method.
/// </para>
/// <para>
/// While SpinWait is designed to be used in concurrent applications, it is not designed to be
/// used from multiple threads concurrently. SpinWait's members are not thread-safe. If multiple
/// threads must spin, each should use its own instance of SpinWait.
/// </para>
/// </remarks>
public struct SpinWait
{
/// <summary>
/// Performs a single spin.
/// </summary>
/// <remarks>
/// This is typically called in a loop, and may change in behavior based on the number of times a
/// <see cref="SpinOnce"/> has been called thus far on this instance.
/// </remarks>
[MethodImpl(MethodImplOptions.InternalCall)]
public extern void SpinOnce();

/// <summary>
/// Spins until the specified timeout is expired.
/// </summary>
/// <param name="timeout">
/// A <see cref="TimeSpan"/> that represents the number of milliseconds to wait.</param>
/// <exception cref="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="Int32.MaxValue"/>.</exception>
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern void SpinUntil(TimeSpan timeout);

/// <summary>
/// Spins until the specified timeout is expired.
/// </summary>
/// <param name="millisecondsTimeout">The number of milliseconds to wait.</param>
/// <exception cref="ArgumentOutOfRangeException"><paramref name="millisecondsTimeout"/> is a
/// negative number other than -1, which represents an infinite time-out.</exception>
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern void SpinUntil(int millisecondsTimeout);
}
}
11 changes: 11 additions & 0 deletions nanoFramework.CoreLibrary/System/Threading/Thread.cs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,17 @@ public static void Sleep(TimeSpan timeout)
Sleep((int)tm);
}

/// <summary>
/// Causes a thread to wait the number of times defined by the <paramref name="iterations"/> parameter.
/// </summary>
/// <param name="iterations">A 32-bit signed integer that defines how long a thread is to wait.</param>
/// <remarks>
/// The <see cref="SpinWait"/> method is useful for implementing locks. Classes in the .NET Framework, such as <see cref="Monitor"/> use this method internally. <see cref="SpinWait"/> essentially puts the processor into a very tight loop, with the loop count specified by the <paramref name="iterations"/> parameter. The duration of the wait therefore depends on the speed of the processor.
/// Contrast this with the <see cref="Sleep"/> method. A thread that calls <see cref="Sleep"/> yields the rest of its current slice of processor time, even if the specified interval is zero. Specifying a non-zero interval for <see cref="Sleep"/> removes the thread from consideration by the thread scheduler until the time interval has elapsed.
/// </remarks>
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern void SpinWait(int iterations);

/// <summary>
/// Gets the currently running thread.
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion version.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
"version": "1.10.3-preview.{height}",
"version": "1.10.4-preview.{height}",
"assemblyVersion": {
"precision": "revision"
},
Expand Down

0 comments on commit 2a0e1ee

Please sign in to comment.