[idd] scheduler: reject isolated work timing stalls

This commit is contained in:
Geoffrey McRae
2026-08-06 17:34:25 +10:00
parent 5e7d944607
commit 807ea52b02
2 changed files with 41 additions and 9 deletions

View File

@@ -260,6 +260,9 @@ void CFrameScheduler::Reset()
m_lastArrival = 0;
m_guestPeriod = 0;
m_workEstimate = 0;
memset(m_workTiming, 0, sizeof(m_workTiming));
m_workTimingCount = 0;
m_workTimingIndex = 0;
m_nextDeadline = 0;
m_deadlineSerial = 0;
m_pendingCorrection = 0;
@@ -1017,10 +1020,35 @@ void CFrameScheduler::TryRecordFrameTiming(uint64_t duration)
if (!TryAcquireSRWLockExclusive(&m_lock))
return;
if (!m_workEstimate || duration > m_workEstimate)
m_workEstimate = duration;
m_workTiming[m_workTimingIndex] = duration;
m_workTimingIndex =
(m_workTimingIndex + 1) % WORK_TIMING_HISTORY_SIZE;
if (m_workTimingCount < WORK_TIMING_HISTORY_SIZE)
++m_workTimingCount;
uint64_t sorted[WORK_TIMING_HISTORY_SIZE];
memcpy(sorted, m_workTiming,
m_workTimingCount * sizeof(*sorted));
for (unsigned i = 1; i < m_workTimingCount; ++i)
{
const uint64_t sample = sorted[i];
unsigned j = i;
while (j && sorted[j - 1] > sample)
{
sorted[j] = sorted[j - 1];
--j;
}
sorted[j] = sample;
}
if (m_workTimingCount == 1)
m_workEstimate = sorted[0];
else
m_workEstimate = (m_workEstimate * 31 + duration) / 32;
{
const unsigned discarded = min(m_workTimingCount - 1,
max(1U, m_workTimingCount / 10));
m_workEstimate = sorted[m_workTimingCount - discarded - 1];
}
ReleaseSRWLockExclusive(&m_lock);
}

View File

@@ -80,6 +80,7 @@ private:
};
static const unsigned PUBLICATION_HISTORY_SIZE = 128;
static const unsigned WORK_TIMING_HISTORY_SIZE = 32;
mutable SRWLOCK m_lock = SRWLOCK_INIT;
HANDLE m_wakeEvent = nullptr;
@@ -94,12 +95,15 @@ private:
uint64_t m_republishRequestTicket = 0;
uint64_t m_republishAckTicket = 0;
uint64_t m_lastArrival = 0;
uint64_t m_guestPeriod = 0;
uint64_t m_workEstimate = 0;
uint64_t m_nextDeadline = 0;
uint32_t m_deadlineSerial = 0;
int64_t m_pendingCorrection = 0;
uint64_t m_lastArrival = 0;
uint64_t m_guestPeriod = 0;
uint64_t m_workEstimate = 0;
uint64_t m_workTiming[WORK_TIMING_HISTORY_SIZE] = {};
unsigned m_workTimingCount = 0;
unsigned m_workTimingIndex = 0;
uint64_t m_nextDeadline = 0;
uint32_t m_deadlineSerial = 0;
int64_t m_pendingCorrection = 0;
Publication m_publications[PUBLICATION_HISTORY_SIZE] = {};
unsigned m_publicationIndex = 0;