Skip to content

Commit 06651ee

Browse files
VSadovjkotas
authored andcommitted
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 22cf0cd commit 06651ee

File tree

3 files changed

+51
-15
lines changed

3 files changed

+51
-15
lines changed

src/coreclr/vm/ceemain.cpp

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -862,6 +862,7 @@ void EEStartupHelper()
862862

863863
#ifdef PROFILING_SUPPORTED
864864
// Initialize the profiling services.
865+
// This must happen before Thread::HasStarted() that fires profiler notifications is called on the finalizer thread.
865866
hr = ProfilingAPIUtility::InitializeProfiling();
866867

867868
_ASSERTE(SUCCEEDED(hr));
@@ -891,7 +892,12 @@ void EEStartupHelper()
891892

892893
// This isn't done as part of InitializeGarbageCollector() above because
893894
// debugger must be initialized before creating EE thread objects
895+
#ifdef TARGET_WINDOWS
896+
// Create the finalizer thread on windows earlier, as we will need to wait for
897+
// the completion of its initialization part that initializes COM as that has to be done
898+
// before the first Thread is attached. Thus we want to give the thread a bit more time.
894899
FinalizerThread::FinalizerThreadCreate();
900+
#endif
895901

896902
InitPreStubManager();
897903

@@ -906,8 +912,6 @@ void EEStartupHelper()
906912
InitJITHelpers1();
907913
InitJITHelpers2();
908914

909-
SyncBlockCache::Attach();
910-
911915
// Set up the sync block
912916
SyncBlockCache::Start();
913917

@@ -922,6 +926,48 @@ void EEStartupHelper()
922926

923927
IfFailGo(hr);
924928

929+
InitializeExceptionHandling();
930+
931+
//
932+
// Install our global exception filter
933+
//
934+
if (!InstallUnhandledExceptionFilter())
935+
{
936+
IfFailGo(E_FAIL);
937+
}
938+
939+
#ifdef TARGET_WINDOWS
940+
// g_pGCHeap->Initialize() above could take nontrivial time, so by now the finalizer thread
941+
// should have initialized FLS slot for thread cleanup notifications.
942+
// And ensured that COM is initialized (must happen before allocating FLS slot).
943+
// Make sure that this was done before we start creating Thread objects
944+
// Ex: The call to SetupThread below will create and attach a Thread object.
945+
// Event pipe might also do that.
946+
FinalizerThread::WaitForFinalizerThreadStart();
947+
#endif
948+
949+
// throws on error
950+
_ASSERTE(GetThreadNULLOk() == NULL);
951+
SetupThread();
952+
953+
#ifdef DEBUGGING_SUPPORTED
954+
// Notify debugger once the first thread is created to finish initialization.
955+
if (g_pDebugInterface != NULL)
956+
{
957+
g_pDebugInterface->StartupPhase2(GetThread());
958+
}
959+
#endif
960+
961+
#ifndef TARGET_WINDOWS
962+
// This isn't done as part of InitializeGarbageCollector() above because
963+
// debugger must be initialized before creating EE thread objects
964+
FinalizerThread::FinalizerThreadCreate();
965+
#else
966+
// On windows the finalizer thread is already partially created and is waiting
967+
// right before doing HasStarted(). We will release it now.
968+
FinalizerThread::EnableFinalization();
969+
#endif
970+
925971
#ifdef FEATURE_PERFTRACING
926972
// Finish setting up rest of EventPipe - specifically enable SampleProfiler if it was requested at startup.
927973
// SampleProfiler needs to cooperate with the GC which hasn't fully finished setting up in the first part of the
@@ -982,12 +1028,6 @@ void EEStartupHelper()
9821028
g_MiniMetaDataBuffMaxSize, MEM_COMMIT, PAGE_READWRITE);
9831029
#endif // FEATURE_MINIMETADATA_IN_TRIAGEDUMPS
9841030

985-
#ifdef TARGET_WINDOWS
986-
// By now finalizer thread should have initialized FLS slot for thread cleanup notifications.
987-
// And ensured that COM is initialized (must happen before allocating FLS slot).
988-
// Make sure that this was done.
989-
FinalizerThread::WaitForFinalizerThreadStart();
990-
#endif
9911031
g_fEEStarted = TRUE;
9921032
g_EEStartupStatus = S_OK;
9931033
hr = S_OK;
@@ -1794,6 +1834,8 @@ void InitFlsSlot()
17941834
// thread - thread to attach
17951835
static void OsAttachThread(void* thread)
17961836
{
1837+
_ASSERTE(g_flsIndex != FLS_OUT_OF_INDEXES);
1838+
17971839
if (t_flsState == FLS_STATE_INVOKED)
17981840
{
17991841
_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
@@ -445,6 +445,7 @@ DWORD WINAPI FinalizerThread::FinalizerThreadStart(void *args)
445445

446446
// handshake with EE initialization, as now we can attach Thread objects to native threads.
447447
hEventFinalizerDone->Set();
448+
WaitForFinalizerEvent (hEventFinalizer);
448449
#endif
449450

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

src/coreclr/vm/syncblk.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -625,13 +625,6 @@ void SyncBlockCache::CleanupSyncBlocks()
625625
} EE_END_FINALLY;
626626
}
627627

628-
// create the sync block cache
629-
/* static */
630-
void SyncBlockCache::Attach()
631-
{
632-
LIMITED_METHOD_CONTRACT;
633-
}
634-
635628
// create the sync block cache
636629
/* static */
637630
void SyncBlockCache::Start()

0 commit comments

Comments
 (0)