From d30aaca62d40d235a55a445edff2f85b8c56ba26 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Wed, 27 Feb 2019 17:53:25 -0500 Subject: Address PR feedback (clean up style in Thread.CoreCLR.cs) --- .../System.Private.CoreLib.csproj | 1 + .../Runtime/CompilerServices/AsyncMethodBuilder.cs | 4 +- .../shared/System/Threading/ExecutionContext.cs | 40 +-- .../shared/System/Threading/ThreadPool.cs | 2 +- .../src/System/Threading/StackCrawlMark.cs | 19 ++ .../src/System/Threading/Thread.CoreCLR.cs | 313 ++++++++------------- 6 files changed, 160 insertions(+), 219 deletions(-) create mode 100644 src/System.Private.CoreLib/src/System/Threading/StackCrawlMark.cs (limited to 'src/System.Private.CoreLib') diff --git a/src/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/System.Private.CoreLib/System.Private.CoreLib.csproj index 55bf8b40c8..afcfcf763f 100644 --- a/src/System.Private.CoreLib/System.Private.CoreLib.csproj +++ b/src/System.Private.CoreLib/System.Private.CoreLib.csproj @@ -255,6 +255,7 @@ + diff --git a/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncMethodBuilder.cs b/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncMethodBuilder.cs index b760a56f92..f72493edbe 100644 --- a/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncMethodBuilder.cs +++ b/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/AsyncMethodBuilder.cs @@ -1011,7 +1011,7 @@ namespace System.Runtime.CompilerServices // Capture references to Thread Contexts Thread currentThread0 = Thread.CurrentThread; Thread currentThread = currentThread0; - ExecutionContext previousExecutionCtx0 = currentThread0.m_ExecutionContext; + ExecutionContext previousExecutionCtx0 = currentThread0._executionContext; // Store current ExecutionContext and SynchronizationContext as "previousXxx". // This allows us to restore them and undo any Context changes made in stateMachine.MoveNext @@ -1036,7 +1036,7 @@ namespace System.Runtime.CompilerServices } ExecutionContext previousExecutionCtx1 = previousExecutionCtx; - ExecutionContext currentExecutionCtx1 = currentThread1.m_ExecutionContext; + ExecutionContext currentExecutionCtx1 = currentThread1._executionContext; if (previousExecutionCtx1 != currentExecutionCtx1) { ExecutionContext.RestoreChangedContextToThread(currentThread1, previousExecutionCtx1, currentExecutionCtx1); diff --git a/src/System.Private.CoreLib/shared/System/Threading/ExecutionContext.cs b/src/System.Private.CoreLib/shared/System/Threading/ExecutionContext.cs index f7de8fe808..97e45a506b 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/ExecutionContext.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/ExecutionContext.cs @@ -54,7 +54,7 @@ namespace System.Threading public static ExecutionContext Capture() { - ExecutionContext executionContext = Thread.CurrentThread.m_ExecutionContext; + ExecutionContext executionContext = Thread.CurrentThread._executionContext; if (executionContext == null) { executionContext = Default; @@ -84,7 +84,7 @@ namespace System.Threading public static AsyncFlowControl SuppressFlow() { Thread currentThread = Thread.CurrentThread; - ExecutionContext executionContext = currentThread.m_ExecutionContext ?? Default; + ExecutionContext executionContext = currentThread._executionContext ?? Default; if (executionContext.m_isFlowSuppressed) { throw new InvalidOperationException(SR.InvalidOperation_CannotSupressFlowMultipleTimes); @@ -92,7 +92,7 @@ namespace System.Threading executionContext = executionContext.ShallowClone(isFlowSuppressed: true); var asyncFlowControl = new AsyncFlowControl(); - currentThread.m_ExecutionContext = executionContext; + currentThread._executionContext = executionContext; asyncFlowControl.Initialize(currentThread); return asyncFlowControl; } @@ -100,18 +100,18 @@ namespace System.Threading public static void RestoreFlow() { Thread currentThread = Thread.CurrentThread; - ExecutionContext executionContext = currentThread.m_ExecutionContext; + ExecutionContext executionContext = currentThread._executionContext; if (executionContext == null || !executionContext.m_isFlowSuppressed) { throw new InvalidOperationException(SR.InvalidOperation_CannotRestoreUnsupressedFlow); } - currentThread.m_ExecutionContext = executionContext.ShallowClone(isFlowSuppressed: false); + currentThread._executionContext = executionContext.ShallowClone(isFlowSuppressed: false); } public static bool IsFlowSuppressed() { - ExecutionContext executionContext = Thread.CurrentThread.m_ExecutionContext; + ExecutionContext executionContext = Thread.CurrentThread._executionContext; return executionContext != null && executionContext.m_isFlowSuppressed; } @@ -140,7 +140,7 @@ namespace System.Threading // Capture references to Thread Contexts Thread currentThread0 = Thread.CurrentThread; Thread currentThread = currentThread0; - ExecutionContext previousExecutionCtx0 = currentThread0.m_ExecutionContext; + ExecutionContext previousExecutionCtx0 = currentThread0._executionContext; if (previousExecutionCtx0 != null && previousExecutionCtx0.m_isDefault) { // Default is a null ExecutionContext internally @@ -189,7 +189,7 @@ namespace System.Threading } ExecutionContext previousExecutionCtx1 = previousExecutionCtx; - ExecutionContext currentExecutionCtx1 = currentThread1.m_ExecutionContext; + ExecutionContext currentExecutionCtx1 = currentThread1._executionContext; if (currentExecutionCtx1 != previousExecutionCtx1) { RestoreChangedContextToThread(currentThread1, previousExecutionCtx1, currentExecutionCtx1); @@ -210,7 +210,7 @@ namespace System.Threading // Capture references to Thread Contexts Thread currentThread0 = Thread.CurrentThread; Thread currentThread = currentThread0; - ExecutionContext previousExecutionCtx0 = currentThread0.m_ExecutionContext; + ExecutionContext previousExecutionCtx0 = currentThread0._executionContext; if (previousExecutionCtx0 != null && previousExecutionCtx0.m_isDefault) { // Default is a null ExecutionContext internally @@ -259,7 +259,7 @@ namespace System.Threading } ExecutionContext previousExecutionCtx1 = previousExecutionCtx; - ExecutionContext currentExecutionCtx1 = currentThread1.m_ExecutionContext; + ExecutionContext currentExecutionCtx1 = currentThread1._executionContext; if (currentExecutionCtx1 != previousExecutionCtx1) { RestoreChangedContextToThread(currentThread1, previousExecutionCtx1, currentExecutionCtx1); @@ -298,7 +298,7 @@ namespace System.Threading // Enregister threadPoolThread as it crossed EH, and use enregistered variable Thread currentThread = threadPoolThread; - ExecutionContext currentExecutionCtx = currentThread.m_ExecutionContext; + ExecutionContext currentExecutionCtx = currentThread._executionContext; // Restore changed SynchronizationContext back to Default currentThread.SynchronizationContext = null; @@ -322,7 +322,7 @@ namespace System.Threading Debug.Assert(executionContext != null && !executionContext.m_isDefault, "ExecutionContext argument is Default."); // Restore Non-Default context - Thread.CurrentThread.m_ExecutionContext = executionContext; + Thread.CurrentThread._executionContext = executionContext; if (executionContext.HasChangeNotifications) { OnValuesChanged(previousExecutionCtx: null, executionContext); @@ -339,7 +339,7 @@ namespace System.Threading Debug.Assert(contextToRestore != currentContext); // Restore changed ExecutionContext back to previous - currentThread.m_ExecutionContext = contextToRestore; + currentThread._executionContext = contextToRestore; if ((currentContext != null && currentContext.HasChangeNotifications) || (contextToRestore != null && contextToRestore.HasChangeNotifications)) { @@ -352,11 +352,11 @@ namespace System.Threading [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void ResetThreadPoolThread(Thread currentThread) { - ExecutionContext currentExecutionCtx = currentThread.m_ExecutionContext; + ExecutionContext currentExecutionCtx = currentThread._executionContext; // Reset to defaults currentThread.SynchronizationContext = null; - currentThread.m_ExecutionContext = null; + currentThread._executionContext = null; if (currentExecutionCtx != null && currentExecutionCtx.HasChangeNotifications) { @@ -364,7 +364,7 @@ namespace System.Threading // Reset to defaults again without change notifications in case the Change handler changed the contexts currentThread.SynchronizationContext = null; - currentThread.m_ExecutionContext = null; + currentThread._executionContext = null; } } @@ -372,7 +372,7 @@ namespace System.Threading internal static void CheckThreadPoolAndContextsAreDefault() { Debug.Assert(Thread.CurrentThread.IsThreadPoolThread); - Debug.Assert(Thread.CurrentThread.m_ExecutionContext == null, "ThreadPool thread not on Default ExecutionContext."); + Debug.Assert(Thread.CurrentThread._executionContext == null, "ThreadPool thread not on Default ExecutionContext."); Debug.Assert(Thread.CurrentThread.SynchronizationContext == null, "ThreadPool thread not on Default SynchronizationContext."); } @@ -470,7 +470,7 @@ namespace System.Threading internal static object GetLocalValue(IAsyncLocal local) { - ExecutionContext current = Thread.CurrentThread.m_ExecutionContext; + ExecutionContext current = Thread.CurrentThread._executionContext; if (current == null) { return null; @@ -482,7 +482,7 @@ namespace System.Threading internal static void SetLocalValue(IAsyncLocal local, object newValue, bool needChangeNotifications) { - ExecutionContext current = Thread.CurrentThread.m_ExecutionContext; + ExecutionContext current = Thread.CurrentThread._executionContext; object previousValue = null; bool hadPreviousValue = false; @@ -540,7 +540,7 @@ namespace System.Threading } } - Thread.CurrentThread.m_ExecutionContext = + Thread.CurrentThread._executionContext = (!isFlowSuppressed && AsyncLocalValueMap.IsEmpty(newValues)) ? null : // No values, return to Default context new ExecutionContext(newValues, newChangeNotifications, isFlowSuppressed); diff --git a/src/System.Private.CoreLib/shared/System/Threading/ThreadPool.cs b/src/System.Private.CoreLib/shared/System/Threading/ThreadPool.cs index 2dcb7bbbc3..eb402e28f3 100644 --- a/src/System.Private.CoreLib/shared/System/Threading/ThreadPool.cs +++ b/src/System.Private.CoreLib/shared/System/Threading/ThreadPool.cs @@ -558,7 +558,7 @@ namespace System.Threading Thread currentThread = tl.currentThread; // Start on clean ExecutionContext and SynchronizationContext - currentThread.m_ExecutionContext = null; + currentThread._executionContext = null; currentThread.SynchronizationContext = null; // diff --git a/src/System.Private.CoreLib/src/System/Threading/StackCrawlMark.cs b/src/System.Private.CoreLib/src/System/Threading/StackCrawlMark.cs new file mode 100644 index 0000000000..7323d1dced --- /dev/null +++ b/src/System.Private.CoreLib/src/System/Threading/StackCrawlMark.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Threading +{ + /// + /// declaring a local var of this enum type and passing it by ref into a function that needs to do a + /// stack crawl will both prevent inlining of the callee and pass an ESP point to stack crawl to + /// Declaring these in EH clauses is illegal; they must declared in the main method body + /// + internal enum StackCrawlMark + { + LookForMe = 0, + LookForMyCaller = 1, + LookForMyCallersCaller = 2, + LookForThread = 3 + } +} diff --git a/src/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs b/src/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs index a5e8f2ad65..e0845b4384 100644 --- a/src/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs +++ b/src/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System; using System.Diagnostics; using System.Globalization; using System.Runtime.CompilerServices; @@ -11,7 +10,7 @@ using System.Runtime.InteropServices; namespace System.Threading { - internal class ThreadHelper + internal sealed class ThreadHelper { private Delegate _start; internal CultureInfo _startCulture; @@ -37,9 +36,9 @@ namespace System.Threading t.InitializeCulture(); - if (t._start is ThreadStart) + if (t._start is ThreadStart threadStart) { - ((ThreadStart)t._start)(); + threadStart(); } else { @@ -95,13 +94,13 @@ namespace System.Threading } } - internal struct ThreadHandle + internal readonly struct ThreadHandle { - private IntPtr m_ptr; + private readonly IntPtr _ptr; internal ThreadHandle(IntPtr pThread) { - m_ptr = pThread; + _ptr = pThread; } } @@ -112,13 +111,13 @@ namespace System.Threading ** ThreadBaseObject to maintain alignment between the two classes. ** DON'T CHANGE THESE UNLESS YOU MODIFY ThreadBaseObject in vm\object.h =========================================================================*/ - internal ExecutionContext m_ExecutionContext; // this call context follows the logical thread - private SynchronizationContext m_SynchronizationContext; // On CoreCLR, this is maintained separately from ExecutionContext + internal ExecutionContext _executionContext; // this call context follows the logical thread + private SynchronizationContext _synchronizationContext; // On CoreCLR, this is maintained separately from ExecutionContext - private string m_Name; - private Delegate m_Delegate; // Delegate + private string _name; + private Delegate _delegate; // Delegate - private object m_ThreadStartArg; + private object _threadStartArg; /*========================================================================= ** The base implementation of Thread is all native. The following fields @@ -126,95 +125,73 @@ namespace System.Threading ** space so the thread object may be allocated. DON'T CHANGE THESE UNLESS ** YOU MODIFY ThreadBaseObject in vm\object.h =========================================================================*/ -#pragma warning disable 169 -#pragma warning disable 414 // These fields are not used from managed. +#pragma warning disable 169 // These fields are not used from managed. // IntPtrs need to be together, and before ints, because IntPtrs are 64-bit - // fields on 64-bit platforms, where they will be sorted together. + // fields on 64-bit platforms, where they will be sorted together. - private IntPtr DONT_USE_InternalThread; // Pointer - private int m_Priority; // INT32 + private IntPtr _DONT_USE_InternalThread; // Pointer + private int _priority; // INT32 // The following field is required for interop with the VS Debugger // Prior to making any changes to this field, please reach out to the VS Debugger // team to make sure that your changes are not going to prevent the debugger // from working. - private int _managedThreadId; // INT32 - -#pragma warning restore 414 + private int _managedThreadId; // INT32 #pragma warning restore 169 [ThreadStatic] private static Thread t_currentThread; - // Adding an empty default ctor for annotation purposes - internal Thread() { } + private Thread() { } - /*========================================================================= - ** Creates a new Thread object which will begin execution at - ** start.ThreadStart on a new thread when the Start method is called. - ** - ** Exceptions: ArgumentNullException if start == null. - =========================================================================*/ - private void Create(ThreadStart start) - { - SetStartHelper((Delegate)start, 0); //0 will setup Thread with default stackSize - } + private void Create(ThreadStart start) => + SetStartHelper((Delegate)start, 0); // 0 will setup Thread with default stackSize - private void Create(ThreadStart start, int maxStackSize) - { + private void Create(ThreadStart start, int maxStackSize) => SetStartHelper((Delegate)start, maxStackSize); - } - private void Create(ParameterizedThreadStart start) - { + private void Create(ParameterizedThreadStart start) => SetStartHelper((Delegate)start, 0); - } - private void Create(ParameterizedThreadStart start, int maxStackSize) - { + private void Create(ParameterizedThreadStart start, int maxStackSize) => SetStartHelper((Delegate)start, maxStackSize); - } public extern int ManagedThreadId { - [MethodImplAttribute(MethodImplOptions.InternalCall)] + [MethodImpl(MethodImplOptions.InternalCall)] get; } - // Returns handle for interop with EE. The handle is guaranteed to be non-null. + /// Returns handle for interop with EE. The handle is guaranteed to be non-null. internal ThreadHandle GetNativeHandle() { - IntPtr thread = DONT_USE_InternalThread; + IntPtr thread = _DONT_USE_InternalThread; - // This should never happen under normal circumstances. m_assembly is always assigned before it is handed out to the user. - // There are ways how to create an uninitialized objects through remoting, etc. Avoid AVing in the EE by throwing a nice - // exception here. + // This should never happen under normal circumstances. if (thread == IntPtr.Zero) + { throw new ArgumentException(null, SR.Argument_InvalidHandle); + } return new ThreadHandle(thread); } - - /*========================================================================= - ** Spawns off a new thread which will begin executing at the ThreadStart - ** method on the IThreadable interface passed in the constructor. Once the - ** thread is dead, it cannot be restarted with another call to Start. - ** - ** Exceptions: ThreadStateException if the thread has already been started. - =========================================================================*/ + /// + /// Spawns off a new thread which will begin executing at the ThreadStart + /// method on the IThreadable interface passed in the constructor. Once the + /// thread is dead, it cannot be restarted with another call to Start. + /// public void Start(object parameter) { - //In the case of a null delegate (second call to start on same thread) - // StartInternal method will take care of the error reporting - if (m_Delegate is ThreadStart) + // In the case of a null delegate (second call to start on same thread) + // StartInternal method will take care of the error reporting. + if (_delegate is ThreadStart) { - //We expect the thread to be setup with a ParameterizedThreadStart - // if this constructor is called. - //If we got here then that wasn't the case + // We expect the thread to be setup with a ParameterizedThreadStart if this Start is called. throw new InvalidOperationException(SR.InvalidOperation_ThreadWrongThreadStart); } - m_ThreadStartArg = parameter; + + _threadStartArg = parameter; Start(); } @@ -228,11 +205,11 @@ namespace System.Threading // Attach current thread's security principal object to the new // thread. Be careful not to bind the current thread to a principal // if it's not already bound. - if (m_Delegate != null) + if (_delegate != null) { // If we reach here with a null delegate, something is broken. But we'll let the StartInternal method take care of // reporting an error. Just make sure we don't try to dereference a null delegate. - ThreadHelper t = (ThreadHelper)(m_Delegate.Target); + ThreadHelper t = (ThreadHelper)_delegate.Target; ExecutionContext ec = ExecutionContext.Capture(); t.SetExecutionContextHelper(ec); } @@ -242,9 +219,9 @@ namespace System.Threading private void SetCultureOnUnstartedThreadNoCheck(CultureInfo value, bool uiCulture) { - Debug.Assert(m_Delegate != null); + Debug.Assert(_delegate != null); - ThreadHelper t = (ThreadHelper)(m_Delegate.Target); + ThreadHelper t = (ThreadHelper)(_delegate.Target); if (uiCulture) { t._startUICulture = value; @@ -259,72 +236,57 @@ namespace System.Threading internal SynchronizationContext SynchronizationContext { - get { return m_SynchronizationContext; } - set { m_SynchronizationContext = value; } + get => _synchronizationContext; + set => _synchronizationContext = value; } - [MethodImplAttribute(MethodImplOptions.InternalCall)] + [MethodImpl(MethodImplOptions.InternalCall)] private extern void StartInternal(); - - // Helper method to get a logical thread ID for StringBuilder (for - // correctness) and for FileStream's async code path (for perf, to - // avoid creating a Thread instance). + // Invoked by VM. Helper method to get a logical thread ID for StringBuilder (for + // correctness) and for FileStream's async code path (for perf, to avoid creating + // a Thread instance). [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern IntPtr InternalGetCurrentThread(); + private static extern IntPtr InternalGetCurrentThread(); - /*========================================================================= - ** Suspends the current thread for timeout milliseconds. If timeout == 0, - ** forces the thread to give up the remainder of its timeslice. If timeout - ** == Timeout.Infinite, no timeout will occur. - ** - ** Exceptions: ArgumentException if timeout < -1 (Timeout.Infinite). - ** ThreadInterruptedException if the thread is interrupted while sleeping. - =========================================================================*/ - [MethodImplAttribute(MethodImplOptions.InternalCall)] + /// + /// Suspends the current thread for timeout milliseconds. If timeout == 0, + /// forces the thread to give up the remainder of its timeslice. If timeout + /// == Timeout.Infinite, no timeout will occur. + /// + [MethodImpl(MethodImplOptions.InternalCall)] private static extern void SleepInternal(int millisecondsTimeout); - public static void Sleep(int millisecondsTimeout) - { - SleepInternal(millisecondsTimeout); - } - - /* wait for a length of time proportional to 'iterations'. Each iteration is should - only take a few machine instructions. Calling this API is preferable to coding - a explicit busy loop because the hardware can be informed that it is busy waiting. */ + public static void Sleep(int millisecondsTimeout) => SleepInternal(millisecondsTimeout); - [MethodImplAttribute(MethodImplOptions.InternalCall)] + /// + /// Wait for a length of time proportional to 'iterations'. Each iteration is should + /// only take a few machine instructions. Calling this API is preferable to coding + /// a explicit busy loop because the hardware can be informed that it is busy waiting. + /// + [MethodImpl(MethodImplOptions.InternalCall)] private static extern void SpinWaitInternal(int iterations); - public static void SpinWait(int iterations) - { - SpinWaitInternal(iterations); - } + public static void SpinWait(int iterations) => SpinWaitInternal(iterations); [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] private static extern bool YieldInternal(); - public static bool Yield() - { - return YieldInternal(); - } + public static bool Yield() => YieldInternal(); public static Thread CurrentThread => t_currentThread ?? InitializeCurrentThread(); [MethodImpl(MethodImplOptions.NoInlining)] - private static Thread InitializeCurrentThread() - { - return (t_currentThread = GetCurrentThreadNative()); - } + private static Thread InitializeCurrentThread() => (t_currentThread = GetCurrentThreadNative()); - [MethodImplAttribute(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] + [MethodImpl(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] private static extern Thread GetCurrentThreadNative(); private void SetStartHelper(Delegate start, int maxStackSize) { Debug.Assert(maxStackSize >= 0); - ThreadHelper threadStartCallBack = new ThreadHelper(start); + var threadStartCallBack = new ThreadHelper(start); if (start is ThreadStart) { SetStart(new ThreadStart(threadStartCallBack.ThreadStart), maxStackSize); @@ -335,45 +297,35 @@ namespace System.Threading } } - /*========================================================================= - ** PRIVATE Sets the IThreadable interface for the thread. Assumes that - ** start != null. - =========================================================================*/ - [MethodImplAttribute(MethodImplOptions.InternalCall)] + /// Sets the IThreadable interface for the thread. Assumes that start != null. + [MethodImpl(MethodImplOptions.InternalCall)] private extern void SetStart(Delegate start, int maxStackSize); - /*========================================================================= - ** Clean up the thread when it goes away. - =========================================================================*/ - ~Thread() - { - // Delegate to the unmanaged portion. - InternalFinalize(); - } + /// Clean up the thread when it goes away. + ~Thread() => InternalFinalize(); // Delegate to the unmanaged portion. - [MethodImplAttribute(MethodImplOptions.InternalCall)] + [MethodImpl(MethodImplOptions.InternalCall)] private extern void InternalFinalize(); #if FEATURE_COMINTEROP_APARTMENT_SUPPORT - [MethodImplAttribute(MethodImplOptions.InternalCall)] + [MethodImpl(MethodImplOptions.InternalCall)] private extern void StartupSetApartmentStateInternal(); #endif // FEATURE_COMINTEROP_APARTMENT_SUPPORT - // Retrieves the name of the thread. - // + /// Retrieves the name of the thread. public string Name { - get - { - return m_Name; - } + get => _name; set { lock (this) { - if (m_Name != null) + if (_name != null) + { throw new InvalidOperationException(SR.InvalidOperation_WriteOnce); - m_Name = value; + } + + _name = value; InformThreadNameChange(GetNativeHandle(), value, (value != null) ? value.Length : 0); } @@ -383,25 +335,21 @@ namespace System.Threading [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] private static extern void InformThreadNameChange(ThreadHandle t, string name, int len); - /*========================================================================= - ** Returns true if the thread has been started and is not dead. - =========================================================================*/ + /// Returns true if the thread has been started and is not dead. public extern bool IsAlive { [MethodImpl(MethodImplOptions.InternalCall)] get; } - /*========================================================================= - ** Return whether or not this thread is a background thread. Background - ** threads do not affect when the Execution Engine shuts down. - ** - ** Exceptions: ThreadStateException if the thread is dead. - =========================================================================*/ + /// + /// Return whether or not this thread is a background thread. Background + /// threads do not affect when the Execution Engine shuts down. + /// public bool IsBackground { - get { return IsBackgroundNative(); } - set { SetBackgroundNative(value); } + get => IsBackgroundNative(); + set => SetBackgroundNative(value); } [MethodImpl(MethodImplOptions.InternalCall)] @@ -410,24 +358,18 @@ namespace System.Threading [MethodImpl(MethodImplOptions.InternalCall)] private extern void SetBackgroundNative(bool isBackground); - /*========================================================================= - ** Returns true if the thread is a threadpool thread. - =========================================================================*/ + /// Returns true if the thread is a threadpool thread. public extern bool IsThreadPoolThread { [MethodImpl(MethodImplOptions.InternalCall)] get; } - /*========================================================================= - ** Returns the priority of the thread. - ** - ** Exceptions: ThreadStateException if the thread is dead. - =========================================================================*/ + /// Returns the priority of the thread. public ThreadPriority Priority { - get { return (ThreadPriority)GetPriorityNative(); } - set { SetPriorityNative((int)value); } + get => (ThreadPriority)GetPriorityNative(); + set => SetPriorityNative((int)value); } [MethodImpl(MethodImplOptions.InternalCall)] @@ -436,55 +378,38 @@ namespace System.Threading [MethodImpl(MethodImplOptions.InternalCall)] private extern void SetPriorityNative(int priority); - /*========================================================================= - ** Returns the operating system identifier for the current thread. - =========================================================================*/ - internal static ulong CurrentOSThreadId - { - get - { - return GetCurrentOSThreadId(); - } - } + /// Returns the operating system identifier for the current thread. + internal static ulong CurrentOSThreadId => GetCurrentOSThreadId(); [DllImport(JitHelpers.QCall)] private static extern ulong GetCurrentOSThreadId(); - /*========================================================================= - ** Return the thread state as a consistent set of bits. This is more - ** general then IsAlive or IsBackground. - =========================================================================*/ - public ThreadState ThreadState - { - get { return (ThreadState)GetThreadStateNative(); } - } + /// + /// Return the thread state as a consistent set of bits. This is more + /// general then IsAlive or IsBackground. + /// + public ThreadState ThreadState => (ThreadState)GetThreadStateNative(); [MethodImpl(MethodImplOptions.InternalCall)] private extern int GetThreadStateNative(); - public ApartmentState GetApartmentState() - { + public ApartmentState GetApartmentState() => #if FEATURE_COMINTEROP_APARTMENT_SUPPORT - return (ApartmentState)GetApartmentStateNative(); + (ApartmentState)GetApartmentStateNative(); #else // !FEATURE_COMINTEROP_APARTMENT_SUPPORT - Debug.Assert(false); // the Thread class in CoreFX should have handled this case - return ApartmentState.MTA; + ApartmentState.MTA; #endif // FEATURE_COMINTEROP_APARTMENT_SUPPORT - } - /*========================================================================= - ** An unstarted thread can be marked to indicate that it will host a - ** single-threaded or multi-threaded apartment. - =========================================================================*/ - public bool TrySetApartmentStateUnchecked(ApartmentState state) - { + /// + /// An unstarted thread can be marked to indicate that it will host a + /// single-threaded or multi-threaded apartment. + /// + public bool TrySetApartmentStateUnchecked(ApartmentState state) => #if FEATURE_COMINTEROP_APARTMENT_SUPPORT - return SetApartmentStateHelper(state, false); + SetApartmentStateHelper(state, false); #else // !FEATURE_COMINTEROP_APARTMENT_SUPPORT - Debug.Assert(false); // the Thread class in CoreFX should have handled this case - return false; + false; #endif // FEATURE_COMINTEROP_APARTMENT_SUPPORT - } #if FEATURE_COMINTEROP_APARTMENT_SUPPORT internal bool SetApartmentStateHelper(ApartmentState state, bool fireMDAOnMismatch) @@ -496,10 +421,14 @@ namespace System.Threading // report the thread as implicitly in the MTA if any // other thread in the process is CoInitialized. if ((state == System.Threading.ApartmentState.Unknown) && (retState == System.Threading.ApartmentState.MTA)) + { return true; + } if (retState != state) + { return false; + } return true; } @@ -568,7 +497,7 @@ namespace System.Threading } } - [MethodImplAttribute(MethodImplOptions.InternalCall)] + [MethodImpl(MethodImplOptions.InternalCall)] private static extern int GetCurrentProcessorNumber(); // The upper bits of t_currentProcessorIdCache are the currentProcessorId. The lower bits of @@ -610,7 +539,10 @@ namespace System.Threading { int currentProcessorIdCache = t_currentProcessorIdCache--; if ((currentProcessorIdCache & ProcessorIdCacheCountDownMask) == 0) + { return RefreshCurrentProcessorId(); + } + return (currentProcessorIdCache >> ProcessorIdCacheShift); } @@ -620,15 +552,4 @@ namespace System.Threading // called internally from the ThreadPool in NotifyWorkItemComplete. } } // End of class Thread - - // declaring a local var of this enum type and passing it by ref into a function that needs to do a - // stack crawl will both prevent inlining of the callee and pass an ESP point to stack crawl to - // Declaring these in EH clauses is illegal; they must declared in the main method body - internal enum StackCrawlMark - { - LookForMe = 0, - LookForMyCaller = 1, - LookForMyCallersCaller = 2, - LookForThread = 3 - } } -- cgit v1.2.3