diff options
author | danmosemsft <danmose@microsoft.com> | 2017-02-10 17:12:53 -0800 |
---|---|---|
committer | danmosemsft <danmose@microsoft.com> | 2017-02-10 21:36:06 -0800 |
commit | 54891e0650e69f08832f75a40dc102efc6115d38 (patch) | |
tree | 0e032a0b337767801f696cbaeacded267c694f32 /src/vm/threadsuspend.cpp | |
parent | 396f7d43b3c0f3ca7034a6d1d9cd7d6914778a1e (diff) | |
download | coreclr-54891e0650e69f08832f75a40dc102efc6115d38.tar.gz coreclr-54891e0650e69f08832f75a40dc102efc6115d38.tar.bz2 coreclr-54891e0650e69f08832f75a40dc102efc6115d38.zip |
Remove always defined FEATURE_CORECLR
Diffstat (limited to 'src/vm/threadsuspend.cpp')
-rw-r--r-- | src/vm/threadsuspend.cpp | 471 |
1 files changed, 0 insertions, 471 deletions
diff --git a/src/vm/threadsuspend.cpp b/src/vm/threadsuspend.cpp index cdfbd79497..d65f3a3af9 100644 --- a/src/vm/threadsuspend.cpp +++ b/src/vm/threadsuspend.cpp @@ -3328,32 +3328,6 @@ void Thread::RareDisablePreemptiveGC() #endif // PROFILING_SUPPORTED -#if !defined(FEATURE_CORECLR) // simple hosting - // First, check to see if there's an IDbgThreadControl interface that needs - // notification of the suspension - if (m_State & TS_DebugSuspendPending) - { - IDebuggerThreadControl *pDbgThreadControl = CorHost::GetDebuggerThreadControl(); - - if (pDbgThreadControl) - pDbgThreadControl->ThreadIsBlockingForDebugger(); - - } - - if (CLRGCHosted()) - { - BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread()); - CorHost2::GetHostGCManager()->ThreadIsBlockingForSuspension(); - END_SO_TOLERANT_CODE_CALLING_HOST; - } - - // If not, check to see if there's an IGCThreadControl interface that needs - // notification of the suspension - IGCThreadControl *pGCThreadControl = CorHost::GetGCThreadControl(); - - if (pGCThreadControl) - pGCThreadControl->ThreadIsBlockingForSuspension(); -#endif // !defined(FEATURE_CORECLR) DWORD status = S_OK; SetThreadStateNC(TSNC_WaitUntilGCFinished); @@ -3453,32 +3427,6 @@ void Thread::RareDisablePreemptiveGC() #endif // PROFILING_SUPPORTED -#if !defined(FEATURE_CORECLR) // simple hosting - // First, check to see if there's an IDbgThreadControl interface that needs - // notification of the suspension - if (m_State & TS_DebugSuspendPending) - { - IDebuggerThreadControl *pDbgThreadControl = CorHost::GetDebuggerThreadControl(); - - if (pDbgThreadControl) - pDbgThreadControl->ThreadIsBlockingForDebugger(); - - } - - if (CLRGCHosted()) - { - BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread()); - CorHost2::GetHostGCManager()->ThreadIsBlockingForSuspension(); - END_SO_TOLERANT_CODE_CALLING_HOST; - } - - // If not, check to see if there's an IGCThreadControl interface that needs - // notification of the suspension - IGCThreadControl *pGCThreadControl = CorHost::GetGCThreadControl(); - - if (pGCThreadControl) - pGCThreadControl->ThreadIsBlockingForSuspension(); -#endif // !defined(FEATURE_CORECLR) // The thread is blocked for shutdown. We do not concern for GC violation. CONTRACT_VIOLATION(GCViolation); @@ -3819,34 +3767,12 @@ void Thread::RareEnablePreemptiveGC() // Life's much simpler this way... -#if !defined(FEATURE_CORECLR) // simple hosting - // Check to see if there's an IDbgThreadControl interface that needs - // notification of the suspension - if (m_State & TS_DebugSuspendPending) - { - IDebuggerThreadControl *pDbgThreadControl = CorHost::GetDebuggerThreadControl(); - - if (pDbgThreadControl) - pDbgThreadControl->ThreadIsBlockingForDebugger(); - - } -#endif // !defined(FEATURE_CORECLR) #endif // DEBUGGING_SUPPORTED #ifdef LOGGING -#if !defined(FEATURE_CORECLR) // simple hosting - if (!CorHost::IsDebuggerSpecialThread(GetThreadId())) -#endif // !defined(FEATURE_CORECLR) { LOG((LF_CORDB, LL_INFO1000, "[0x%x] SUSPEND: suspended while enabling gc.\n", GetThreadId())); } -#if !defined(FEATURE_CORECLR) // simple hosting - else - { - LOG((LF_CORDB, LL_INFO1000, - "[0x%x] ALERT: debugger special thread did not suspend while enabling gc.\n", GetThreadId())); - } -#endif // !defined(FEATURE_CORECLR) #endif WaitSuspendEvents(); // sets bits, too @@ -4186,20 +4112,8 @@ void __stdcall Thread::RedirectedHandledJITCase(RedirectReason reason) // Notify the interface of the pending suspension switch (reason) { case RedirectReason_GCSuspension: -#if !defined(FEATURE_CORECLR) // simple hosting - if (CorHost::GetGCThreadControl()) - CorHost::GetGCThreadControl()->ThreadIsBlockingForSuspension(); - if (CLRGCHosted()) - { - NotifyHostOnGCSuspension(); - } -#endif // !defined(FEATURE_CORECLR) break; case RedirectReason_DebugSuspension: -#if !defined(FEATURE_CORECLR) // simple hosting - if (CorHost::GetDebuggerThreadControl() && CorHost::IsDebuggerSpecialThread(pThread->GetThreadId())) - CorHost::GetDebuggerThreadControl()->ThreadIsBlockingForDebugger(); -#endif // !defined(FEATURE_CORECLR) break; case RedirectReason_UserSuspension: // Do nothing; @@ -4857,21 +4771,6 @@ HRESULT ThreadSuspend::SuspendRuntime(ThreadSuspend::SUSPEND_REASON reason) STRESS_LOG1(LF_SYNC, LL_INFO1000, "Thread::SuspendRuntime(reason=0x%x)\n", reason); -#if !defined(FEATURE_CORECLR) // simple hosting - // Alert the host that a GC is starting, in case the host is scheduling threads - // for non-runtime tasks during GC. - IGCThreadControl *pGCThreadControl = CorHost::GetGCThreadControl(); - - if (pGCThreadControl) - pGCThreadControl->SuspensionStarting(); - - if (CLRGCHosted()) - { - BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread()); - CorHost2::GetHostGCManager()->SuspensionStarting(); - END_SO_TOLERANT_CODE_CALLING_HOST; - } -#endif // !defined(FEATURE_CORECLR) #ifdef PROFILING_SUPPORTED // If the profiler desires information about GCs, then let it know that one @@ -5562,33 +5461,6 @@ void ThreadSuspend::ResumeRuntime(BOOL bFinishedGC, BOOL SuspendSucceded) // Notify everyone who cares, that this suspension is over, and this thread is going to go do other things. // -#if !defined(FEATURE_CORECLR) // simple hosting - // Alert the host that a GC is ending, in case the host is scheduling threads - // for non-runtime tasks during GC. - IGCThreadControl *pGCThreadControl = CorHost::GetGCThreadControl(); - - if (pGCThreadControl) - { - // If we the suspension was for a GC, tell the host what generation GC. - DWORD Generation = (bFinishedGC - ? GCHeapUtilities::GetGCHeap()->GetCondemnedGeneration() - : ~0U); - - pGCThreadControl->SuspensionEnding(Generation); - } - - if (CLRGCHosted()) - { - // If we the suspension was for a GC, tell the host what generation GC. - DWORD Generation = (bFinishedGC - ? GCHeapUtilities::GetGCHeap()->GetCondemnedGeneration() - : ~0U); - - BEGIN_SO_TOLERANT_CODE_CALLING_HOST(GetThread()); - CorHost2::GetHostGCManager()->SuspensionEnding(Generation); - END_SO_TOLERANT_CODE_CALLING_HOST; - } -#endif // !defined(FEATURE_CORECLR) #ifdef PROFILING_SUPPORTED // Need to give resume event for the GC thread @@ -5961,13 +5833,6 @@ bool Thread::SysStartSuspendForDebug(AppDomain *pAppDomain) // Caller is expected to be holding the ThreadStore lock _ASSERTE(ThreadStore::HoldingThreadStore() || IsAtProcessExit()); -#if !defined(FEATURE_CORECLR) // simple hosting - // If there is a debugging thread control object, tell it we're suspending the Runtime. - IDebuggerThreadControl *pDbgThreadControl = CorHost::GetDebuggerThreadControl(); - - if (pDbgThreadControl) - pDbgThreadControl->StartBlockingForDebugger(0); -#endif // !defined(FEATURE_CORECLR) // NOTE::NOTE::NOTE::NOTE::NOTE // This function has parallel logic in SuspendRuntime. Please make @@ -6341,16 +6206,6 @@ void Thread::SysResumeFromDebug(AppDomain *pAppDomain) LOG((LF_CORDB, LL_INFO1000, "RESUME: starting resume AD:0x%x.\n", pAppDomain)); -#if !defined(FEATURE_CORECLR) // simple hosting - // Notify the client that it should release any threads that it had doing work - // while the runtime was debugger-suspended. - IDebuggerThreadControl *pIDTC = CorHost::GetDebuggerThreadControl(); - if (pIDTC) - { - LOG((LF_CORDB, LL_INFO1000, "RESUME: notifying IDebuggerThreadControl client.\n")); - pIDTC->ReleaseAllRuntimeThreads(); - } -#endif // !defined(FEATURE_CORECLR) // Make sure we completed the previous sync _ASSERTE(m_DebugWillSyncCount == -1); @@ -6407,321 +6262,6 @@ void Thread::SysResumeFromDebug(AppDomain *pAppDomain) LOG((LF_CORDB, LL_INFO1000, "RESUME: resume complete. Trap count: %d\n", g_TrapReturningThreads.Load())); } -#ifndef FEATURE_CORECLR - -// Suspend a thread at the system level. We distinguish between user suspensions, -// and system suspensions so that a VB program cannot resume a thread we have -// suspended for GC. -// -// This service won't return until the suspension is complete. This deserves some -// explanation. The thread is considered to be suspended if it can make no further -// progress within the EE. For example, a thread that has exited the EE via -// COM Interop or N/Direct is considered suspended -- if we've arranged it so that -// the thread cannot return back to the EE without blocking. -void Thread::UserSuspendThread() -{ - CONTRACTL { - NOTHROW; - GC_TRIGGERS; - } - CONTRACTL_END; - - // Read the general comments on thread suspension earlier, to understand why we - // take these locks. - - // GC can occur in here: - STRESS_LOG0(LF_SYNC, LL_INFO100, "UserSuspendThread obtain lock\n"); - ThreadStoreLockHolder tsl; - - // User suspensions (e.g. from VB and C#) are distinguished from internal - // suspensions so a poorly behaved program cannot resume a thread that the system - // has suspended for GC. - if (m_State & TS_UserSuspendPending) - { - // This thread is already experiencing a user suspension, so ignore the - // new request. - _ASSERTE(!ThreadStore::HoldingThreadStore(this)); - } - else - if (this != GetThread()) - { - // First suspension of a thread other than the current one. - if (m_State & TS_Unstarted) - { - // There is an important window in here. T1 can call T2.Start() and then - // T2.Suspend(). Suspend is disallowed on an unstarted thread. But from T1's - // point of view, T2 is started. In reality, T2 hasn't been scheduled by the - // OS, so it is still an unstarted thread. We don't want to perform a normal - // suspension on it in this case, because it is currently contributing to the - // PendingThreadCount. We want to get it fully started before we suspend it. - // This is particularly important if its background status is changing - // underneath us because otherwise we might not detect that the process should - // be exited at the right time. - // - // It turns out that this is a simple situation to implement. We are holding - // the ThreadStoreLock. TransferStartedThread will likewise acquire that - // lock. So if we detect it, we simply set a bit telling the thread to - // suspend itself. This is NOT the normal suspension request because we don't - // want the thread to suspend until it has fully started. - FastInterlockOr((ULONG *) &m_State, TS_SuspendUnstarted); - } - else if (m_State & (TS_Detached | TS_Dead)) - { - return; - } - else - { - // We just want to trap this thread if it comes back into cooperative mode - SetupForSuspension(TS_UserSuspendPending); - m_SafeEvent.Reset(); - - // Pause it so we can operate on it without it squirming under us. -RetrySuspension: - // We can not allocate memory after we suspend a thread. - // Otherwise, we may deadlock the process when CLR is hosted. - ThreadStore::AllocateOSContext(); - - SuspendThreadResult str = SuspendThread(); - - // The only safe place to suspend a thread asynchronously is if it is in - // fully interruptible cooperative JIT code. Preemptive mode can hold all - // kinds of locks that make it unsafe to suspend. All other cases are - // handled somewhat synchronously (e.g. through hijacks, GC mode toggles, etc.) - // - // For example, on a SMP if the thread is blocked waiting for the ThreadStore - // lock, it can cause a deadlock if we suspend it (even though it is in - // preemptive mode). - // - // If a thread is in preemptive mode (including the tricky optimized N/Direct - // case), we can just mark it for suspension. It will make no further progress - // in the EE. - if (str == STR_NoStressLog) - { - // We annot assume anything about the thread's current state. - goto RetrySuspension; - } - else if (!m_fPreemptiveGCDisabled) - { - MarkForSuspension(TS_UserSuspendPending); - - // Let the thread run until it reaches a safe spot. - if (str == STR_Success) - { - ResumeThread(); - } - } - else if (str == STR_Failure || str == STR_UnstartedOrDead) - { - // The thread cannot be unstarted, as we have already - // checked for that above. - _ASSERTE(!(m_State & TS_Unstarted)); - - // Nothing to do if the thread has already terminated. - } - else if (str == STR_SwitchedOut) - { - goto RetrySuspension; - } - else - { - _ASSERTE(str == STR_Success); -#if defined(FEATURE_HIJACK) && !defined(PLATFORM_UNIX) - WorkingOnThreadContextHolder workingOnThreadContext(this); - if (workingOnThreadContext.Acquired() && HandledJITCase()) - { - _ASSERTE(m_fPreemptiveGCDisabled); - // Redirect thread so we can capture a good thread context - // (GetThreadContext is not sufficient, due to an OS bug). - // If we don't succeed (should only happen on Win9X, due to - // a different OS bug), we must resume the thread and try - // again. - if (!CheckForAndDoRedirectForUserSuspend()) - { - ResumeThread(); - goto RetrySuspension; - } - } -#endif // FEATURE_HIJACK && !PLATFORM_UNIX - - // Thread is executing in cooperative mode. We're going to have to - // move it to a safe spot. - MarkForSuspension(TS_UserSuspendPending); - - // Let the thread run until it reaches a safe spot. - ResumeThread(); - - // wait until it leaves cooperative GC mode or is JIT suspended - FinishSuspendingThread(); - } - } - } - else - { - GCX_PREEMP(); - SetupForSuspension(TS_UserSuspendPending); - MarkForSuspension(TS_UserSuspendPending); - - // prepare to block ourselves - tsl.Release(); - _ASSERTE(!ThreadStore::HoldingThreadStore(this)); - - WaitSuspendEvents(); - } -} - - -// if the only suspension of this thread is user imposed, resume it. But don't -// resume from any system suspensions (like GC). -BOOL Thread::UserResumeThread() -{ - CONTRACTL { - NOTHROW; - GC_TRIGGERS; - } - CONTRACTL_END; - - // If we are attempting to resume when we aren't in a user suspension, - // its an error. - BOOL res = FALSE; - - // Note that the model does not count. In other words, you can call Thread.Suspend() - // five times and Thread.Resume() once. The result is that the thread resumes. - - STRESS_LOG0(LF_SYNC, INFO3, "UserResumeThread obtain lock\n"); - ThreadStoreLockHolder TSLockHolder; - - // If we have marked a thread for suspension, while that thread is still starting - // up, simply remove the bit to resume it. - if (m_State & TS_SuspendUnstarted) - { - _ASSERTE((m_State & TS_UserSuspendPending) == 0); - FastInterlockAnd((ULONG *) &m_State, ~TS_SuspendUnstarted); - res = TRUE; - } - - // If we are still trying to suspend the thread, forget about it. - if (m_State & TS_UserSuspendPending) - { - ReleaseFromSuspension(TS_UserSuspendPending); - SetSafeEvent(); - res = TRUE; - } - - return res; -} - - -// We are asynchronously trying to suspend this thread. Stay here until we achieve -// that goal (in fully interruptible JIT code), or the thread dies, or it leaves -// the EE (in which case the Pending flag will cause it to synchronously suspend -// itself later, or if the thread tells us it is going to synchronously suspend -// itself because of hijack activity, etc. -void Thread::FinishSuspendingThread() -{ - CONTRACTL { - NOTHROW; - if (GetThread()) {GC_TRIGGERS;} else {DISABLED(GC_NOTRIGGER);} - } - CONTRACTL_END; - - DWORD res; - - // There are two threads of interest -- the current thread and the thread we are - // going to wait for. Since the current thread is about to wait, it's important - // that it be in preemptive mode at this time. - -#if _DEBUG - DWORD dbgTotalTimeout = 0; -#endif - - // Wait for us to enter the ping period, then check if we are in interruptible - // JIT code. - while (TRUE) - { - ThreadSuspend::UnlockThreadStore(); - res = m_SafeEvent.Wait(PING_JIT_TIMEOUT,FALSE); - STRESS_LOG0(LF_SYNC, INFO3, "FinishSuspendingThread obtain lock\n"); - ThreadSuspend::LockThreadStore(ThreadSuspend::SUSPEND_OTHER); - - if (res == WAIT_TIMEOUT) - { -#ifdef _DEBUG - if ((dbgTotalTimeout += PING_JIT_TIMEOUT) >= g_pConfig->SuspendDeadlockTimeout()) - { - _ASSERTE(!"Timeout detected trying to synchronously suspend a thread"); - dbgTotalTimeout = 0; - } -#endif - // Suspend the thread and see if we are in interruptible code (placing - // a hijack if warranted). -#if defined(FEATURE_HIJACK) && !defined(PLATFORM_UNIX) - RetrySuspension: -#endif - // The thread is detached/dead. Suspend is no op. - if (m_State & (TS_Detached | TS_Dead)) - { - return; - } - - // We can not allocate memory after we suspend a thread. - // Otherwise, we may deadlock the process when CLR is hosted. - ThreadStore::AllocateOSContext(); - - SuspendThreadResult str = SuspendThread(); - - if (m_fPreemptiveGCDisabled && str == STR_Success) - { -#if defined(FEATURE_HIJACK) && !defined(PLATFORM_UNIX) - WorkingOnThreadContextHolder workingOnThreadContext(this); - if (workingOnThreadContext.Acquired() && HandledJITCase()) - { - _ASSERTE(m_State & TS_UserSuspendPending); - // Redirect thread so we can capture a good thread context - // (GetThreadContext is not sufficient, due to an OS bug). - // If we don't succeed (should only happen on Win9X, due to - // a different OS bug), we must resume the thread and try - // again. - if (!CheckForAndDoRedirectForUserSuspend()) - { - ResumeThread(); - goto RetrySuspension; - } - } -#endif // FEATURE_HIJACK && !PLATFORM_UNIX - // Keep trying... - ResumeThread(); - } - else if (!m_fPreemptiveGCDisabled) - { - // The thread has transitioned out of the EE. It can't get back in - // without synchronously suspending itself. We can now return to our - // caller since this thread cannot make further progress within the - // EE. - if (str == STR_Success) - { - ResumeThread(); - } - break; - } - else if (str == STR_SwitchedOut) - { - // The task has been switched out while in Cooperative GC mode. - // We will wait for the thread again. - } - } - else - { - // SafeEvent has been set so we don't need to actually suspend. Either - // the thread died, or it will enter a synchronous suspension based on - // the UserSuspendPending bit. - _ASSERTE(res == WAIT_OBJECT_0); - _ASSERTE(!ThreadStore::HoldingThreadStore(this)); - break; - } - } -} - -#endif // FEATURE_CORECLR void Thread::SetSafeEvent() @@ -7008,12 +6548,6 @@ StackWalkAction SWCB_GetExecutionState(CrawlFrame *pCF, VOID *pData) else #endif // FEATURE_CONSERVATIVE_GC { -#ifndef HIJACK_NONINTERRUPTIBLE_THREADS - if (!pES->m_IsInterruptible) - { - notJittedCase = true; - } -#else // HIJACK_NONINTERRUPTIBLE_THREADS // if we're not interruptible right here, we need to determine the // return address for hijacking. if (!pES->m_IsInterruptible) @@ -7087,7 +6621,6 @@ StackWalkAction SWCB_GetExecutionState(CrawlFrame *pCF, VOID *pData) action = SWA_CONTINUE; #endif // !WIN64EXCEPTIONS } -#endif // HIJACK_NONINTERRUPTIBLE_THREADS } // else we are successfully out of here with SWA_ABORT } @@ -7162,7 +6695,6 @@ void STDCALL OnHijackWorker(HijackArgs * pArgs) } CONTRACTL_END; -#ifdef HIJACK_NONINTERRUPTIBLE_THREADS Thread *thread = GetThread(); #ifdef FEATURE_STACK_PROBE @@ -7205,9 +6737,6 @@ void STDCALL OnHijackWorker(HijackArgs * pArgs) #endif // _DEBUG frame.Pop(); -#else - PORTABILITY_ASSERT("OnHijackWorker not implemented on this platform."); -#endif // HIJACK_NONINTERRUPTIBLE_THREADS } ReturnKind GetReturnKindFromMethodTable(Thread *pThread, EECodeInfo *codeInfo) |