1
0
Fork 0
mirror of https://github.com/VSadov/Satori.git synced 2025-06-09 17:44:48 +09:00

do not wait 1 msec in suspension.

This commit is contained in:
vsadov 2022-08-18 08:20:30 -07:00
parent ece0c416a2
commit 126476ad1b

View file

@ -3205,6 +3205,35 @@ COR_PRF_SUSPEND_REASON GCSuspendReasonToProfSuspendReason(ThreadSuspend::SUSPEND
}
#endif // PROFILING_SUPPORTED
// exponential spinwait with an approximate time limit for waiting in microsecond range.
// when iteration == -1, only usecLimit is used
void SpinWait(int iteration, int usecLimit)
{
LARGE_INTEGER li;
QueryPerformanceCounter(&li);
int64_t startTicks = li.QuadPart;
QueryPerformanceFrequency(&li);
int64_t ticksPerSecond = li.QuadPart;
int64_t endTicks = startTicks + (usecLimit * ticksPerSecond) / 1000000;
int l = min((unsigned)iteration, 30);
for (int i = 0; i < l; i++)
{
for (int j = 0; j < (1 << i); j++)
{
System_YieldProcessor();
}
QueryPerformanceCounter(&li);
int64_t currentTicks = li.QuadPart;
if (currentTicks > endTicks)
{
break;
}
}
}
//************************************************************************************
//
// SuspendRuntime is responsible for ensuring that all managed threads reach a
@ -3340,6 +3369,7 @@ void ThreadSuspend::SuspendRuntime(ThreadSuspend::SUSPEND_REASON reason)
DWORD dbgStartTimeout = GetTickCount();
#endif
int retries = 0;
while (true)
{
Thread* thread = NULL;
@ -3557,7 +3587,7 @@ void ThreadSuspend::SuspendRuntime(ThreadSuspend::SUSPEND_REASON reason)
if (g_SystemInfo.dwNumberOfProcessors > 1 && (hasProgress || !observeOnly))
{
// small pause
YieldProcessorNormalized();
SpinWait(-1, 5);
STRESS_LOG1(LF_SYNC, LL_INFO1000, "Spinning, %d threads remaining\n", countThreads);
observeOnly = true;
@ -3578,7 +3608,19 @@ void ThreadSuspend::SuspendRuntime(ThreadSuspend::SUSPEND_REASON reason)
// milliseconds, causing long GC pause times.
STRESS_LOG1(LF_SYNC, LL_INFO1000, "Waiting for suspend event %d threads remaining\n", countThreads);
DWORD res = g_pGCSuspendEvent->Wait(PING_JIT_TIMEOUT, FALSE);
// DWORD res = g_pGCSuspendEvent->Wait(PING_JIT_TIMEOUT, FALSE);
SpinWait(retries++, 100);
// make sure our spining is not starving other threads, but not too often,
// this can cause a 1-15 msec delay, depending on OS, and that is a lot while
// very rarely needed, since threads are supposed to be releasing their CPUs
if ((retries & 127) == 0)
{
SwitchToThread();
}
DWORD res = WAIT_OBJECT_0;
#ifdef TIME_SUSPEND
g_SuspendStatistics.wait.Accumulate(