From 0aaf0a793e95fbef99c2c7e7e68fb3e1e91adcff Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Fri, 4 Sep 2015 10:16:37 +0200 Subject: Remove thread affinity and critical region stuff for Unix The WaitHandleNative::CorWaitMultipleNative was calling Thread::BeginThreadAffinityAndCriticalRegion that results in incrementing the Thread::m_dwCriticalRegionCount. However, there is nothing that would decrement it on CoreCLR, so if the WaitHandleNative::CorWaitMultipleNative is called, in debug build we get an assert in Thread::InternalReset. It turns out that the critical region and thread affinity stuff is not to be used in CoreCLR, so I have disabled handling of that in CoreCLR for Unix. The only remainder are the static methods Thread::BeginThreadAffinity and Thread::EndThreadAffinity which are used in the ThreadAffinityHolder. Conditionally removing the holder usage would be messy, so I have rather kept those methods and made their bodies empty. --- src/vm/comisolatedstorage.cpp | 4 ++++ src/vm/common.h | 4 ++++ src/vm/comsynchronizable.cpp | 3 ++- src/vm/comsynchronizable.h | 2 ++ src/vm/comwaithandle.cpp | 11 +++++++++-- src/vm/frames.h | 24 +++++++++++++++++++----- src/vm/threads.cpp | 29 ++++++++++++++++++++++++----- src/vm/threads.h | 36 +++++++++++++++++++++++++++++------- 8 files changed, 93 insertions(+), 20 deletions(-) (limited to 'src/vm') diff --git a/src/vm/comisolatedstorage.cpp b/src/vm/comisolatedstorage.cpp index cba98c6adb..50eb9fe1b0 100644 --- a/src/vm/comisolatedstorage.cpp +++ b/src/vm/comisolatedstorage.cpp @@ -993,7 +993,9 @@ HRESULT AccountingInfo::Lock() DWORD dwRet; { // m_hLock is a mutex +#ifndef FEATURE_CORECLR Thread::BeginThreadAffinityAndCriticalRegion(); +#endif dwRet = WaitForSingleObject(m_hLock, INFINITE); } @@ -1064,7 +1066,9 @@ void AccountingInfo::Unlock() InterlockedDecrement((LPLONG)&m_dwNumLocks); #endif +#ifndef FEATURE_CORECLR Thread::EndThreadAffinityAndCriticalRegion(); +#endif } #endif diff --git a/src/vm/common.h b/src/vm/common.h index 5d214818f1..e323333ef5 100644 --- a/src/vm/common.h +++ b/src/vm/common.h @@ -392,9 +392,11 @@ inline VOID UnsafeEEEnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection) STATIC_CONTRACT_GC_NOTRIGGER; STATIC_CONTRACT_CAN_TAKE_LOCK; +#ifndef FEATURE_CORECLR if (CLRTaskHosted()) { Thread::BeginThreadAffinity(); } +#endif // !FEATURE_CORECLR UnsafeEnterCriticalSection(lpCriticalSection); INCTHREADLOCKCOUNT(); } @@ -406,9 +408,11 @@ inline VOID UnsafeEELeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection) UnsafeLeaveCriticalSection(lpCriticalSection); DECTHREADLOCKCOUNT(); +#ifndef FEATURE_CORECLR if (CLRTaskHosted()) { Thread::EndThreadAffinity(); } +#endif // !FEATURE_CORECLR } inline BOOL UnsafeEETryEnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection) diff --git a/src/vm/comsynchronizable.cpp b/src/vm/comsynchronizable.cpp index a4c08af0f6..473e7e1e6d 100644 --- a/src/vm/comsynchronizable.cpp +++ b/src/vm/comsynchronizable.cpp @@ -1938,7 +1938,7 @@ UINT64 QCALLTYPE ThreadNative::GetProcessDefaultStackSize() return (UINT64)reserve; } - +#ifndef FEATURE_CORECLR FCIMPL0(void, ThreadNative::BeginCriticalRegion) { FCALL_CONTRACT; @@ -1972,6 +1972,7 @@ FCIMPL0(void, ThreadNative::EndThreadAffinity) Thread::EndThreadAffinity(); } FCIMPLEND +#endif // !FEATURE_CORECLR FCIMPL1(FC_BOOL_RET, ThreadNative::IsThreadpoolThread, ThreadBaseObject* thread) diff --git a/src/vm/comsynchronizable.h b/src/vm/comsynchronizable.h index 8b10e11e8e..53c2db86b8 100644 --- a/src/vm/comsynchronizable.h +++ b/src/vm/comsynchronizable.h @@ -110,10 +110,12 @@ public: UINT64 QCALLTYPE GetProcessDefaultStackSize(); static FCDECL1(INT32, GetManagedThreadId, ThreadBaseObject* th); +#ifndef FEATURE_CORECLR static FCDECL0(void, BeginCriticalRegion); static FCDECL0(void, EndCriticalRegion); static FCDECL0(void, BeginThreadAffinity); static FCDECL0(void, EndThreadAffinity); +#endif // !FEATURE_CORECLR static FCDECL1(void, SpinWait, int iterations); static BOOL QCALLTYPE YieldThread(); static FCDECL0(Object*, GetCurrentThread); diff --git a/src/vm/comwaithandle.cpp b/src/vm/comwaithandle.cpp index 3c56cb9c36..0c96e9abf2 100644 --- a/src/vm/comwaithandle.cpp +++ b/src/vm/comwaithandle.cpp @@ -275,9 +275,11 @@ FCIMPL4(INT32, WaitHandleNative::CorWaitMultipleNative, Object* waitObjectsUNSAF pWaitObjects = (PTRARRAYREF)waitObjects; // array of objects on which to wait HANDLE* internalHandles = (HANDLE*) _alloca(numWaiters*sizeof(HANDLE)); +#ifndef FEATURE_CORECLR BOOL *hasThreadAffinity = (BOOL*) _alloca(numWaiters*sizeof(BOOL)); BOOL mayRequireThreadAffinity = FALSE; +#endif // !FEATURE_CORECLR for (int i=0;im_Array[i]; @@ -288,15 +290,19 @@ FCIMPL4(INT32, WaitHandleNative::CorWaitMultipleNative, Object* waitObjectsUNSAF // this behavior seems wrong but someone explicitly coded that condition so it must have been for a reason. internalHandles[i] = waitObject->m_handle; +#ifndef FEATURE_CORECLR // m_hasThreadAffinity is set for Mutex only hasThreadAffinity[i] = waitObject->m_hasThreadAffinity; if (hasThreadAffinity[i]) { mayRequireThreadAffinity = TRUE; } +#endif // !FEATURE_CORECLR } DWORD res = (DWORD) -1; +#ifndef FEATURE_CORECLR ThreadAffinityHolder affinityHolder(mayRequireThreadAffinity); +#endif // !FEATURE_CORECLR Context* targetContext; targetContext = pThread->GetContext(); _ASSERTE(targetContext); @@ -330,6 +336,7 @@ FCIMPL4(INT32, WaitHandleNative::CorWaitMultipleNative, Object* waitObjectsUNSAF } } +#ifndef FEATURE_CORECLR if (mayRequireThreadAffinity) { if (waitForAll) { if (res >= (DWORD) WAIT_OBJECT_0 && res < (DWORD) WAIT_OBJECT_0 + numWaiters) { @@ -367,6 +374,8 @@ FCIMPL4(INT32, WaitHandleNative::CorWaitMultipleNative, Object* waitObjectsUNSAF } } } +#endif // !FEATURE_CORECLR + retVal = res; HELPER_METHOD_FRAME_END(); @@ -449,5 +458,3 @@ FCIMPL5(INT32, WaitHandleNative::CorSignalAndWaitOneNative, SafeHandle* safeWait } FCIMPLEND #endif // !FEATURE_CORECLR - - diff --git a/src/vm/frames.h b/src/vm/frames.h index ce65b38623..dcaa4403ff 100644 --- a/src/vm/frames.h +++ b/src/vm/frames.h @@ -3165,8 +3165,9 @@ private: PTR_Object m_LastThrownObjectInParentContext; ULONG_PTR m_LockCount; // Number of locks the thread takes // before the transition. +#ifndef FEATURE_CORECLR ULONG_PTR m_CriticalRegionCount; - +#endif // !FEATURE_CORECLR VPTR_VTABLE_CLASS(ContextTransitionFrame, Frame) public: @@ -3194,18 +3195,29 @@ public: m_LastThrownObjectInParentContext = OBJECTREFToObject(lastThrownObject); } - void SetLockCount(DWORD lockCount, DWORD criticalRegionCount) + void SetLockCount(DWORD lockCount) { LIMITED_METHOD_CONTRACT; m_LockCount = lockCount; + } + DWORD GetLockCount() + { + LIMITED_METHOD_CONTRACT; + return (DWORD) m_LockCount; + } + +#ifndef FEATURE_CORECLR + void SetCriticalRegionCount(DWORD criticalRegionCount) + { + LIMITED_METHOD_CONTRACT; m_CriticalRegionCount = criticalRegionCount; } - void GetLockCount(DWORD* pLockCount, DWORD* pCriticalRegionCount) + DWORD GetCriticalRegionCount() { LIMITED_METHOD_CONTRACT; - *pLockCount = (DWORD) m_LockCount; - *pCriticalRegionCount = (DWORD) m_CriticalRegionCount; + return (DWORD) m_CriticalRegionCount; } +#endif // !FEATURE_CORECLR // Let debugger know that we're transitioning between AppDomains. ETransitionType GetTransitionType() @@ -3220,7 +3232,9 @@ public: , m_ReturnExecutionContext(NULL) , m_LastThrownObjectInParentContext(NULL) , m_LockCount(0) +#ifndef FEATURE_CORECLR , m_CriticalRegionCount(0) +#endif // !FEATURE_CORECLR { LIMITED_METHOD_CONTRACT; } diff --git a/src/vm/threads.cpp b/src/vm/threads.cpp index 035abd1fb8..076ffe1e3f 100644 --- a/src/vm/threads.cpp +++ b/src/vm/threads.cpp @@ -1921,9 +1921,11 @@ Thread::Thread() m_dwLockCount = 0; m_dwBeginLockCount = 0; +#ifndef FEATURE_CORECLR m_dwBeginCriticalRegionCount = 0; m_dwCriticalRegionCount = 0; m_dwThreadAffinityCount = 0; +#endif // !FEATURE_CORECLR #ifdef _DEBUG dbg_m_cSuspendedThreads = 0; @@ -8750,9 +8752,12 @@ void Thread::EnterContextRestricted(Context *pContext, ContextTransitionFrame *p if (pPrevDomain != pDomain) { - pFrame->SetLockCount(m_dwBeginLockCount, m_dwBeginCriticalRegionCount); - m_dwBeginLockCount = m_dwLockCount; - m_dwBeginCriticalRegionCount = m_dwCriticalRegionCount; + pFrame->SetLockCount(m_dwBeginLockCount); + m_dwBeginLockCount = m_dwLockCount; +#ifndef FEATURE_CORECLR + pFrame->SetCriticalRegionCount(m_dwBeginCriticalRegionCount); + m_dwBeginCriticalRegionCount = m_dwCriticalRegionCount; +#endif // !FEATURE_CORECLR } if (m_Context == pContext) { @@ -8935,9 +8940,12 @@ void Thread::ReturnToContext(ContextTransitionFrame *pFrame) } m_dwLockCount = m_dwBeginLockCount; + m_dwBeginLockCount = pFrame->GetLockCount(); +#ifndef FEATURE_CORECLR m_dwCriticalRegionCount = m_dwBeginCriticalRegionCount; + m_dwBeginCriticalRegionCount = pFrame->GetCriticalRegionCount(); +#endif // !FEATURE_CORECLR - pFrame->GetLockCount(&m_dwBeginLockCount, &m_dwBeginCriticalRegionCount); } if (m_Context == pReturnContext) @@ -11733,11 +11741,13 @@ void Thread::InternalReset(BOOL fFull, BOOL fNotFinalizerThread, BOOL fThreadObj FullResetThread(); } +#ifndef FEATURE_CORECLR _ASSERTE (m_dwCriticalRegionCount == 0); m_dwCriticalRegionCount = 0; _ASSERTE (m_dwThreadAffinityCount == 0); m_dwThreadAffinityCount = 0; +#endif // !FEATURE_CORECLR //m_MarshalAlloc.Collapse(NULL); @@ -11861,7 +11871,9 @@ HRESULT Thread::Reset(BOOL fFull) ResetThreadStateNC(TSNC_UnbalancedLocks); m_dwLockCount = 0; +#ifndef FEATURE_CORECLR m_dwCriticalRegionCount = 0; +#endif // !FEATURE_CORECLR InternalSwitchOut(); m_OSThreadId = SWITCHED_OUT_FIBER_OSID; @@ -12235,7 +12247,10 @@ HRESULT Thread::LocksHeld(SIZE_T *pLockCount) { LIMITED_METHOD_CONTRACT; - *pLockCount = m_dwLockCount + m_dwCriticalRegionCount; + *pLockCount = m_dwLockCount; +#ifndef FEATURE_CORECLR + *pLockCount += m_dwCriticalRegionCount; +#endif // !FEATURE_CORECLR return S_OK; } @@ -12829,6 +12844,7 @@ void Thread::BeginThreadAffinity() { LIMITED_METHOD_CONTRACT; +#ifndef FEATURE_CORECLR if (!CLRTaskHosted()) { return; @@ -12858,6 +12874,7 @@ void Thread::BeginThreadAffinity() #endif } #endif // FEATURE_INCLUDE_ALL_INTERFACES +#endif // !FEATURE_CORECLR } @@ -12866,6 +12883,7 @@ void Thread::EndThreadAffinity() { LIMITED_METHOD_CONTRACT; +#ifndef FEATURE_CORECLR if (!CLRTaskHosted()) { return; @@ -12898,6 +12916,7 @@ void Thread::EndThreadAffinity() _ASSERTE (hr == S_OK); #endif // FEATURE_INCLUDE_ALL_INTERFACES +#endif // !FEATURE_CORECLR } void Thread::SetupThreadForHost() diff --git a/src/vm/threads.h b/src/vm/threads.h index c8c888dcae..1b2f6d8a59 100644 --- a/src/vm/threads.h +++ b/src/vm/threads.h @@ -1787,10 +1787,12 @@ public: private: DWORD m_dwBeginLockCount; // lock count when the thread enters current domain +#ifndef FEATURE_CORECLR DWORD m_dwBeginCriticalRegionCount; // lock count when the thread enters current domain DWORD m_dwCriticalRegionCount; DWORD m_dwThreadAffinityCount; +#endif // !FEATURE_CORECLR #ifdef _DEBUG DWORD dbg_m_cSuspendedThreads; @@ -1883,15 +1885,21 @@ public: LIMITED_METHOD_CONTRACT; _ASSERTE(m_dwLockCount >= m_dwBeginLockCount); +#ifndef FEATURE_CORECLR _ASSERTE(m_dwCriticalRegionCount >= m_dwBeginCriticalRegionCount); +#endif // !FEATURE_CORECLR // Equivalent to (m_dwLockCount != m_dwBeginLockCount || // m_dwCriticalRegionCount ! m_dwBeginCriticalRegionCount), // but without branching instructions - return ((m_dwLockCount ^ m_dwBeginLockCount) | - (m_dwCriticalRegionCount ^ m_dwBeginCriticalRegionCount)); - } + BOOL fHasLock = (m_dwLockCount ^ m_dwBeginLockCount); +#ifndef FEATURE_CORECLR + fHasLock |= (m_dwCriticalRegionCount ^ m_dwBeginCriticalRegionCount); +#endif // !FEATURE_CORECLR + return fHasLock; + } +#ifndef FEATURE_CORECLR inline void BeginCriticalRegion() { LIMITED_METHOD_CONTRACT; @@ -1929,11 +1937,16 @@ public: _ASSERTE (m_dwCriticalRegionCount > 0); m_dwCriticalRegionCount --; } +#endif // !FEATURE_CORECLR inline BOOL HasCriticalRegion() { LIMITED_METHOD_CONTRACT; +#ifndef FEATURE_CORECLR return m_dwCriticalRegionCount != 0; +#else + return FALSE; +#endif } inline DWORD GetNewHashCode() @@ -1980,6 +1993,11 @@ public: static void ReverseEnterRuntimeThrowComplus(); static void ReverseLeaveRuntime(); + // Hook for OS Critical Section, Mutex, and others that require thread affinity + static void BeginThreadAffinity(); + static void EndThreadAffinity(); + +#ifndef FEATURE_CORECLR inline void IncThreadAffinityCount() { LIMITED_METHOD_CONTRACT; @@ -1995,10 +2013,6 @@ public: m_dwThreadAffinityCount --; } - // Hook for OS Critical Section, Mutex, and others that require thread affinity - static void BeginThreadAffinity(); - static void EndThreadAffinity(); - static void BeginThreadAffinityAndCriticalRegion() { LIMITED_METHOD_CONTRACT; @@ -2012,11 +2026,16 @@ public: GetThread()->EndCriticalRegion(); EndThreadAffinity(); } +#endif // !FEATURE_CORECLR BOOL HasThreadAffinity() { LIMITED_METHOD_CONTRACT; +#ifndef FEATURE_CORECLR return m_dwThreadAffinityCount > 0; +#else + return FALSE; +#endif } private: @@ -5539,9 +5558,12 @@ public: LCID GetThreadCultureIdNoThrow(Thread *pThread, BOOL bUICulture); +#ifndef FEATURE_CORECLR // Request/Remove Thread Affinity for the current thread typedef StateHolder ThreadAffinityAndCriticalRegionHolder; +#endif // !FEATURE_CORECLR typedef StateHolder ThreadAffinityHolder; + typedef Thread::ForbidSuspendThreadHolder ForbidSuspendThreadHolder; typedef Thread::ThreadPreventAsyncHolder ThreadPreventAsyncHolder; typedef Thread::ThreadPreventAbortHolder ThreadPreventAbortHolder; -- cgit v1.2.3