Skip to content

Commit 1998b26

Browse files
VSadovjkotas
andauthored
Move FLS init before EventPipeAdapter::FinishInitialize and the first SetupThread() (#115546)
* fix * PR feedback Co-authored-by: Jan Kotas <[email protected]> * moved profiler init before FinalizerThreadCreate * Update src/coreclr/vm/ceemain.cpp Co-authored-by: Jan Kotas <[email protected]> * create finalizer thread earlier only on Windows. * Update src/coreclr/vm/ceemain.cpp Co-authored-by: Jan Kotas <[email protected]> --------- Co-authored-by: Jan Kotas <[email protected]>
1 parent 330cee1 commit 1998b26

File tree

3 files changed

+51
-38
lines changed

3 files changed

+51
-38
lines changed

src/coreclr/vm/ceemain.cpp

Lines changed: 50 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -839,36 +839,19 @@ void EEStartupHelper()
839839

840840
#ifdef PROFILING_SUPPORTED
841841
// Initialize the profiling services.
842+
// This must happen before Thread::HasStarted() that fires profiler notifications is called on the finalizer thread.
842843
hr = ProfilingAPIUtility::InitializeProfiling();
843844

844845
_ASSERTE(SUCCEEDED(hr));
845846
IfFailGo(hr);
846847
#endif // PROFILING_SUPPORTED
847848

848-
InitializeExceptionHandling();
849-
850-
//
851-
// Install our global exception filter
852-
//
853-
if (!InstallUnhandledExceptionFilter())
854-
{
855-
IfFailGo(E_FAIL);
856-
}
857-
858-
// throws on error
859-
SetupThread();
860-
861-
#ifdef DEBUGGING_SUPPORTED
862-
// Notify debugger once the first thread is created to finish initialization.
863-
if (g_pDebugInterface != NULL)
864-
{
865-
g_pDebugInterface->StartupPhase2(GetThread());
866-
}
867-
#endif
868-
869-
// This isn't done as part of InitializeGarbageCollector() above because
870-
// debugger must be initialized before creating EE thread objects
849+
#ifdef TARGET_WINDOWS
850+
// Create the finalizer thread on windows earlier, as we will need to wait for
851+
// the completion of its initialization part that initializes COM as that has to be done
852+
// before the first Thread is attached. Thus we want to give the thread a bit more time.
871853
FinalizerThread::FinalizerThreadCreate();
854+
#endif
872855

873856
InitPreStubManager();
874857

@@ -882,8 +865,6 @@ void EEStartupHelper()
882865
// of the JIT helpers.
883866
InitJITHelpers1();
884867

885-
SyncBlockCache::Attach();
886-
887868
// Set up the sync block
888869
SyncBlockCache::Start();
889870

@@ -898,6 +879,48 @@ void EEStartupHelper()
898879

899880
IfFailGo(hr);
900881

882+
InitializeExceptionHandling();
883+
884+
//
885+
// Install our global exception filter
886+
//
887+
if (!InstallUnhandledExceptionFilter())
888+
{
889+
IfFailGo(E_FAIL);
890+
}
891+
892+
#ifdef TARGET_WINDOWS
893+
// g_pGCHeap->Initialize() above could take nontrivial time, so by now the finalizer thread
894+
// should have initialized FLS slot for thread cleanup notifications.
895+
// And ensured that COM is initialized (must happen before allocating FLS slot).
896+
// Make sure that this was done before we start creating Thread objects
897+
// Ex: The call to SetupThread below will create and attach a Thread object.
898+
// Event pipe might also do that.
899+
FinalizerThread::WaitForFinalizerThreadStart();
900+
#endif
901+
902+
// throws on error
903+
_ASSERTE(GetThreadNULLOk() == NULL);
904+
SetupThread();
905+
906+
#ifdef DEBUGGING_SUPPORTED
907+
// Notify debugger once the first thread is created to finish initialization.
908+
if (g_pDebugInterface != NULL)
909+
{
910+
g_pDebugInterface->StartupPhase2(GetThread());
911+
}
912+
#endif
913+
914+
#ifndef TARGET_WINDOWS
915+
// This isn't done as part of InitializeGarbageCollector() above because
916+
// debugger must be initialized before creating EE thread objects
917+
FinalizerThread::FinalizerThreadCreate();
918+
#else
919+
// On windows the finalizer thread is already partially created and is waiting
920+
// right before doing HasStarted(). We will release it now.
921+
FinalizerThread::EnableFinalization();
922+
#endif
923+
901924
#ifdef FEATURE_PERFTRACING
902925
// Finish setting up rest of EventPipe - specifically enable SampleProfiler if it was requested at startup.
903926
// SampleProfiler needs to cooperate with the GC which hasn't fully finished setting up in the first part of the
@@ -957,12 +980,6 @@ void EEStartupHelper()
957980
g_MiniMetaDataBuffMaxSize, MEM_COMMIT, PAGE_READWRITE);
958981
#endif // FEATURE_MINIMETADATA_IN_TRIAGEDUMPS
959982

960-
#ifdef TARGET_WINDOWS
961-
// By now finalizer thread should have initialized FLS slot for thread cleanup notifications.
962-
// And ensured that COM is initialized (must happen before allocating FLS slot).
963-
// Make sure that this was done.
964-
FinalizerThread::WaitForFinalizerThreadStart();
965-
#endif
966983
g_fEEStarted = TRUE;
967984
g_EEStartupStatus = S_OK;
968985
hr = S_OK;
@@ -1764,6 +1781,8 @@ void InitFlsSlot()
17641781
// thread - thread to attach
17651782
static void OsAttachThread(void* thread)
17661783
{
1784+
_ASSERTE(g_flsIndex != FLS_OUT_OF_INDEXES);
1785+
17671786
if (t_flsState == FLS_STATE_INVOKED)
17681787
{
17691788
_ASSERTE_ALL_BUILDS(!"Attempt to execute managed code after the .NET runtime thread state has been destroyed.");

src/coreclr/vm/finalizerthread.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,7 @@ DWORD WINAPI FinalizerThread::FinalizerThreadStart(void *args)
386386

387387
// handshake with EE initialization, as now we can attach Thread objects to native threads.
388388
hEventFinalizerDone->Set();
389+
WaitForFinalizerEvent (hEventFinalizer);
389390
#endif
390391

391392
s_FinalizerThreadOK = GetFinalizerThread()->HasStarted();

src/coreclr/vm/syncblk.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -591,13 +591,6 @@ void SyncBlockCache::CleanupSyncBlocks()
591591
} EE_END_FINALLY;
592592
}
593593

594-
// create the sync block cache
595-
/* static */
596-
void SyncBlockCache::Attach()
597-
{
598-
LIMITED_METHOD_CONTRACT;
599-
}
600-
601594
// create the sync block cache
602595
/* static */
603596
void SyncBlockCache::Start()

0 commit comments

Comments
 (0)