diff options
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.cs | 63 |
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); + } } } |