diff options
author | dotnet-bot <dotnet-bot@microsoft.com> | 2015-01-30 14:14:42 -0800 |
---|---|---|
committer | dotnet-bot <dotnet-bot@microsoft.com> | 2015-01-30 14:14:42 -0800 |
commit | ef1e2ab328087c61a6878c1e84f4fc5d710aebce (patch) | |
tree | dee1bbb89e9d722e16b0d1485e3cdd1b6c8e2cfa /src/vm/threads.inl | |
download | coreclr-ef1e2ab328087c61a6878c1e84f4fc5d710aebce.tar.gz coreclr-ef1e2ab328087c61a6878c1e84f4fc5d710aebce.tar.bz2 coreclr-ef1e2ab328087c61a6878c1e84f4fc5d710aebce.zip |
Initial commit to populate CoreCLR repo
[tfs-changeset: 1407945]
Diffstat (limited to 'src/vm/threads.inl')
-rw-r--r-- | src/vm/threads.inl | 297 |
1 files changed, 297 insertions, 0 deletions
diff --git a/src/vm/threads.inl b/src/vm/threads.inl new file mode 100644 index 0000000000..d3d34057ca --- /dev/null +++ b/src/vm/threads.inl @@ -0,0 +1,297 @@ +// +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// +// + + +// +// +/*============================================================ +** +** Header: Threads.inl +** +** Purpose: Implements Thread inline functions +** +** +===========================================================*/ +#ifndef _THREADS_INL +#define _THREADS_INL + +#include "threads.h" +#include "appdomain.hpp" +#include "frames.h" + +#ifdef ENABLE_GET_THREAD_GENERIC_FULL_CHECK +// See code:GetThreadGenericFullCheck +inline /* static */ BOOL Thread::ShouldEnforceEEThreadNotRequiredContracts() +{ + LIMITED_METHOD_CONTRACT; + return s_fEnforceEEThreadNotRequiredContracts; +} +#endif // ENABLE_GET_THREAD_GENERIC_FULL_CHECK + +inline void Thread::IncLockCount() +{ + LIMITED_METHOD_CONTRACT; + _ASSERTE(GetThread() == this); + m_dwLockCount++; + _ASSERTE(m_dwLockCount != 0 || HasThreadStateNC(TSNC_UnbalancedLocks) || GetDomain()->OkToIgnoreOrphanedLocks()); +} + +inline void Thread::DecLockCount() +{ + LIMITED_METHOD_CONTRACT; + _ASSERTE(GetThread() == this); + _ASSERTE(m_dwLockCount > 0 || HasThreadStateNC(TSNC_UnbalancedLocks) || GetDomain()->OkToIgnoreOrphanedLocks()); + m_dwLockCount--; +} + +inline +Frame* Thread::FindFrame(SIZE_T StackPointer) +{ + Frame* pFrame = GetFrame(); + + while ((SIZE_T)pFrame < StackPointer) + { + pFrame = pFrame->Next(); + } + + return pFrame; +} + +inline void Thread::SetThrowable(OBJECTREF pThrowable DEBUG_ARG(ThreadExceptionState::SetThrowableErrorChecking stecFlags)) +{ + WRAPPER_NO_CONTRACT; + + m_ExceptionState.SetThrowable(pThrowable DEBUG_ARG(stecFlags)); +} + +inline void Thread::SetKickOffDomainId(ADID ad) +{ + CONTRACTL { + NOTHROW; + GC_NOTRIGGER; + SO_TOLERANT; + } + CONTRACTL_END; + + m_pKickOffDomainId = ad; +} + + +inline ADID Thread::GetKickOffDomainId() +{ + CONTRACTL { + NOTHROW; + GC_NOTRIGGER; + SO_TOLERANT; + } + CONTRACTL_END; + + _ASSERTE(m_pKickOffDomainId.m_dwId != 0); + return m_pKickOffDomainId; +} + +// get the current notification (if any) from this thread +inline OBJECTHANDLE Thread::GetThreadCurrNotification() +{ + CONTRACTL + { + SO_NOT_MAINLINE; + NOTHROW; + GC_NOTRIGGER; + SUPPORTS_DAC; + } + CONTRACTL_END; + + return m_hCurrNotification; +} + +// set the current notification (if any) from this thread +inline void Thread::SetThreadCurrNotification(OBJECTHANDLE handle) +{ + CONTRACTL + { + SO_NOT_MAINLINE; + NOTHROW; + GC_NOTRIGGER; + } + CONTRACTL_END; + + m_hCurrNotification = handle; +} + +// clear the current notification (if any) from this thread +inline void Thread::ClearThreadCurrNotification() +{ + CONTRACTL + { + SO_NOT_MAINLINE; + NOTHROW; + GC_NOTRIGGER; + } + CONTRACTL_END; + + m_hCurrNotification = NULL; +} + + +inline OBJECTREF Thread::GetExposedObjectRaw() +{ + CONTRACTL { + NOTHROW; + GC_NOTRIGGER; + SO_TOLERANT; + SUPPORTS_DAC; + } + CONTRACTL_END; + + return ObjectFromHandle(m_ExposedObject); +} + +inline void Thread::FinishSOWork() +{ + WRAPPER_NO_CONTRACT; +#ifdef FEATURE_STACK_PROBE + if (HasThreadStateNC(TSNC_SOWorkNeeded)) + { + ResetThreadStateNC(TSNC_SOWorkNeeded); + // Wake up AD unload thread to finish SO work that is delayed due to limit stack + AppDomain::EnableADUnloadWorkerForThreadAbort(); + } +#else + _ASSERTE(!HasThreadStateNC(TSNC_SOWorkNeeded)); +#endif +} + +inline DWORD Thread::IncrementOverridesCount() +{ + WRAPPER_NO_CONTRACT; + return m_ADStack.IncrementOverridesCount(); +} + +inline DWORD Thread::DecrementOverridesCount() +{ + WRAPPER_NO_CONTRACT; + return m_ADStack.DecrementOverridesCount(); +} + +inline DWORD Thread::GetOverridesCount() +{ + WRAPPER_NO_CONTRACT; + return m_ADStack.GetOverridesCount(); +} + +inline DWORD Thread::IncrementAssertCount() +{ + WRAPPER_NO_CONTRACT; + return m_ADStack.IncrementAssertCount(); +} + +inline DWORD Thread::DecrementAssertCount() +{ + WRAPPER_NO_CONTRACT; + return m_ADStack.DecrementAssertCount(); +} + +inline DWORD Thread::GetAssertCount() +{ + LIMITED_METHOD_CONTRACT; + return m_ADStack.GetAssertCount(); +} + +#ifndef DACCESS_COMPILE +inline void Thread::PushDomain(ADID pDomain) +{ + WRAPPER_NO_CONTRACT; + m_ADStack.PushDomain(pDomain); +} + +inline ADID Thread::PopDomain() +{ + WRAPPER_NO_CONTRACT; + return m_ADStack.PopDomain(); +} +#endif // DACCESS_COMPILE + +inline DWORD Thread::GetNumAppDomainsOnThread() +{ + WRAPPER_NO_CONTRACT; + return m_ADStack.GetNumDomains(); +} + +inline BOOL Thread::CheckThreadWideSpecialFlag(DWORD flags) +{ + WRAPPER_NO_CONTRACT; + return m_ADStack.GetThreadWideSpecialFlag() & flags; +} + +inline void Thread::InitDomainIteration(DWORD *pIndex) +{ + WRAPPER_NO_CONTRACT; + m_ADStack.InitDomainIteration(pIndex); +} + +inline ADID Thread::GetNextDomainOnStack(DWORD *pIndex, DWORD *pOverrides, DWORD *pAsserts) +{ + WRAPPER_NO_CONTRACT; + return m_ADStack.GetNextDomainOnStack(pIndex, pOverrides, pAsserts); +} + +inline void Thread::UpdateDomainOnStack(DWORD pIndex, DWORD asserts, DWORD overrides) +{ + WRAPPER_NO_CONTRACT; + return m_ADStack.UpdateDomainOnStack(pIndex, asserts, overrides); +} + +#ifdef FEATURE_COMINTEROP +inline void Thread::RevokeApartmentSpy() +{ + LIMITED_METHOD_CONTRACT; + + if (m_fInitializeSpyRegistered) + { + VERIFY(SUCCEEDED(CoRevokeInitializeSpy(m_uliInitializeSpyCookie))); + m_fInitializeSpyRegistered = false; + } +} + +inline LPVOID Thread::GetLastSTACtxCookie(BOOL *pfNAContext) +{ + LIMITED_METHOD_CONTRACT; + *pfNAContext = ((UINT_PTR)m_pLastSTACtxCookie & 1); + return (LPVOID)((UINT_PTR)m_pLastSTACtxCookie & ~1); +} + +inline void Thread::SetLastSTACtxCookie(LPVOID pCtxCookie, BOOL fNAContext) +{ + LIMITED_METHOD_CONTRACT; + if (fNAContext) + { + // The ctx cookie is an interface pointer so we can steal the lowest bit + // to mark whether the context is known to be Neutral Apartment or not. + m_pLastSTACtxCookie = (LPVOID)((UINT_PTR)pCtxCookie | 1); + } + else + { + m_pLastSTACtxCookie = pCtxCookie; + } +} +#endif // FEATURE_COMINTEROP + +#include "appdomainstack.inl" + +inline bool Thread::IsGCSpecial() +{ + LIMITED_METHOD_CONTRACT; + return m_fGCSpecial; +} + +inline void Thread::SetGCSpecial(bool fGCSpecial) +{ + LIMITED_METHOD_CONTRACT; + m_fGCSpecial = fGCSpecial; +} + +#endif |