mirror of
https://github.com/VSadov/Satori.git
synced 2025-06-09 17:44:48 +09:00
Suspend SpinWait tweak
This commit is contained in:
parent
9bcf08d5e9
commit
1dad554930
2 changed files with 38 additions and 21 deletions
|
@ -222,27 +222,39 @@ void ThreadStore::UnlockThreadStore()
|
|||
m_Lock.Leave();
|
||||
}
|
||||
|
||||
// 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)
|
||||
// spinwait with an approximate time limit for waiting in microsecond range.
|
||||
void SpinWait(int usecLimit)
|
||||
{
|
||||
int64_t startTicks = PalQueryPerformanceCounter();
|
||||
int64_t ticksPerSecond = PalQueryPerformanceFrequency();
|
||||
int64_t endTicks = startTicks + (usecLimit * ticksPerSecond) / 1000000;
|
||||
|
||||
int l = min((unsigned)iteration, 30);
|
||||
for (int i = 0; i < l; i++)
|
||||
#ifdef TARGET_UNIX
|
||||
if (usecLimit > 10)
|
||||
{
|
||||
for (int j = 0; j < (1 << i); j++)
|
||||
struct timespec requested;
|
||||
struct timespec remaining;
|
||||
requested.tv_sec = 0;
|
||||
requested.tv_nsec = usecLimit * 1000;
|
||||
while (nanosleep(&requested, &remaining) == EINTR)
|
||||
{
|
||||
System_YieldProcessor();
|
||||
requested = remaining;
|
||||
}
|
||||
}
|
||||
#endif // TARGET_UNIX
|
||||
|
||||
for (int i = 0; i < 30; i++)
|
||||
{
|
||||
int64_t currentTicks = PalQueryPerformanceCounter();
|
||||
if (currentTicks > endTicks)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
for (int j = 0; j < (1 << i); j++)
|
||||
{
|
||||
System_YieldProcessor();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -297,12 +309,12 @@ void ThreadStore::SuspendAllThreads(bool waitForGCEvent)
|
|||
if (remaining < prevRemaining || !observeOnly)
|
||||
{
|
||||
// 5 usec delay, then check for more progress
|
||||
SpinWait(-1, 5);
|
||||
SpinWait(5);
|
||||
observeOnly = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
SpinWait(retries++, 100);
|
||||
SpinWait(min(1 << retries++, 100));
|
||||
observeOnly = false;
|
||||
|
||||
// make sure our spining is not starving other threads, but not too often,
|
||||
|
|
|
@ -3206,8 +3206,7 @@ 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)
|
||||
void SpinWait(int usecLimit)
|
||||
{
|
||||
LARGE_INTEGER li;
|
||||
QueryPerformanceCounter(&li);
|
||||
|
@ -3217,20 +3216,26 @@ void SpinWait(int iteration, int usecLimit)
|
|||
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++)
|
||||
#ifdef TARGET_UNIX
|
||||
if (usecLimit > 10)
|
||||
{
|
||||
for (int j = 0; j < (1 << i); j++)
|
||||
{
|
||||
System_YieldProcessor();
|
||||
PAL_nanosleep(usecLimit * 1000);
|
||||
}
|
||||
#endif // TARGET_UNIX
|
||||
|
||||
for (int i = 0; i < 30; i++)
|
||||
{
|
||||
QueryPerformanceCounter(&li);
|
||||
int64_t currentTicks = li.QuadPart;
|
||||
if (currentTicks > endTicks)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
for (int j = 0; j < (1 << i); j++)
|
||||
{
|
||||
System_YieldProcessor();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3587,7 +3592,7 @@ void ThreadSuspend::SuspendRuntime(ThreadSuspend::SUSPEND_REASON reason)
|
|||
if (g_SystemInfo.dwNumberOfProcessors > 1 && (hasProgress || !observeOnly))
|
||||
{
|
||||
// small pause
|
||||
SpinWait(-1, 5);
|
||||
SpinWait(5);
|
||||
|
||||
STRESS_LOG1(LF_SYNC, LL_INFO1000, "Spinning, %d threads remaining\n", countThreads);
|
||||
observeOnly = true;
|
||||
|
@ -3610,7 +3615,7 @@ void ThreadSuspend::SuspendRuntime(ThreadSuspend::SUSPEND_REASON reason)
|
|||
STRESS_LOG1(LF_SYNC, LL_INFO1000, "Waiting for suspend event %d threads remaining\n", countThreads);
|
||||
// DWORD res = g_pGCSuspendEvent->Wait(PING_JIT_TIMEOUT, FALSE);
|
||||
|
||||
SpinWait(retries++, 100);
|
||||
SpinWait(min(1 << 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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue