mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-08-09 00:31:31 +00:00
[idd] scheduler: preserve concurrent force requests
Replace the shared force and republish booleans with request tickets. A completed publication now acknowledges only requests captured when it began, so a concurrent immediate or cadence-break request survives.
This commit is contained in:
@@ -147,8 +147,16 @@ bool CFrameScheduler::ElectOwner(uint64_t now)
|
||||
m_nextDeadline = m_scheduling ? fastest->nextDelivery : 0;
|
||||
if (m_scheduling && !m_nextDeadline)
|
||||
m_nextDeadline = now + m_schedule.period;
|
||||
m_forceNext = m_scheduling;
|
||||
m_republishNext = m_scheduling;
|
||||
if (m_scheduling)
|
||||
{
|
||||
++m_forceRequestTicket;
|
||||
++m_republishRequestTicket;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_forceAckTicket = m_forceRequestTicket;
|
||||
m_republishAckTicket = m_republishRequestTicket;
|
||||
}
|
||||
|
||||
if (fastest)
|
||||
fastest->lastFeedbackFrameSerial = 0;
|
||||
@@ -178,11 +186,12 @@ void CFrameScheduler::Reset()
|
||||
AcquireSRWLockExclusive(&m_lock);
|
||||
for (Client& client : m_clients)
|
||||
client = {};
|
||||
m_schedule = {};
|
||||
m_scheduling = false;
|
||||
m_forceNext = false;
|
||||
m_republishNext = false;
|
||||
m_epoch = 0;
|
||||
m_schedule = {};
|
||||
m_scheduling = false;
|
||||
m_epoch = 0;
|
||||
|
||||
m_forceAckTicket = m_forceRequestTicket;
|
||||
m_republishAckTicket = m_republishRequestTicket;
|
||||
|
||||
m_lastArrival = 0;
|
||||
m_guestPeriod = 0;
|
||||
@@ -359,11 +368,12 @@ bool CFrameScheduler::UpdateSchedule(uint32_t sourceClientID,
|
||||
}
|
||||
wake |= ElectOwner(now);
|
||||
if (m_scheduling && client->clientID == m_schedule.clientID &&
|
||||
client->generation == m_schedule.generation && client->immediate)
|
||||
client->generation == m_schedule.generation &&
|
||||
(schedule.flags & KVMFR_FRAME_SCHEDULE_IMMEDIATE))
|
||||
{
|
||||
m_forceNext = true;
|
||||
m_republishNext = true;
|
||||
wake = true;
|
||||
++m_forceRequestTicket;
|
||||
++m_republishRequestTicket;
|
||||
wake = true;
|
||||
}
|
||||
wake |= ApplyFeedback(*client, schedule);
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
@@ -447,6 +457,7 @@ bool CFrameScheduler::GetSchedule(Schedule& schedule) const
|
||||
|
||||
void CFrameScheduler::ObserveFrame(uint64_t now)
|
||||
{
|
||||
bool wake = false;
|
||||
AcquireSRWLockExclusive(&m_lock);
|
||||
++m_acquiredFrames;
|
||||
if (m_lastArrival && now > m_lastArrival)
|
||||
@@ -455,7 +466,8 @@ void CFrameScheduler::ObserveFrame(uint64_t now)
|
||||
if (m_guestPeriod && interval > m_guestPeriod * CADENCE_BREAK)
|
||||
{
|
||||
m_guestPeriod = 0;
|
||||
m_forceNext = true;
|
||||
++m_forceRequestTicket;
|
||||
wake = true;
|
||||
}
|
||||
else if (interval >= MIN_SOURCE_PERIOD_NS &&
|
||||
interval <= MAX_PERIOD_NS)
|
||||
@@ -468,12 +480,14 @@ void CFrameScheduler::ObserveFrame(uint64_t now)
|
||||
}
|
||||
m_lastArrival = now;
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
if (wake)
|
||||
WakePublisher();
|
||||
}
|
||||
|
||||
void CFrameScheduler::ForceFrame()
|
||||
{
|
||||
AcquireSRWLockExclusive(&m_lock);
|
||||
m_forceNext = true;
|
||||
++m_forceRequestTicket;
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
WakePublisher();
|
||||
}
|
||||
@@ -492,8 +506,10 @@ bool CFrameScheduler::GetPublishTarget(uint64_t now, uint64_t& target,
|
||||
return true;
|
||||
}
|
||||
|
||||
schedule = m_schedule;
|
||||
republish = m_republishNext;
|
||||
schedule = m_schedule;
|
||||
schedule.forceTicket = m_forceRequestTicket;
|
||||
schedule.republishTicket = m_republishRequestTicket;
|
||||
republish = schedule.republishTicket != m_republishAckTicket;
|
||||
|
||||
const uint64_t safety =
|
||||
max(MIN_SAFETY_NS, m_workEstimate / 8);
|
||||
@@ -502,7 +518,7 @@ bool CFrameScheduler::GetPublishTarget(uint64_t now, uint64_t& target,
|
||||
const uint64_t periodicTarget = m_nextDeadline > lead ?
|
||||
m_nextDeadline - lead : now;
|
||||
|
||||
if (m_forceNext)
|
||||
if (schedule.forceTicket != m_forceAckTicket)
|
||||
{
|
||||
periodic = periodicTarget <= now;
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
@@ -536,13 +552,16 @@ void CFrameScheduler::FramePublished(const Schedule& schedule,
|
||||
schedule.generation == m_schedule.generation &&
|
||||
schedule.epoch == m_schedule.epoch)
|
||||
{
|
||||
m_forceNext = false;
|
||||
m_republishNext = false;
|
||||
if (schedule.forceTicket > m_forceAckTicket)
|
||||
m_forceAckTicket = schedule.forceTicket;
|
||||
if (schedule.republishTicket > m_republishAckTicket)
|
||||
m_republishAckTicket = schedule.republishTicket;
|
||||
|
||||
Client * client = FindClient(m_schedule.clientID);
|
||||
if (client)
|
||||
{
|
||||
client->immediate = false;
|
||||
if (m_republishAckTicket == m_republishRequestTicket)
|
||||
client->immediate = false;
|
||||
client->lastDeliveredFrameSerial = frameSerial;
|
||||
client->deliveredFrameValid = true;
|
||||
}
|
||||
@@ -567,12 +586,14 @@ void CFrameScheduler::FrameRepublished(const Schedule& schedule,
|
||||
schedule.generation == m_schedule.generation &&
|
||||
schedule.epoch == m_schedule.epoch)
|
||||
{
|
||||
m_republishNext = false;
|
||||
if (schedule.republishTicket > m_republishAckTicket)
|
||||
m_republishAckTicket = schedule.republishTicket;
|
||||
|
||||
Client * client = FindClient(m_schedule.clientID);
|
||||
if (client)
|
||||
{
|
||||
client->immediate = false;
|
||||
if (m_republishAckTicket == m_republishRequestTicket)
|
||||
client->immediate = false;
|
||||
client->lastDeliveredFrameSerial = frameSerial;
|
||||
client->deliveredFrameValid = true;
|
||||
client->nextDelivery = m_nextDeadline;
|
||||
|
||||
@@ -39,6 +39,8 @@ public:
|
||||
uint32_t epoch;
|
||||
uint64_t period;
|
||||
uint64_t targetSlack;
|
||||
uint64_t forceTicket;
|
||||
uint64_t republishTicket;
|
||||
};
|
||||
|
||||
private:
|
||||
@@ -65,10 +67,14 @@ private:
|
||||
Client m_clients[LGMP_MAX_CLIENTS] = {};
|
||||
Schedule m_schedule = {};
|
||||
bool m_scheduling = false;
|
||||
bool m_forceNext = false;
|
||||
bool m_republishNext = false;
|
||||
uint32_t m_epoch = 0;
|
||||
|
||||
// A result acknowledges only the request tickets captured by its attempt.
|
||||
uint64_t m_forceRequestTicket = 0;
|
||||
uint64_t m_forceAckTicket = 0;
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user