From 72f147ef313007e227b9fddfe741d51aec31a9f7 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Fri, 6 Sep 2024 17:24:15 -0700 Subject: [PATCH 1/8] Convert Thread.IsAlive property --- .../src/System/Threading/Thread.CoreCLR.cs | 13 ++++++-- src/coreclr/vm/comsynchronizable.cpp | 30 +++++++------------ src/coreclr/vm/comsynchronizable.h | 2 +- src/coreclr/vm/ecalllist.h | 1 - src/coreclr/vm/qcallentrypoints.cpp | 1 + 5 files changed, 23 insertions(+), 24 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs index 486e5a505abeb7..b008d9165bc180 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs @@ -175,12 +175,19 @@ partial void ThreadNameChanged(string? value) private static partial void InformThreadNameChange(ThreadHandle t, string? name, int len); /// Returns true if the thread has been started and is not dead. - public extern bool IsAlive + public bool IsAlive { - [MethodImpl(MethodImplOptions.InternalCall)] - get; + get + { + Thread _this = this; + return IsAliveWorker(ObjectHandleOnStack.Create(ref _this)); + } } + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ThreadNative_IsAlive")] + [return: MarshalAs(UnmanagedType.Bool)] + private static partial bool IsAliveWorker(ObjectHandleOnStack t); + /// /// Return whether or not this thread is a background thread. Background /// threads do not affect when the Execution Engine shuts down. diff --git a/src/coreclr/vm/comsynchronizable.cpp b/src/coreclr/vm/comsynchronizable.cpp index 73cc949ec66d5c..0d3612e2c12529 100644 --- a/src/coreclr/vm/comsynchronizable.cpp +++ b/src/coreclr/vm/comsynchronizable.cpp @@ -362,36 +362,28 @@ extern "C" void QCALLTYPE ThreadNative_SetPriority(QCall::ObjectHandleOnStack th END_QCALL; } -FCIMPL1(FC_BOOL_RET, ThreadNative::IsAlive, ThreadBaseObject* pThisUNSAFE) +extern "C" BOOL QCALLTYPE ThreadNative_IsAlive(QCall::ObjectHandleOnStack t) { - FCALL_CONTRACT; + QCALL_CONTRACT; - if (pThisUNSAFE==NULL) - FCThrowRes(kNullReferenceException, W("NullReference_This")); + BOOL ret = FALSE; - THREADBASEREF thisRef(pThisUNSAFE); - BOOL ret = false; + BEGIN_QCALL; - // Keep managed Thread object alive, since the native object's - // lifetime is tied to the managed object's finalizer. And with - // resurrection, it may be possible to get a dangling pointer here - - // consider both protecting thisRef and setting the managed object's - // Thread* to NULL in the GC's ScanForFinalization method. - HELPER_METHOD_FRAME_BEGIN_RET_1(thisRef); + GCX_COOP(); - Thread *thread = thisRef->GetInternal(); + if (t.Get() == NULL) + COMPlusThrow(kNullReferenceException, W("NullReference_This")); - if (thread == 0) + Thread* thread = ((THREADBASEREF)t.Get())->GetInternal(); + if (thread == NULL) COMPlusThrow(kThreadStateException, IDS_EE_THREAD_CANNOT_GET); ret = ThreadIsRunning(thread); - HELPER_METHOD_POLL(); - HELPER_METHOD_FRAME_END(); - - FC_RETURN_BOOL(ret); + END_QCALL; + return ret; } -FCIMPLEND NOINLINE static Object* GetCurrentThreadHelper() { diff --git a/src/coreclr/vm/comsynchronizable.h b/src/coreclr/vm/comsynchronizable.h index 9180216deeea90..1b8c38acf71758 100644 --- a/src/coreclr/vm/comsynchronizable.h +++ b/src/coreclr/vm/comsynchronizable.h @@ -52,7 +52,6 @@ friend class ThreadBaseObject; ThreadAbortRequested = 128, }; - static FCDECL1(FC_BOOL_RET, IsAlive, ThreadBaseObject* pThisUNSAFE); static FCDECL1(void, Initialize, ThreadBaseObject* pThisUNSAFE); static FCDECL1(FC_BOOL_RET, GetIsBackground, ThreadBaseObject* pThisUNSAFE); static FCDECL1(INT32, GetThreadState, ThreadBaseObject* pThisUNSAFE); @@ -79,6 +78,7 @@ friend class ThreadBaseObject; extern "C" void QCALLTYPE ThreadNative_Start(QCall::ThreadHandle thread, int threadStackSize, int priority, PCWSTR pThreadName); extern "C" void QCALLTYPE ThreadNative_SetPriority(QCall::ObjectHandleOnStack thread, INT32 iPriority); +extern "C" BOOL QCALLTYPE ThreadNative_IsAlive(QCall::ObjectHandleOnStack t); extern "C" void QCALLTYPE ThreadNative_SetIsBackground(QCall::ThreadHandle thread, BOOL value); extern "C" void QCALLTYPE ThreadNative_InformThreadNameChange(QCall::ThreadHandle thread, LPCWSTR name, INT32 len); extern "C" BOOL QCALLTYPE ThreadNative_YieldThread(); diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index 2b065fd3380341..10602368ba7da0 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -301,7 +301,6 @@ FCFuncStart(gThreadFuncs) FCFuncElement("Initialize", ThreadNative::Initialize) FCFuncElement("GetCurrentThreadNative", ThreadNative::GetCurrentThread) FCFuncElement("InternalFinalize", ThreadNative::Finalize) - FCFuncElement("get_IsAlive", ThreadNative::IsAlive) FCFuncElement("GetIsBackground", ThreadNative::GetIsBackground) FCFuncElement("get_IsThreadPoolThread", ThreadNative::IsThreadpoolThread) FCFuncElement("set_IsThreadPoolThread", ThreadNative::SetIsThreadpoolThread) diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index 2d2345ca214c12..4b813b7c2f0fcc 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -235,6 +235,7 @@ static const Entry s_QCall[] = DllImportEntry(AppDomain_CreateDynamicAssembly) DllImportEntry(ThreadNative_Start) DllImportEntry(ThreadNative_SetPriority) + DllImportEntry(ThreadNative_IsAlive) DllImportEntry(ThreadNative_SetIsBackground) DllImportEntry(ThreadNative_InformThreadNameChange) DllImportEntry(ThreadNative_YieldThread) From b072c8c2d1d0b29e4c05828235f532c656662c19 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Fri, 6 Sep 2024 19:00:30 -0700 Subject: [PATCH 2/8] Convert Thread.GetCurrentThread() --- .../src/System/Threading/Thread.CoreCLR.cs | 19 +++++++++- src/coreclr/vm/comsynchronizable.cpp | 30 ++++++--------- src/coreclr/vm/comsynchronizable.h | 1 + src/coreclr/vm/ecalllist.h | 2 +- src/coreclr/vm/qcallentrypoints.cpp | 1 + src/coreclr/vm/threads.h | 38 +++++++++---------- 6 files changed, 49 insertions(+), 42 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs index b008d9165bc180..d20908cb4f1d55 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs @@ -151,10 +151,25 @@ public static void SpinWait(int iterations) public static bool Yield() => YieldInternal() != Interop.BOOL.FALSE; [MethodImpl(MethodImplOptions.NoInlining)] - private static Thread InitializeCurrentThread() => t_currentThread = GetCurrentThreadNative(); + private static Thread InitializeCurrentThread() + { + t_currentThread = GetCurrentThread() ?? GetCurrentThreadWorker(); + return t_currentThread; + + [MethodImpl(MethodImplOptions.NoInlining)] + static Thread GetCurrentThreadWorker() + { + Thread? thread = null; + GetCurrentThreadSlow(ObjectHandleOnStack.Create(ref thread)); + return thread!; + } + } [MethodImpl(MethodImplOptions.InternalCall)] - private static extern Thread GetCurrentThreadNative(); + private static extern Thread GetCurrentThread(); + + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ThreadNative_GetCurrentThreadSlow")] + private static partial void GetCurrentThreadSlow(ObjectHandleOnStack thread); [MethodImpl(MethodImplOptions.InternalCall)] private extern void Initialize(); diff --git a/src/coreclr/vm/comsynchronizable.cpp b/src/coreclr/vm/comsynchronizable.cpp index 0d3612e2c12529..5439f1e4e2bfa6 100644 --- a/src/coreclr/vm/comsynchronizable.cpp +++ b/src/coreclr/vm/comsynchronizable.cpp @@ -385,32 +385,24 @@ extern "C" BOOL QCALLTYPE ThreadNative_IsAlive(QCall::ObjectHandleOnStack t) return ret; } -NOINLINE static Object* GetCurrentThreadHelper() +FCIMPL0(Object*, ThreadNative::GetCurrentThread) { FCALL_CONTRACT; - FC_INNER_PROLOG(ThreadNative::GetCurrentThread); - OBJECTREF refRetVal = NULL; - - HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_1(Frame::FRAME_ATTR_EXACT_DEPTH|Frame::FRAME_ATTR_CAPTURE_DEPTH_2, refRetVal); - refRetVal = GetThread()->GetExposedObject(); - HELPER_METHOD_FRAME_END(); - - FC_INNER_EPILOG(); - return OBJECTREFToObject(refRetVal); + return OBJECTREFToObject(GetThread()->GetExposedObjectRaw()); } +FCIMPLEND -FCIMPL0(Object*, ThreadNative::GetCurrentThread) +extern "C" void QCALLTYPE ThreadNative_GetCurrentThreadSlow(QCall::ObjectHandleOnStack thread) { - FCALL_CONTRACT; - OBJECTHANDLE ExposedObject = GetThread()->m_ExposedObject; - _ASSERTE(ExposedObject != 0); //Thread's constructor always initializes its GCHandle - Object* result = *((Object**) ExposedObject); - if (result != 0) - return result; + QCALL_CONTRACT; + + BEGIN_QCALL; - FC_INNER_RETURN(Object*, GetCurrentThreadHelper()); + GCX_COOP(); + thread.Set(GetThread()->GetExposedObject()); + + END_QCALL; } -FCIMPLEND extern "C" UINT64 QCALLTYPE ThreadNative_GetCurrentOSThreadId() { diff --git a/src/coreclr/vm/comsynchronizable.h b/src/coreclr/vm/comsynchronizable.h index 1b8c38acf71758..c84dfc4ea8b857 100644 --- a/src/coreclr/vm/comsynchronizable.h +++ b/src/coreclr/vm/comsynchronizable.h @@ -79,6 +79,7 @@ friend class ThreadBaseObject; extern "C" void QCALLTYPE ThreadNative_Start(QCall::ThreadHandle thread, int threadStackSize, int priority, PCWSTR pThreadName); extern "C" void QCALLTYPE ThreadNative_SetPriority(QCall::ObjectHandleOnStack thread, INT32 iPriority); extern "C" BOOL QCALLTYPE ThreadNative_IsAlive(QCall::ObjectHandleOnStack t); +extern "C" void QCALLTYPE ThreadNative_GetCurrentThreadSlow(QCall::ObjectHandleOnStack thread); extern "C" void QCALLTYPE ThreadNative_SetIsBackground(QCall::ThreadHandle thread, BOOL value); extern "C" void QCALLTYPE ThreadNative_InformThreadNameChange(QCall::ThreadHandle thread, LPCWSTR name, INT32 len); extern "C" BOOL QCALLTYPE ThreadNative_YieldThread(); diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index 10602368ba7da0..ed50ab530fe1a4 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -299,7 +299,7 @@ FCFuncEnd() FCFuncStart(gThreadFuncs) FCFuncElement("Initialize", ThreadNative::Initialize) - FCFuncElement("GetCurrentThreadNative", ThreadNative::GetCurrentThread) + FCFuncElement("GetCurrentThread", ThreadNative::GetCurrentThread) FCFuncElement("InternalFinalize", ThreadNative::Finalize) FCFuncElement("GetIsBackground", ThreadNative::GetIsBackground) FCFuncElement("get_IsThreadPoolThread", ThreadNative::IsThreadpoolThread) diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index 4b813b7c2f0fcc..8bab2451dd64d3 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -236,6 +236,7 @@ static const Entry s_QCall[] = DllImportEntry(ThreadNative_Start) DllImportEntry(ThreadNative_SetPriority) DllImportEntry(ThreadNative_IsAlive) + DllImportEntry(ThreadNative_GetCurrentThreadSlow) DllImportEntry(ThreadNative_SetIsBackground) DllImportEntry(ThreadNative_InformThreadNameChange) DllImportEntry(ThreadNative_YieldThread) diff --git a/src/coreclr/vm/threads.h b/src/coreclr/vm/threads.h index f3b7894c3dea64..44a537e7fe9050 100644 --- a/src/coreclr/vm/threads.h +++ b/src/coreclr/vm/threads.h @@ -468,7 +468,6 @@ class Thread friend class ThreadSuspend; friend class SyncBlock; friend struct PendingSync; - friend class ThreadNative; #ifdef _DEBUG friend class EEContract; #endif @@ -2706,6 +2705,24 @@ class Thread #endif // TRACK_SYNC + // Access to thread handle and ThreadId. + HANDLE GetThreadHandle() + { + LIMITED_METHOD_CONTRACT; +#if defined(_DEBUG) && !defined(DACCESS_COMPILE) + { + CounterHolder handleHolder(&m_dwThreadHandleBeingUsed); + HANDLE handle = m_ThreadHandle; + _ASSERTE ( handle == INVALID_HANDLE_VALUE + || m_OSThreadId == 0 + || m_OSThreadId == 0xbaadf00d + || ::MatchThreadHandleToOsId(handle, (DWORD)m_OSThreadId) ); + } +#endif + DACCOP_IGNORE(FieldAccess, "Treated as raw address, no marshaling is necessary"); + return m_ThreadHandle; + } + private: // For suspends: CLREvent m_DebugSuspendEvent; @@ -2729,25 +2746,6 @@ class Thread return walk; } - // Access to thread handle and ThreadId. - HANDLE GetThreadHandle() - { - LIMITED_METHOD_CONTRACT; -#if defined(_DEBUG) && !defined(DACCESS_COMPILE) - { - CounterHolder handleHolder(&m_dwThreadHandleBeingUsed); - HANDLE handle = m_ThreadHandle; - _ASSERTE ( handle == INVALID_HANDLE_VALUE - || m_OSThreadId == 0 - || m_OSThreadId == 0xbaadf00d - || ::MatchThreadHandleToOsId(handle, (DWORD)m_OSThreadId) ); - } -#endif - - DACCOP_IGNORE(FieldAccess, "Treated as raw address, no marshaling is necessary"); - return m_ThreadHandle; - } - void SetThreadHandle(HANDLE h) { LIMITED_METHOD_CONTRACT; From a1e3f5a6db17f45f5663007ce5167ba6ea574b0f Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Fri, 6 Sep 2024 21:09:46 -0700 Subject: [PATCH 3/8] Convert Thread.ThreadState property --- .../src/System/Threading/Thread.CoreCLR.cs | 13 +++-- src/coreclr/debug/daccess/dacdbiimpl.cpp | 2 + src/coreclr/vm/comsynchronizable.cpp | 48 +++++++++---------- src/coreclr/vm/comsynchronizable.h | 2 +- src/coreclr/vm/ecalllist.h | 1 - src/coreclr/vm/qcallentrypoints.cpp | 1 + 6 files changed, 37 insertions(+), 30 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs index d20908cb4f1d55..1326f6b167d6fd 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs @@ -269,10 +269,17 @@ public ThreadPriority Priority /// Return the thread state as a consistent set of bits. This is more /// general then IsAlive or IsBackground. /// - public ThreadState ThreadState => (ThreadState)GetThreadStateNative(); + public ThreadState ThreadState + { + get + { + Thread _this = this; + return (ThreadState)GetThreadState(ObjectHandleOnStack.Create(ref _this)); + } + } - [MethodImpl(MethodImplOptions.InternalCall)] - private extern int GetThreadStateNative(); + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ThreadNative_GetThreadState")] + private static partial int GetThreadState(ObjectHandleOnStack t); /// /// An unstarted thread can be marked to indicate that it will host a diff --git a/src/coreclr/debug/daccess/dacdbiimpl.cpp b/src/coreclr/debug/daccess/dacdbiimpl.cpp index 6309533648bb20..223d675df254ae 100644 --- a/src/coreclr/debug/daccess/dacdbiimpl.cpp +++ b/src/coreclr/debug/daccess/dacdbiimpl.cpp @@ -5557,6 +5557,8 @@ CorDebugUserState DacDbiInterfaceImpl::GetPartialUserState(VMPTR_Thread vmThread result |= USER_STOPPED; } + // Don't report Thread::TS_AbortRequested + // The interruptible flag is unreliable (see issue 699245) // The Debugger_SleepWaitJoin is always accurate when it is present, but it is still // just a band-aid fix to cover some of the race conditions interruptible has. diff --git a/src/coreclr/vm/comsynchronizable.cpp b/src/coreclr/vm/comsynchronizable.cpp index 5439f1e4e2bfa6..4e15bd37a9593a 100644 --- a/src/coreclr/vm/comsynchronizable.cpp +++ b/src/coreclr/vm/comsynchronizable.cpp @@ -473,57 +473,55 @@ FCIMPL1(FC_BOOL_RET, ThreadNative::GetIsBackground, ThreadBaseObject* pThisUNSAF FCIMPLEND // Deliver the state of the thread as a consistent set of bits. -// This copied in VM\EEDbgInterfaceImpl.h's -// CorDebugUserState GetUserState( Thread *pThread ) -// , so propagate changes to both functions -FCIMPL1(INT32, ThreadNative::GetThreadState, ThreadBaseObject* pThisUNSAFE) +// Duplicate logic in DacDbiInterfaceImpl::GetPartialUserState() +extern "C" INT32 QCALLTYPE ThreadNative_GetThreadState(QCall::ObjectHandleOnStack t) { - FCALL_CONTRACT; - - INT32 res = 0; - Thread::ThreadState state; + QCALL_CONTRACT; - if (pThisUNSAFE==NULL) - FCThrowRes(kNullReferenceException, W("NullReference_This")); + INT32 res = 0; - // validate the thread. Failure here implies that the thread was finalized - // and then resurrected. - Thread *thread = pThisUNSAFE->GetInternal(); + BEGIN_QCALL; - if (!thread) - FCThrowEx(kThreadStateException, IDS_EE_THREAD_CANNOT_GET, NULL, NULL, NULL); + Thread* thread = NULL; + { + GCX_COOP(); + if (t.Get() == NULL) + COMPlusThrow(kNullReferenceException, W("NullReference_This")); - HELPER_METHOD_FRAME_BEGIN_RET_0(); + // validate the thread. Failure here implies that the thread was finalized + // and then resurrected. + thread = ((THREADBASEREF)t.Get())->GetInternal(); + if (thread == NULL) + COMPlusThrow(kThreadStateException, IDS_EE_THREAD_CANNOT_GET); + } // grab a snapshot - state = thread->GetSnapshotState(); + Thread::ThreadState state = thread->GetSnapshotState(); if (state & Thread::TS_Background) - res |= ThreadBackground; + res |= ThreadNative::ThreadBackground; if (state & Thread::TS_Unstarted) - res |= ThreadUnstarted; + res |= ThreadNative::ThreadUnstarted; // Don't report a StopRequested if the thread has actually stopped. if (state & Thread::TS_Dead) { - res |= ThreadStopped; + res |= ThreadNative::ThreadStopped; } else { if (state & Thread::TS_AbortRequested) - res |= ThreadAbortRequested; + res |= ThreadNative::ThreadAbortRequested; } if (state & Thread::TS_Interruptible) - res |= ThreadWaitSleepJoin; + res |= ThreadNative::ThreadWaitSleepJoin; - HELPER_METHOD_POLL(); - HELPER_METHOD_FRAME_END(); + END_QCALL; return res; } -FCIMPLEND #ifdef FEATURE_COMINTEROP_APARTMENT_SUPPORT diff --git a/src/coreclr/vm/comsynchronizable.h b/src/coreclr/vm/comsynchronizable.h index c84dfc4ea8b857..9fde0a1f7a1656 100644 --- a/src/coreclr/vm/comsynchronizable.h +++ b/src/coreclr/vm/comsynchronizable.h @@ -54,7 +54,6 @@ friend class ThreadBaseObject; static FCDECL1(void, Initialize, ThreadBaseObject* pThisUNSAFE); static FCDECL1(FC_BOOL_RET, GetIsBackground, ThreadBaseObject* pThisUNSAFE); - static FCDECL1(INT32, GetThreadState, ThreadBaseObject* pThisUNSAFE); static FCDECL0(INT32, GetOptimalMaxSpinWaitsPerSpinIteration); static FCDECL0(Object*, GetCurrentThread); @@ -84,6 +83,7 @@ extern "C" void QCALLTYPE ThreadNative_SetIsBackground(QCall::ThreadHandle threa extern "C" void QCALLTYPE ThreadNative_InformThreadNameChange(QCall::ThreadHandle thread, LPCWSTR name, INT32 len); extern "C" BOOL QCALLTYPE ThreadNative_YieldThread(); extern "C" UINT64 QCALLTYPE ThreadNative_GetCurrentOSThreadId(); +extern "C" INT32 QCALLTYPE ThreadNative_GetThreadState(QCall::ObjectHandleOnStack t); #ifdef FEATURE_COMINTEROP_APARTMENT_SUPPORT extern "C" INT32 QCALLTYPE ThreadNative_GetApartmentState(QCall::ObjectHandleOnStack t); diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index ed50ab530fe1a4..752f681a93b355 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -304,7 +304,6 @@ FCFuncStart(gThreadFuncs) FCFuncElement("GetIsBackground", ThreadNative::GetIsBackground) FCFuncElement("get_IsThreadPoolThread", ThreadNative::IsThreadpoolThread) FCFuncElement("set_IsThreadPoolThread", ThreadNative::SetIsThreadpoolThread) - FCFuncElement("GetThreadStateNative", ThreadNative::GetThreadState) FCFuncElement("get_OptimalMaxSpinWaitsPerSpinIteration", ThreadNative::GetOptimalMaxSpinWaitsPerSpinIteration) FCFuncEnd() diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index 8bab2451dd64d3..e7b962cc75fa6e 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -241,6 +241,7 @@ static const Entry s_QCall[] = DllImportEntry(ThreadNative_InformThreadNameChange) DllImportEntry(ThreadNative_YieldThread) DllImportEntry(ThreadNative_GetCurrentOSThreadId) + DllImportEntry(ThreadNative_GetThreadState) #ifdef FEATURE_COMINTEROP_APARTMENT_SUPPORT DllImportEntry(ThreadNative_GetApartmentState) DllImportEntry(ThreadNative_SetApartmentState) From c5f1ebadaaf2935b41b9b0e8a086c7a0a6b9d78a Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Fri, 6 Sep 2024 21:30:25 -0700 Subject: [PATCH 4/8] Convert Thread.Initialize() --- .../src/System/Threading/Thread.CoreCLR.cs | 10 ++++-- src/coreclr/vm/comsynchronizable.cpp | 31 ++++++++++--------- src/coreclr/vm/comsynchronizable.h | 2 +- src/coreclr/vm/ecalllist.h | 1 - src/coreclr/vm/object.h | 1 - src/coreclr/vm/qcallentrypoints.cpp | 1 + 6 files changed, 27 insertions(+), 19 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs index 1326f6b167d6fd..2abeb4baef847c 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs @@ -171,8 +171,14 @@ static Thread GetCurrentThreadWorker() [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ThreadNative_GetCurrentThreadSlow")] private static partial void GetCurrentThreadSlow(ObjectHandleOnStack thread); - [MethodImpl(MethodImplOptions.InternalCall)] - private extern void Initialize(); + private void Initialize() + { + Thread _this = this; + Initialize(ObjectHandleOnStack.Create(ref _this)); + } + + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ThreadNative_Initialize")] + private static partial void Initialize(ObjectHandleOnStack thread); /// Clean up the thread when it goes away. ~Thread() => InternalFinalize(); // Delegate to the unmanaged portion. diff --git a/src/coreclr/vm/comsynchronizable.cpp b/src/coreclr/vm/comsynchronizable.cpp index 4e15bd37a9593a..5e4beca07bb3f3 100644 --- a/src/coreclr/vm/comsynchronizable.cpp +++ b/src/coreclr/vm/comsynchronizable.cpp @@ -426,33 +426,36 @@ extern "C" UINT64 QCALLTYPE ThreadNative_GetCurrentOSThreadId() return threadId; } -FCIMPL1(void, ThreadNative::Initialize, ThreadBaseObject* pThisUNSAFE) +extern "C" void QCALLTYPE ThreadNative_Initialize(QCall::ObjectHandleOnStack t) { - FCALL_CONTRACT; + QCALL_CONTRACT; - THREADBASEREF pThis = (THREADBASEREF) pThisUNSAFE; + BEGIN_QCALL; - HELPER_METHOD_FRAME_BEGIN_1(pThis); + GCX_COOP(); - _ASSERTE(pThis != NULL); - _ASSERTE(pThis->m_InternalThread == NULL); + THREADBASEREF threadRef = NULL; + GCPROTECT_BEGIN(threadRef) + threadRef = (THREADBASEREF)t.Get(); + + _ASSERTE(threadRef != NULL); + _ASSERTE(threadRef->GetInternal() == NULL); // if we don't have an internal Thread object associated with this exposed object, // now is our first opportunity to create one. - Thread *unstarted = SetupUnstartedThread(); - + Thread* unstarted = SetupUnstartedThread(); PREFIX_ASSUME(unstarted != NULL); - pThis->SetInternal(unstarted); - pThis->SetManagedThreadId(unstarted->GetThreadId()); - unstarted->SetExposedObject(pThis); + threadRef->SetInternal(unstarted); + threadRef->SetManagedThreadId(unstarted->GetThreadId()); + unstarted->SetExposedObject(threadRef); // Initialize the thread priority to normal. - pThis->SetPriority(ThreadNative::PRIORITY_NORMAL); + threadRef->SetPriority(ThreadNative::PRIORITY_NORMAL); - HELPER_METHOD_FRAME_END(); + GCPROTECT_END(); + END_QCALL; } -FCIMPLEND // Return whether or not this is a background thread. FCIMPL1(FC_BOOL_RET, ThreadNative::GetIsBackground, ThreadBaseObject* pThisUNSAFE) diff --git a/src/coreclr/vm/comsynchronizable.h b/src/coreclr/vm/comsynchronizable.h index 9fde0a1f7a1656..65fd0c4e3e72da 100644 --- a/src/coreclr/vm/comsynchronizable.h +++ b/src/coreclr/vm/comsynchronizable.h @@ -52,7 +52,6 @@ friend class ThreadBaseObject; ThreadAbortRequested = 128, }; - static FCDECL1(void, Initialize, ThreadBaseObject* pThisUNSAFE); static FCDECL1(FC_BOOL_RET, GetIsBackground, ThreadBaseObject* pThisUNSAFE); static FCDECL0(INT32, GetOptimalMaxSpinWaitsPerSpinIteration); @@ -83,6 +82,7 @@ extern "C" void QCALLTYPE ThreadNative_SetIsBackground(QCall::ThreadHandle threa extern "C" void QCALLTYPE ThreadNative_InformThreadNameChange(QCall::ThreadHandle thread, LPCWSTR name, INT32 len); extern "C" BOOL QCALLTYPE ThreadNative_YieldThread(); extern "C" UINT64 QCALLTYPE ThreadNative_GetCurrentOSThreadId(); +extern "C" void QCALLTYPE ThreadNative_Initialize(QCall::ObjectHandleOnStack t); extern "C" INT32 QCALLTYPE ThreadNative_GetThreadState(QCall::ObjectHandleOnStack t); #ifdef FEATURE_COMINTEROP_APARTMENT_SUPPORT diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index 752f681a93b355..971d670ca17dea 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -298,7 +298,6 @@ FCFuncStart(gMathFFuncs) FCFuncEnd() FCFuncStart(gThreadFuncs) - FCFuncElement("Initialize", ThreadNative::Initialize) FCFuncElement("GetCurrentThread", ThreadNative::GetCurrentThread) FCFuncElement("InternalFinalize", ThreadNative::Finalize) FCFuncElement("GetIsBackground", ThreadNative::GetIsBackground) diff --git a/src/coreclr/vm/object.h b/src/coreclr/vm/object.h index 1afd632dea09e1..78fb10e90833eb 100644 --- a/src/coreclr/vm/object.h +++ b/src/coreclr/vm/object.h @@ -1302,7 +1302,6 @@ typedef DPTR(class ThreadBaseObject) PTR_ThreadBaseObject; class ThreadBaseObject : public Object { friend class ClrDataAccess; - friend class ThreadNative; friend class CoreLibBinder; friend class Object; diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index e7b962cc75fa6e..dc16ed827cfc0b 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -241,6 +241,7 @@ static const Entry s_QCall[] = DllImportEntry(ThreadNative_InformThreadNameChange) DllImportEntry(ThreadNative_YieldThread) DllImportEntry(ThreadNative_GetCurrentOSThreadId) + DllImportEntry(ThreadNative_Initialize) DllImportEntry(ThreadNative_GetThreadState) #ifdef FEATURE_COMINTEROP_APARTMENT_SUPPORT DllImportEntry(ThreadNative_GetApartmentState) From 32ab4a81665073295333508c5d90d5469184a54b Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Sun, 8 Sep 2024 17:23:59 -0700 Subject: [PATCH 5/8] Feedback Thread.GetCurrentThread() --- .../src/System/Threading/Thread.CoreCLR.cs | 20 +++++-------------- src/coreclr/vm/comsynchronizable.cpp | 9 +-------- src/coreclr/vm/comsynchronizable.h | 3 +-- src/coreclr/vm/ecalllist.h | 1 - src/coreclr/vm/qcallentrypoints.cpp | 2 +- 5 files changed, 8 insertions(+), 27 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs index 2abeb4baef847c..c08da3fcc4ed1a 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs @@ -153,23 +153,13 @@ public static void SpinWait(int iterations) [MethodImpl(MethodImplOptions.NoInlining)] private static Thread InitializeCurrentThread() { - t_currentThread = GetCurrentThread() ?? GetCurrentThreadWorker(); - return t_currentThread; - - [MethodImpl(MethodImplOptions.NoInlining)] - static Thread GetCurrentThreadWorker() - { - Thread? thread = null; - GetCurrentThreadSlow(ObjectHandleOnStack.Create(ref thread)); - return thread!; - } + Thread? thread = null; + GetCurrentThread(ObjectHandleOnStack.Create(ref thread)); + return t_currentThread = thread!; } - [MethodImpl(MethodImplOptions.InternalCall)] - private static extern Thread GetCurrentThread(); - - [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ThreadNative_GetCurrentThreadSlow")] - private static partial void GetCurrentThreadSlow(ObjectHandleOnStack thread); + [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ThreadNative_GetCurrentThread")] + private static partial void GetCurrentThread(ObjectHandleOnStack thread); private void Initialize() { diff --git a/src/coreclr/vm/comsynchronizable.cpp b/src/coreclr/vm/comsynchronizable.cpp index 5e4beca07bb3f3..1d56469c8ae724 100644 --- a/src/coreclr/vm/comsynchronizable.cpp +++ b/src/coreclr/vm/comsynchronizable.cpp @@ -385,14 +385,7 @@ extern "C" BOOL QCALLTYPE ThreadNative_IsAlive(QCall::ObjectHandleOnStack t) return ret; } -FCIMPL0(Object*, ThreadNative::GetCurrentThread) -{ - FCALL_CONTRACT; - return OBJECTREFToObject(GetThread()->GetExposedObjectRaw()); -} -FCIMPLEND - -extern "C" void QCALLTYPE ThreadNative_GetCurrentThreadSlow(QCall::ObjectHandleOnStack thread) +extern "C" void QCALLTYPE ThreadNative_GetCurrentThread(QCall::ObjectHandleOnStack thread) { QCALL_CONTRACT; diff --git a/src/coreclr/vm/comsynchronizable.h b/src/coreclr/vm/comsynchronizable.h index 65fd0c4e3e72da..c32aafcf643fb1 100644 --- a/src/coreclr/vm/comsynchronizable.h +++ b/src/coreclr/vm/comsynchronizable.h @@ -55,7 +55,6 @@ friend class ThreadBaseObject; static FCDECL1(FC_BOOL_RET, GetIsBackground, ThreadBaseObject* pThisUNSAFE); static FCDECL0(INT32, GetOptimalMaxSpinWaitsPerSpinIteration); - static FCDECL0(Object*, GetCurrentThread); static FCDECL1(void, Finalize, ThreadBaseObject* pThis); static FCDECL1(FC_BOOL_RET,IsThreadpoolThread, ThreadBaseObject* thread); static FCDECL1(void, SetIsThreadpoolThread, ThreadBaseObject* thread); @@ -77,7 +76,7 @@ friend class ThreadBaseObject; extern "C" void QCALLTYPE ThreadNative_Start(QCall::ThreadHandle thread, int threadStackSize, int priority, PCWSTR pThreadName); extern "C" void QCALLTYPE ThreadNative_SetPriority(QCall::ObjectHandleOnStack thread, INT32 iPriority); extern "C" BOOL QCALLTYPE ThreadNative_IsAlive(QCall::ObjectHandleOnStack t); -extern "C" void QCALLTYPE ThreadNative_GetCurrentThreadSlow(QCall::ObjectHandleOnStack thread); +extern "C" void QCALLTYPE ThreadNative_GetCurrentThread(QCall::ObjectHandleOnStack thread); extern "C" void QCALLTYPE ThreadNative_SetIsBackground(QCall::ThreadHandle thread, BOOL value); extern "C" void QCALLTYPE ThreadNative_InformThreadNameChange(QCall::ThreadHandle thread, LPCWSTR name, INT32 len); extern "C" BOOL QCALLTYPE ThreadNative_YieldThread(); diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index 971d670ca17dea..a26101fef86b46 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -298,7 +298,6 @@ FCFuncStart(gMathFFuncs) FCFuncEnd() FCFuncStart(gThreadFuncs) - FCFuncElement("GetCurrentThread", ThreadNative::GetCurrentThread) FCFuncElement("InternalFinalize", ThreadNative::Finalize) FCFuncElement("GetIsBackground", ThreadNative::GetIsBackground) FCFuncElement("get_IsThreadPoolThread", ThreadNative::IsThreadpoolThread) diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index dc16ed827cfc0b..9198dcdc1c803b 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -236,7 +236,7 @@ static const Entry s_QCall[] = DllImportEntry(ThreadNative_Start) DllImportEntry(ThreadNative_SetPriority) DllImportEntry(ThreadNative_IsAlive) - DllImportEntry(ThreadNative_GetCurrentThreadSlow) + DllImportEntry(ThreadNative_GetCurrentThread) DllImportEntry(ThreadNative_SetIsBackground) DllImportEntry(ThreadNative_InformThreadNameChange) DllImportEntry(ThreadNative_YieldThread) From 8fab44308ee0dcca7cb7faa1b30eeb6d342e0ec7 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Sun, 8 Sep 2024 17:31:27 -0700 Subject: [PATCH 6/8] Feedback Thread.IsAlive property --- .../src/System/Threading/Thread.CoreCLR.cs | 13 +---------- src/coreclr/vm/comsynchronizable.cpp | 23 ------------------- src/coreclr/vm/comsynchronizable.h | 1 - src/coreclr/vm/qcallentrypoints.cpp | 1 - 4 files changed, 1 insertion(+), 37 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs index c08da3fcc4ed1a..91e39cedb90a42 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs @@ -186,18 +186,7 @@ partial void ThreadNameChanged(string? value) private static partial void InformThreadNameChange(ThreadHandle t, string? name, int len); /// Returns true if the thread has been started and is not dead. - public bool IsAlive - { - get - { - Thread _this = this; - return IsAliveWorker(ObjectHandleOnStack.Create(ref _this)); - } - } - - [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ThreadNative_IsAlive")] - [return: MarshalAs(UnmanagedType.Bool)] - private static partial bool IsAliveWorker(ObjectHandleOnStack t); + public bool IsAlive => (ThreadState & (ThreadState.Unstarted | ThreadState.Stopped | ThreadState.Aborted)) == 0; /// /// Return whether or not this thread is a background thread. Background diff --git a/src/coreclr/vm/comsynchronizable.cpp b/src/coreclr/vm/comsynchronizable.cpp index 1d56469c8ae724..6ae18ac106f46f 100644 --- a/src/coreclr/vm/comsynchronizable.cpp +++ b/src/coreclr/vm/comsynchronizable.cpp @@ -362,29 +362,6 @@ extern "C" void QCALLTYPE ThreadNative_SetPriority(QCall::ObjectHandleOnStack th END_QCALL; } -extern "C" BOOL QCALLTYPE ThreadNative_IsAlive(QCall::ObjectHandleOnStack t) -{ - QCALL_CONTRACT; - - BOOL ret = FALSE; - - BEGIN_QCALL; - - GCX_COOP(); - - if (t.Get() == NULL) - COMPlusThrow(kNullReferenceException, W("NullReference_This")); - - Thread* thread = ((THREADBASEREF)t.Get())->GetInternal(); - if (thread == NULL) - COMPlusThrow(kThreadStateException, IDS_EE_THREAD_CANNOT_GET); - - ret = ThreadIsRunning(thread); - - END_QCALL; - return ret; -} - extern "C" void QCALLTYPE ThreadNative_GetCurrentThread(QCall::ObjectHandleOnStack thread) { QCALL_CONTRACT; diff --git a/src/coreclr/vm/comsynchronizable.h b/src/coreclr/vm/comsynchronizable.h index c32aafcf643fb1..bea9590cd96a20 100644 --- a/src/coreclr/vm/comsynchronizable.h +++ b/src/coreclr/vm/comsynchronizable.h @@ -75,7 +75,6 @@ friend class ThreadBaseObject; extern "C" void QCALLTYPE ThreadNative_Start(QCall::ThreadHandle thread, int threadStackSize, int priority, PCWSTR pThreadName); extern "C" void QCALLTYPE ThreadNative_SetPriority(QCall::ObjectHandleOnStack thread, INT32 iPriority); -extern "C" BOOL QCALLTYPE ThreadNative_IsAlive(QCall::ObjectHandleOnStack t); extern "C" void QCALLTYPE ThreadNative_GetCurrentThread(QCall::ObjectHandleOnStack thread); extern "C" void QCALLTYPE ThreadNative_SetIsBackground(QCall::ThreadHandle thread, BOOL value); extern "C" void QCALLTYPE ThreadNative_InformThreadNameChange(QCall::ThreadHandle thread, LPCWSTR name, INT32 len); diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp index 9198dcdc1c803b..d62b15decf5a4d 100644 --- a/src/coreclr/vm/qcallentrypoints.cpp +++ b/src/coreclr/vm/qcallentrypoints.cpp @@ -235,7 +235,6 @@ static const Entry s_QCall[] = DllImportEntry(AppDomain_CreateDynamicAssembly) DllImportEntry(ThreadNative_Start) DllImportEntry(ThreadNative_SetPriority) - DllImportEntry(ThreadNative_IsAlive) DllImportEntry(ThreadNative_GetCurrentThread) DllImportEntry(ThreadNative_SetIsBackground) DllImportEntry(ThreadNative_InformThreadNameChange) From ea6cc0229f2059a9c5d3cd10929404c5be121d2e Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Sun, 8 Sep 2024 17:44:44 -0700 Subject: [PATCH 7/8] Feedback Thread.ThreadState property --- .../src/System/Threading/Thread.CoreCLR.cs | 9 ++++--- src/coreclr/dlls/mscorrc/mscorrc.rc | 1 - src/coreclr/dlls/mscorrc/resource.h | 1 - src/coreclr/vm/comsynchronizable.cpp | 25 ++++++------------- src/coreclr/vm/comsynchronizable.h | 2 +- 5 files changed, 15 insertions(+), 23 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs index 91e39cedb90a42..08b3ae8944d630 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs @@ -258,13 +258,15 @@ public ThreadState ThreadState { get { - Thread _this = this; - return (ThreadState)GetThreadState(ObjectHandleOnStack.Create(ref _this)); + var state = (ThreadState)GetThreadState(GetNativeHandle()); + GC.KeepAlive(this); + return state; } } + [SuppressGCTransition] [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ThreadNative_GetThreadState")] - private static partial int GetThreadState(ObjectHandleOnStack t); + private static partial int GetThreadState(ThreadHandle t); /// /// An unstarted thread can be marked to indicate that it will host a @@ -341,6 +343,7 @@ public void DisableComObjectEagerCleanup() GC.KeepAlive(this); } + [SuppressGCTransition] [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "ThreadNative_DisableComObjectEagerCleanup")] private static partial void DisableComObjectEagerCleanup(ThreadHandle t); #else // !FEATURE_COMINTEROP diff --git a/src/coreclr/dlls/mscorrc/mscorrc.rc b/src/coreclr/dlls/mscorrc/mscorrc.rc index 927b287844df73..1d58a0681b584c 100644 --- a/src/coreclr/dlls/mscorrc/mscorrc.rc +++ b/src/coreclr/dlls/mscorrc/mscorrc.rc @@ -467,7 +467,6 @@ BEGIN IDS_EE_INVALID_CA "Invalid custom attribute provided." - IDS_EE_THREAD_CANNOT_GET "Unable to retrieve thread information." IDS_EE_THREAD_ABORT_WHILE_SUSPEND "Thread is suspended; attempting to abort." IDS_EE_NOVARIANTRETURN "PInvoke restriction: cannot return variants." diff --git a/src/coreclr/dlls/mscorrc/resource.h b/src/coreclr/dlls/mscorrc/resource.h index 09bf78dfb93c49..964cb7128325d9 100644 --- a/src/coreclr/dlls/mscorrc/resource.h +++ b/src/coreclr/dlls/mscorrc/resource.h @@ -232,7 +232,6 @@ #define IDS_EE_INVALID_CA 0x1a10 -#define IDS_EE_THREAD_CANNOT_GET 0x1a15 #define IDS_EE_THREAD_ABORT_WHILE_SUSPEND 0x1a1c #define IDS_EE_NOVARIANTRETURN 0x1a1d diff --git a/src/coreclr/vm/comsynchronizable.cpp b/src/coreclr/vm/comsynchronizable.cpp index 6ae18ac106f46f..145f352512a6cb 100644 --- a/src/coreclr/vm/comsynchronizable.cpp +++ b/src/coreclr/vm/comsynchronizable.cpp @@ -447,27 +447,19 @@ FCIMPLEND // Deliver the state of the thread as a consistent set of bits. // Duplicate logic in DacDbiInterfaceImpl::GetPartialUserState() -extern "C" INT32 QCALLTYPE ThreadNative_GetThreadState(QCall::ObjectHandleOnStack t) +extern "C" INT32 QCALLTYPE ThreadNative_GetThreadState(QCall::ThreadHandle thread) { - QCALL_CONTRACT; + CONTRACTL + { + QCALL_CHECK_NO_GC_TRANSITION; + PRECONDITION(thread != NULL); + } + CONTRACTL_END; INT32 res = 0; BEGIN_QCALL; - Thread* thread = NULL; - { - GCX_COOP(); - if (t.Get() == NULL) - COMPlusThrow(kNullReferenceException, W("NullReference_This")); - - // validate the thread. Failure here implies that the thread was finalized - // and then resurrected. - thread = ((THREADBASEREF)t.Get())->GetInternal(); - if (thread == NULL) - COMPlusThrow(kThreadStateException, IDS_EE_THREAD_CANNOT_GET); - } - // grab a snapshot Thread::ThreadState state = thread->GetSnapshotState(); @@ -492,7 +484,6 @@ extern "C" INT32 QCALLTYPE ThreadNative_GetThreadState(QCall::ObjectHandleOnStac res |= ThreadNative::ThreadWaitSleepJoin; END_QCALL; - return res; } @@ -897,7 +888,7 @@ extern "C" void QCALLTYPE ThreadNative_DisableComObjectEagerCleanup(QCall::Threa { CONTRACTL { - QCALL_CHECK; + QCALL_CHECK_NO_GC_TRANSITION; PRECONDITION(thread != NULL); } CONTRACTL_END; diff --git a/src/coreclr/vm/comsynchronizable.h b/src/coreclr/vm/comsynchronizable.h index bea9590cd96a20..b7c64c529084f8 100644 --- a/src/coreclr/vm/comsynchronizable.h +++ b/src/coreclr/vm/comsynchronizable.h @@ -81,7 +81,7 @@ extern "C" void QCALLTYPE ThreadNative_InformThreadNameChange(QCall::ThreadHandl extern "C" BOOL QCALLTYPE ThreadNative_YieldThread(); extern "C" UINT64 QCALLTYPE ThreadNative_GetCurrentOSThreadId(); extern "C" void QCALLTYPE ThreadNative_Initialize(QCall::ObjectHandleOnStack t); -extern "C" INT32 QCALLTYPE ThreadNative_GetThreadState(QCall::ObjectHandleOnStack t); +extern "C" INT32 QCALLTYPE ThreadNative_GetThreadState(QCall::ThreadHandle thread); #ifdef FEATURE_COMINTEROP_APARTMENT_SUPPORT extern "C" INT32 QCALLTYPE ThreadNative_GetApartmentState(QCall::ObjectHandleOnStack t); From bb8e0c256c14b3ff812183a134f66e05988fc635 Mon Sep 17 00:00:00 2001 From: Aaron R Robinson Date: Mon, 9 Sep 2024 10:02:16 -0700 Subject: [PATCH 8/8] Feedback on contracts --- src/coreclr/vm/comsynchronizable.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/coreclr/vm/comsynchronizable.cpp b/src/coreclr/vm/comsynchronizable.cpp index 145f352512a6cb..7f1751aaa15f58 100644 --- a/src/coreclr/vm/comsynchronizable.cpp +++ b/src/coreclr/vm/comsynchronizable.cpp @@ -458,8 +458,6 @@ extern "C" INT32 QCALLTYPE ThreadNative_GetThreadState(QCall::ThreadHandle threa INT32 res = 0; - BEGIN_QCALL; - // grab a snapshot Thread::ThreadState state = thread->GetSnapshotState(); @@ -483,7 +481,6 @@ extern "C" INT32 QCALLTYPE ThreadNative_GetThreadState(QCall::ThreadHandle threa if (state & Thread::TS_Interruptible) res |= ThreadNative::ThreadWaitSleepJoin; - END_QCALL; return res; } @@ -893,11 +890,7 @@ extern "C" void QCALLTYPE ThreadNative_DisableComObjectEagerCleanup(QCall::Threa } CONTRACTL_END; - BEGIN_QCALL; - thread->SetDisableComObjectEagerCleanup(); - - END_QCALL; } #endif //FEATURE_COMINTEROP