Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeThread.cs')
-rw-r--r--src/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeThread.cs63
1 files changed, 51 insertions, 12 deletions
diff --git a/src/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeThread.cs b/src/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeThread.cs
index b21d9ced8..b3e9a14fe 100644
--- a/src/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeThread.cs
+++ b/src/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeThread.cs
@@ -7,6 +7,7 @@ using System;
using System.Diagnostics;
using System.Globalization;
using System.Runtime;
+using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
@@ -79,6 +80,14 @@ namespace Internal.Runtime.Augments
}
}
+ internal static ulong CurrentOSThreadId
+ {
+ get
+ {
+ return RuntimeImports.RhCurrentOSThreadId();
+ }
+ }
+
// Slow path executed once per thread
private static RuntimeThread InitializeExistingThread(bool threadPoolThread)
{
@@ -103,7 +112,7 @@ namespace Internal.Runtime.Augments
if (threadPoolThread)
{
- RoInitialize();
+ InitializeCom();
}
return currentThread;
@@ -142,16 +151,6 @@ namespace Internal.Runtime.Augments
}
/// <summary>
- /// Ensures the Windows Runtime is initialized on the current thread.
- /// </summary>
- internal static void RoInitialize()
- {
-#if ENABLE_WINRT
- Interop.WinRT.RoInitialize();
-#endif
- }
-
- /// <summary>
/// Returns true if the underlying OS thread has been created and started execution of managed code.
/// </summary>
private bool HasStarted()
@@ -370,6 +369,7 @@ namespace Internal.Runtime.Augments
return JoinInternal(millisecondsTimeout);
}
+ [MethodImpl(MethodImplOptions.NoInlining)] // Slow path method. Make sure that the caller frame does not pay for PInvoke overhead.
public static void Sleep(int millisecondsTimeout) => SleepInternal(VerifyTimeoutMilliseconds(millisecondsTimeout));
/// <summary>
@@ -381,6 +381,8 @@ namespace Internal.Runtime.Augments
internal static readonly int OptimalMaxSpinWaitsPerSpinIteration = 64;
public static void SpinWait(int iterations) => RuntimeImports.RhSpinWait(iterations);
+
+ [MethodImpl(MethodImplOptions.NoInlining)] // Slow path method. Make sure that the caller frame does not pay for PInvoke overhead.
public static bool Yield() => RuntimeImports.RhYield();
public void Start() => StartInternal(null);
@@ -455,7 +457,7 @@ namespace Internal.Runtime.Augments
{
t_currentThread = thread;
System.Threading.ManagedThreadId.SetForCurrentThread(thread._managedThreadId);
- RoInitialize();
+ thread.InitializeComOnNewThread();
}
catch (OutOfMemoryException)
{
@@ -491,5 +493,42 @@ namespace Internal.Runtime.Augments
thread.SetThreadStateBit(ThreadState.Stopped);
}
}
+
+ // The upper bits of t_currentProcessorIdCache are the currentProcessorId. The lower bits of
+ // the t_currentProcessorIdCache are counting down to get it periodically refreshed.
+ // TODO: Consider flushing the currentProcessorIdCache on Wait operations or similar
+ // actions that are likely to result in changing the executing core
+ [ThreadStatic]
+ private static int t_currentProcessorIdCache;
+
+ private const int ProcessorIdCacheShift = 16;
+ private const int ProcessorIdCacheCountDownMask = (1 << ProcessorIdCacheShift) - 1;
+ private const int ProcessorIdRefreshRate = 5000;
+
+ private static int RefreshCurrentProcessorId()
+ {
+ int currentProcessorId = ComputeCurrentProcessorId();
+
+ // Add offset to make it clear that it is not guaranteed to be 0-based processor number
+ currentProcessorId += 100;
+
+ Debug.Assert(ProcessorIdRefreshRate <= ProcessorIdCacheCountDownMask);
+
+ // Mask with int.MaxValue to ensure the execution Id is not negative
+ t_currentProcessorIdCache = ((currentProcessorId << ProcessorIdCacheShift) & int.MaxValue) + ProcessorIdRefreshRate;
+
+ return currentProcessorId;
+ }
+
+ // Cached processor id used as a hint for which per-core stack to access. It is periodically
+ // refreshed to trail the actual thread core affinity.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int GetCurrentProcessorId()
+ {
+ int currentProcessorIdCache = t_currentProcessorIdCache--;
+ if ((currentProcessorIdCache & ProcessorIdCacheCountDownMask) == 0)
+ return RefreshCurrentProcessorId();
+ return (currentProcessorIdCache >> ProcessorIdCacheShift);
+ }
}
}