diff options
author | Austin Wise <AustinWise@gmail.com> | 2017-03-05 17:51:40 -0800 |
---|---|---|
committer | Jan Kotas <jkotas@microsoft.com> | 2017-03-05 17:51:40 -0800 |
commit | 51e968b013e9b1582035f202e004ed024f747f4f (patch) | |
tree | 25b0b82deb3392cbeacb3be81bbf3c29e11e81cb /src/vm/finalizerthread.cpp | |
parent | 118f88dc17c75800ca249330ea41a963d3bae306 (diff) | |
download | coreclr-51e968b013e9b1582035f202e004ed024f747f4f.tar.gz coreclr-51e968b013e9b1582035f202e004ed024f747f4f.tar.bz2 coreclr-51e968b013e9b1582035f202e004ed024f747f4f.zip |
Remove hosting methods that always return false (#9930)
* Remove CLRIoCompletionHosted as it always returns false.
* Remove CLRSyncHosted as it always returns false.
* Remove CLRMemoryHosted as it always returns false.
* Remove CLRTaskHosted as it always returns false.
* Remove CLRAssemblyHosted, CLRGCHosted,and CLRSecurityHosted.
They are not called.
* Remove IsThreadPoolHosted as it always returns false.
* Remove EnterRuntime and LeaveRuntime, as they do nothing.
* Add back calls to RevertIfImpersonated and GCX_PREEMP.
I accidentally deleted the call to RevertIfImpersonated instead of just
removing an extra parameter.
When I removed the HR_LEAVE_RUNTIME_HOLDER macro from windowsruntime.h,
I not only removed a LeaveRuntimeHolder but also a GCX_PREEMP. So I added
it back. The holder and GCX_PREEMP where only inserted when the
FEATURE_LEAVE_RUNTIME_HOLDER macro was defined. Since it is always defined,
I removed it. Also as I understand it, you would always want to have a
GCX_PREEMP before calling into the Windows API as not to block the GC,
so I'm not sure why you would want to disable it.
Diffstat (limited to 'src/vm/finalizerthread.cpp')
-rw-r--r-- | src/vm/finalizerthread.cpp | 286 |
1 files changed, 102 insertions, 184 deletions
diff --git a/src/vm/finalizerthread.cpp b/src/vm/finalizerthread.cpp index befd4c34d0..b19f252517 100644 --- a/src/vm/finalizerthread.cpp +++ b/src/vm/finalizerthread.cpp @@ -342,9 +342,7 @@ void FinalizerThread::ProcessProfilerAttachIfNecessary(ULONGLONG * pui64Timestam STATIC_CONTRACT_GC_NOTRIGGER; STATIC_CONTRACT_MODE_ANY; - if (CLRMemoryHosted() || - CLRSyncHosted() || - (MHandles[kProfilingAPIAttach] == NULL)) + if (MHandles[kProfilingAPIAttach] == NULL) { return; } @@ -397,185 +395,130 @@ void FinalizerThread::ProcessProfilerAttachIfNecessary(ULONGLONG * pui64Timestam void FinalizerThread::WaitForFinalizerEvent (CLREvent *event) { - // TODO wwl: merge the following two blocks - if (!CLRMemoryHosted() && !CLRSyncHosted()) { - // Non-host environment - - // We don't want kLowMemoryNotification to starve out kFinalizer - // (as the latter may help correct the former), and we don't want either - // to starve out kProfilingAPIAttach, as we want decent responsiveness - // to a user trying to attach a profiler. So check in this order: - // kProfilingAPIAttach alone (0 wait) - // kFinalizer alone (2s wait) - // all events together (infinite wait) + // Non-host environment + + // We don't want kLowMemoryNotification to starve out kFinalizer + // (as the latter may help correct the former), and we don't want either + // to starve out kProfilingAPIAttach, as we want decent responsiveness + // to a user trying to attach a profiler. So check in this order: + // kProfilingAPIAttach alone (0 wait) + // kFinalizer alone (2s wait) + // all events together (infinite wait) #ifdef FEATURE_PROFAPI_ATTACH_DETACH - // NULL means check attach event now, and don't worry about how long it was since - // the last time the event was checked. - ProcessProfilerAttachIfNecessary(NULL); + // NULL means check attach event now, and don't worry about how long it was since + // the last time the event was checked. + ProcessProfilerAttachIfNecessary(NULL); #endif // FEATURE_PROFAPI_ATTACH_DETACH - //give a chance to the finalizer event (2s) - switch (event->Wait(2000, FALSE)) - { - case (WAIT_OBJECT_0): - return; - case (WAIT_ABANDONED): - return; - case (WAIT_TIMEOUT): - break; - } - MHandles[kFinalizer] = event->GetHandleUNHOSTED(); - while (1) - { - // WaitForMultipleObjects will wait on the event handles in MHandles - // starting at this offset - UINT uiEventIndexOffsetForWait = 0; + //give a chance to the finalizer event (2s) + switch (event->Wait(2000, FALSE)) + { + case (WAIT_OBJECT_0): + return; + case (WAIT_ABANDONED): + return; + case (WAIT_TIMEOUT): + break; + } + MHandles[kFinalizer] = event->GetHandleUNHOSTED(); + while (1) + { + // WaitForMultipleObjects will wait on the event handles in MHandles + // starting at this offset + UINT uiEventIndexOffsetForWait = 0; - // WaitForMultipleObjects will wait on this number of event handles - DWORD cEventsForWait = kHandleCount; - - // #MHandleTypeValues: - // WaitForMultipleObjects will now wait on a subset of the events in the - // MHandles array. At this point kFinalizer should have a non-NULL entry - // in the array. Wait on the following events: - // - // * kLowMemoryNotification (if it's non-NULL && g_fEEStarted) - // * kFinalizer (always) - // * kProfilingAPIAttach (if it's non-NULL) - // - // The enum code:MHandleType values become important here, as - // WaitForMultipleObjects needs to wait on a contiguous set of non-NULL - // entries in MHandles, so we'll assert the values are contiguous as we - // expect. - _ASSERTE(kLowMemoryNotification == 0); - _ASSERTE((kFinalizer == 1) && (MHandles[1] != NULL)); + // WaitForMultipleObjects will wait on this number of event handles + DWORD cEventsForWait = kHandleCount; + + // #MHandleTypeValues: + // WaitForMultipleObjects will now wait on a subset of the events in the + // MHandles array. At this point kFinalizer should have a non-NULL entry + // in the array. Wait on the following events: + // + // * kLowMemoryNotification (if it's non-NULL && g_fEEStarted) + // * kFinalizer (always) + // * kProfilingAPIAttach (if it's non-NULL) + // + // The enum code:MHandleType values become important here, as + // WaitForMultipleObjects needs to wait on a contiguous set of non-NULL + // entries in MHandles, so we'll assert the values are contiguous as we + // expect. + _ASSERTE(kLowMemoryNotification == 0); + _ASSERTE((kFinalizer == 1) && (MHandles[1] != NULL)); #ifdef FEATURE_PROFAPI_ATTACH_DETACH - _ASSERTE(kProfilingAPIAttach == 2); + _ASSERTE(kProfilingAPIAttach == 2); #endif //FEATURE_PROFAPI_ATTACH_DETACH - // Exclude the low-memory notification event from the wait if the event - // handle is NULL or the EE isn't fully started up yet. - if ((MHandles[kLowMemoryNotification] == NULL) || !g_fEEStarted) - { - uiEventIndexOffsetForWait = kLowMemoryNotification + 1; - cEventsForWait--; - } + // Exclude the low-memory notification event from the wait if the event + // handle is NULL or the EE isn't fully started up yet. + if ((MHandles[kLowMemoryNotification] == NULL) || !g_fEEStarted) + { + uiEventIndexOffsetForWait = kLowMemoryNotification + 1; + cEventsForWait--; + } #ifdef FEATURE_PROFAPI_ATTACH_DETACH - // Exclude kProfilingAPIAttach if it's NULL - if (MHandles[kProfilingAPIAttach] == NULL) - { - cEventsForWait--; - } + // Exclude kProfilingAPIAttach if it's NULL + if (MHandles[kProfilingAPIAttach] == NULL) + { + cEventsForWait--; + } #endif //FEATURE_PROFAPI_ATTACH_DETACH - switch (WaitForMultipleObjectsEx( - cEventsForWait, // # objects to wait on - &(MHandles[uiEventIndexOffsetForWait]), // array of objects to wait on - FALSE, // bWaitAll == FALSE, so wait for first signal + switch (WaitForMultipleObjectsEx( + cEventsForWait, // # objects to wait on + &(MHandles[uiEventIndexOffsetForWait]), // array of objects to wait on + FALSE, // bWaitAll == FALSE, so wait for first signal #if defined(__linux__) && defined(FEATURE_EVENT_TRACE) - LINUX_HEAP_DUMP_TIME_OUT, + LINUX_HEAP_DUMP_TIME_OUT, #else - INFINITE, // timeout + INFINITE, // timeout #endif - FALSE) // alertable + FALSE) // alertable - // Adjust the returned array index for the offset we used, so the return - // value is relative to entire MHandles array - + uiEventIndexOffsetForWait) + // Adjust the returned array index for the offset we used, so the return + // value is relative to entire MHandles array + + uiEventIndexOffsetForWait) + { + case (WAIT_OBJECT_0 + kLowMemoryNotification): + //short on memory GC immediately + GetFinalizerThread()->DisablePreemptiveGC(); + GCHeapUtilities::GetGCHeap()->GarbageCollect(0, TRUE); + GetFinalizerThread()->EnablePreemptiveGC(); + //wait only on the event for 2s + switch (event->Wait(2000, FALSE)) { - case (WAIT_OBJECT_0 + kLowMemoryNotification): - //short on memory GC immediately - GetFinalizerThread()->DisablePreemptiveGC(); - GCHeapUtilities::GetGCHeap()->GarbageCollect(0, TRUE); - GetFinalizerThread()->EnablePreemptiveGC(); - //wait only on the event for 2s - switch (event->Wait(2000, FALSE)) - { - case (WAIT_OBJECT_0): - return; - case (WAIT_ABANDONED): - return; - case (WAIT_TIMEOUT): - break; - } - break; - case (WAIT_OBJECT_0 + kFinalizer): + case (WAIT_OBJECT_0): return; -#ifdef FEATURE_PROFAPI_ATTACH_DETACH - case (WAIT_OBJECT_0 + kProfilingAPIAttach): - // Spawn thread to perform the profiler attach, then resume our wait - ProfilingAPIAttachDetach::ProcessSignaledAttachEvent(); + case (WAIT_ABANDONED): + return; + case (WAIT_TIMEOUT): break; + } + break; + case (WAIT_OBJECT_0 + kFinalizer): + return; +#ifdef FEATURE_PROFAPI_ATTACH_DETACH + case (WAIT_OBJECT_0 + kProfilingAPIAttach): + // Spawn thread to perform the profiler attach, then resume our wait + ProfilingAPIAttachDetach::ProcessSignaledAttachEvent(); + break; #endif // FEATURE_PROFAPI_ATTACH_DETACH #if defined(__linux__) && defined(FEATURE_EVENT_TRACE) - case (WAIT_TIMEOUT + kLowMemoryNotification): - case (WAIT_TIMEOUT + kFinalizer): - if (g_TriggerHeapDump) - { - return; - } - - break; -#endif - default: - //what's wrong? - _ASSERTE (!"Bad return code from WaitForMultipleObjects"); + case (WAIT_TIMEOUT + kLowMemoryNotification): + case (WAIT_TIMEOUT + kFinalizer): + if (g_TriggerHeapDump) + { return; } - } - } - else { - static LONG sLastLowMemoryFromHost = 0; - while (1) { -#if defined(__linux__) && defined(FEATURE_EVENT_TRACE) - DWORD timeout = LINUX_HEAP_DUMP_TIME_OUT; -#else - DWORD timeout = INFINITE; -#endif - if (!CLRMemoryHosted()) - { - if (WaitForSingleObject(MHandles[kLowMemoryNotification], 0) == WAIT_OBJECT_0) { - //short on memory GC immediately - GetFinalizerThread()->DisablePreemptiveGC(); - GCHeapUtilities::GetGCHeap()->GarbageCollect(0, TRUE); - GetFinalizerThread()->EnablePreemptiveGC(); - } - //wait only on the event for 2s - // The previous GC might not wake up finalizer thread if there is - // no objects to be finalized. - timeout = 2000; - } - switch (event->Wait(timeout, FALSE)) - { - case (WAIT_OBJECT_0): - if (CLRMemoryHosted()) - { - if (sLastLowMemoryFromHost != g_bLowMemoryFromHost) - { - sLastLowMemoryFromHost = g_bLowMemoryFromHost; - if (sLastLowMemoryFromHost != 0) - { - GetFinalizerThread()->DisablePreemptiveGC(); - GCHeapUtilities::GetGCHeap()->GarbageCollect(0, TRUE); - GetFinalizerThread()->EnablePreemptiveGC(); - } - } - } - return; - case (WAIT_ABANDONED): - return; - case (WAIT_TIMEOUT): -#if defined(__linux__) && defined(FEATURE_EVENT_TRACE) - if (g_TriggerHeapDump) - { - return; - } + break; #endif - break; - } + default: + //what's wrong? + _ASSERTE (!"Bad return code from WaitForMultipleObjects"); + return; } } } @@ -789,18 +732,6 @@ DWORD __stdcall FinalizerThread::FinalizerThreadStart(void *args) _ASSERTE(s_FinalizerThreadOK); _ASSERTE(GetThread() == GetFinalizerThread()); - // workaround wwl: avoid oom problem for finalizer thread startup. - if (CLRTaskHosted()) - { - SignalFinalizationDone(TRUE); - // SQL's scheduler may give finalizer thread a very small slice of CPU if finalizer thread - // shares a scheduler with other tasks. This can cause severe problem for finalizer thread. - // To reduce pain here, we move finalizer thread off SQL's scheduler. - // But SQL's scheduler does not support IHostTask::Alert on a task off scheduler, so we need - // to return finalizer thread back to scheduler when we wait alertably. - // GetFinalizerThread()->LeaveRuntime((size_t)SetupThreadNoThrow); - } - // finalizer should always park in default domain if (s_FinalizerThreadOK) @@ -958,11 +889,8 @@ void FinalizerThread::FinalizerThreadCreate() } CONTRACTL_END; #ifndef FEATURE_PAL - if (!CLRMemoryHosted()) - { - MHandles[kLowMemoryNotification] = - CreateMemoryResourceNotification(LowMemoryResourceNotification); - } + MHandles[kLowMemoryNotification] = + CreateMemoryResourceNotification(LowMemoryResourceNotification); #endif // FEATURE_PAL hEventFinalizerDone = new CLREvent(); @@ -998,16 +926,6 @@ void FinalizerThread::FinalizerThreadCreate() // debugger may have been detached between the time it got the notification // and the moment we execute the test below. _ASSERTE(dwRet == 1 || dwRet == 2); - - // workaround wwl: make sure finalizer is ready. This avoids OOM problem on finalizer - // thread startup. - if (CLRTaskHosted()) { - FinalizerThreadWait(INFINITE); - if (!s_FinalizerThreadOK) - { - ThrowOutOfMemory(); - } - } } } |