Skip to content

Commit 00a8973

Browse files
authored
Porting SuspendAllThreads from the NativeAOT to CoreCLR. (#101782)
* port suspension algo from NativeAOT * PING_JIT_TIMEOUT gone * CatchAtSafePoint is always opportunistic * current * removed RareEnablePreemptiveGC * cleanup RareDisablePreemptiveGC * fix for x86 * factored out Thread::Hijack * fix build for non-x64 windows * assert noone holds TSL into coop mode * activation safety check is always for the current thread * undo comment * PulseGCMode should not check for CatchAtSafePointOpportunistic * not disabling preempt while holding TSL * tweak * dead assert * tweak RareDisablePreemptiveGC * RareDisablePreemptiveGC avoid GetSuspensionThread() * updated Thread::Hijack * fix typo * allow coop mode while holding TS lock * Refactored into SuspendAllThreads/ResumeAllThreads * SetThreadTrapForSuspension * deleted TS_GCSuspendPending * tweaks * PR feedback
1 parent 6b03ebd commit 00a8973

26 files changed

Lines changed: 684 additions & 966 deletions

docs/design/datacontracts/Thread.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,7 @@ enum ThreadState
2222
2323
TS_AbortRequested = 0x00000001, // Abort the thread
2424
25-
TS_GCSuspendPending = 0x00000002, // ThreadSuspend::SuspendRuntime watches this thread to leave coop mode.
2625
TS_GCSuspendRedirected = 0x00000004, // ThreadSuspend::SuspendRuntime has redirected the thread to suspention routine.
27-
TS_GCSuspendFlags = TS_GCSuspendPending | TS_GCSuspendRedirected, // used to track suspension progress. Only SuspendRuntime writes/resets these.
2826
2927
TS_DebugSuspendPending = 0x00000008, // Is the debugger suspending threads?
3028
TS_GCOnTransitions = 0x00000010, // Force a GC on stub transitions (GCStress only)

src/coreclr/debug/ee/debugger.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3893,7 +3893,7 @@ HANDLE OpenWin32EventOrThrow(
38933893
// debugger may not be expecting it. Instead, just leave the lock and retry.
38943894
// When we leave, we'll enter coop mode first and get suspended if a suspension is in progress.
38953895
// Afterwards, we'll transition back into preemptive mode, and we'll block because this thread
3896-
// has been suspended by the debugger (see code:Thread::RareEnablePreemptiveGC).
3896+
// has been suspended by the debugger (see code:Thread::RareDisablePreemptiveGC).
38973897
#define SENDIPCEVENT_BEGIN_EX(pDebugger, thread, gcxStmt) \
38983898
{ \
38993899
FireEtwDebugIPCEventStart(); \

src/coreclr/nativeaot/Runtime/thread.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -328,14 +328,6 @@ bool Thread::IsGCSpecial()
328328
return IsStateSet(TSF_IsGcSpecialThread);
329329
}
330330

331-
bool Thread::CatchAtSafePoint()
332-
{
333-
// This is only called by the GC on a background GC worker thread that's explicitly interested in letting
334-
// a foreground GC proceed at that point. So it's always safe to return true.
335-
ASSERT(IsGCSpecial());
336-
return true;
337-
}
338-
339331
uint64_t Thread::GetPalThreadIdForLogging()
340332
{
341333
return m_threadId;

src/coreclr/nativeaot/Runtime/thread.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,6 @@ class Thread : private ThreadBuffer
297297
//
298298
void SetGCSpecial();
299299
bool IsGCSpecial();
300-
bool CatchAtSafePoint();
301300

302301
//
303302
// Managed/unmanaged interop transitions support APIs

src/coreclr/pal/inc/pal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3772,7 +3772,7 @@ PALAPI
37723772
FlushProcessWriteBuffers();
37733773

37743774
typedef void (*PAL_ActivationFunction)(CONTEXT *context);
3775-
typedef BOOL (*PAL_SafeActivationCheckFunction)(SIZE_T ip, BOOL checkingCurrentThread);
3775+
typedef BOOL (*PAL_SafeActivationCheckFunction)(SIZE_T ip);
37763776

37773777
PALIMPORT
37783778
VOID

src/coreclr/pal/src/exception/signal.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -833,7 +833,7 @@ static void inject_activation_handler(int code, siginfo_t *siginfo, void *contex
833833
&winContext,
834834
contextFlags);
835835

836-
if (g_safeActivationCheckFunction(CONTEXTGetPC(&winContext), /* checkingCurrentThread */ TRUE))
836+
if (g_safeActivationCheckFunction(CONTEXTGetPC(&winContext)))
837837
{
838838
g_inject_activation_context_locvar_offset = (int)((char*)&winContext - (char*)__builtin_frame_address(0));
839839
int savedErrNo = errno; // Make sure that errno is not modified

src/coreclr/vm/comtoclrcall.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,7 @@ extern "C" UINT64 __stdcall COMToCLRWorker(Thread *pThread, ComMethodFrame* pFra
515515
// we have additional checks for thread abort that are performed only when
516516
// g_TrapReturningThreads is set.
517517
pThread->m_fPreemptiveGCDisabled.StoreWithoutBarrier(1);
518-
if (g_TrapReturningThreads.LoadWithoutBarrier())
518+
if (g_TrapReturningThreads)
519519
{
520520
hr = StubRareDisableHRWorker(pThread);
521521
if (S_OK != hr)
@@ -1339,14 +1339,12 @@ Stub* ComCall::CreateGenericComCallStub(BOOL isFieldAccess)
13391339
// ends up throwing an OOM exception.
13401340

13411341
CodeLabel* rgRareLabels[] = {
1342-
psl->NewCodeLabel(),
13431342
psl->NewCodeLabel(),
13441343
psl->NewCodeLabel()
13451344
};
13461345

13471346

13481347
CodeLabel* rgRejoinLabels[] = {
1349-
psl->NewCodeLabel(),
13501348
psl->NewCodeLabel(),
13511349
psl->NewCodeLabel()
13521350
};

src/coreclr/vm/eedbginterfaceimpl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -652,7 +652,7 @@ void EEDbgInterfaceImpl::EnablePreemptiveGC(void)
652652
CONTRACTL
653653
{
654654
NOTHROW;
655-
DISABLED(GC_TRIGGERS); // Disabled because disabled in RareEnablePreemptiveGC()
655+
GC_NOTRIGGER;
656656
}
657657
CONTRACTL_END;
658658

src/coreclr/vm/fcall.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ NOINLINE Object* FC_GCPoll(void* __me, Object* objToProtect)
129129
INCONTRACT(FCallCheck __fCallCheck(__FILE__, __LINE__));
130130

131131
Thread *thread = GetThread();
132-
if (thread->CatchAtSafePointOpportunistic()) // Does someone want this thread stopped?
132+
if (thread->CatchAtSafePoint()) // Does someone want this thread stopped?
133133
{
134134
HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_1(Frame::FRAME_ATTR_CAPTURE_DEPTH_2, objToProtect);
135135

src/coreclr/vm/fcall.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -809,7 +809,7 @@ Object* FC_GCPoll(void* me, Object* objToProtect = NULL);
809809
{ \
810810
INCONTRACT(Thread::TriggersGC(GetThread());) \
811811
INCONTRACT(__fCallCheck.SetDidPoll();) \
812-
if (g_TrapReturningThreads.LoadWithoutBarrier()) \
812+
if (g_TrapReturningThreads) \
813813
{ \
814814
if (FC_GCPoll(__me)) \
815815
return ret; \
@@ -824,7 +824,7 @@ Object* FC_GCPoll(void* me, Object* objToProtect = NULL);
824824
{ \
825825
INCONTRACT(__fCallCheck.SetDidPoll();) \
826826
Object* __temp = OBJECTREFToObject(obj); \
827-
if (g_TrapReturningThreads.LoadWithoutBarrier()) \
827+
if (g_TrapReturningThreads) \
828828
{ \
829829
__temp = FC_GCPoll(__me, __temp); \
830830
while (0 == FC_NO_TAILCALL) { }; /* side effect the compile can't remove */ \

0 commit comments

Comments
 (0)