[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_lastArrival = 0;
m_guestPeriod = 0; m_guestPeriod = 0;
m_workEstimate = 0; m_workEstimate = 0;
memset(m_workTiming, 0, sizeof(m_workTiming));
m_workTimingCount = 0;
m_workTimingIndex = 0;
m_nextDeadline = 0; m_nextDeadline = 0;
m_deadlineSerial = 0; m_deadlineSerial = 0;
m_pendingCorrection = 0; m_pendingCorrection = 0;
@@ -1017,10 +1020,35 @@ void CFrameScheduler::TryRecordFrameTiming(uint64_t duration)
if (!TryAcquireSRWLockExclusive(&m_lock)) if (!TryAcquireSRWLockExclusive(&m_lock))
return; return;
if (!m_workEstimate || duration > m_workEstimate) m_workTiming[m_workTimingIndex] = duration;
m_workEstimate = 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 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); ReleaseSRWLockExclusive(&m_lock);
} }

View File

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