use super::*;
impl TaskSystem {
pub(in crate::sched::system::task_system) fn service_expired_park_deadline(
&self,
event: ExpiredTaskDeadline,
) -> Result<(), TaskError> {
let Some(thread) = event.thread() else {
return Ok(());
};
let handle = match self.thread_handle(thread) {
Ok(handle) => handle,
Err(TaskError::StaleThreadId) => return Ok(()),
Err(error) => return Err(error),
};
let completed = handle.core.complete_sleep_timer(event.token().generation());
let park_matches = event.kind().is_some_and(|kind| {
kind.park_generation() == Some(handle.core.ordinary_park_generation())
});
if completed && park_matches {
let _wake_result = handle.wake_handle().wake();
}
Ok(())
}
pub(crate) fn service_expired_scheduler_deadline(
&self,
cpu: Pin<&mut CpuLocal>,
event: ExpiredTaskDeadline,
) -> Result<(), TaskError> {
let Some(thread) = event.thread() else {
return Ok(());
};
let Some(core) = cpu
.remote()
.lock_run_queue(RunQueueGuardSource::DeadlineAccounting)
.deadline_member(thread)
else {
return Ok(());
};
match event.kind() {
Some(TaskDeadlineKind::DeadlineCbs) => {
self.service_expired_deadline_cbs(cpu, core, event)
}
Some(TaskDeadlineKind::DeadlineZeroLag) => {
self.service_expired_deadline_zero_lag(cpu, core, event)
}
Some(TaskDeadlineKind::ParkTimeout { .. }) | None => Ok(()),
}
}
pub(crate) fn service_due_hard_timers(
&self,
mut cpu: Pin<&mut CpuLocal>,
now: MonotonicInstant,
budget: usize,
) -> Result<HardTimerServiceBatch, TaskError> {
let mut processed = 0;
loop {
let claim = match cpu.as_mut().claim_due_hard_timer_step(now, budget)? {
HardTimerServiceStep::Claim(claim) => claim,
HardTimerServiceStep::Complete { soft } => {
return Ok(HardTimerServiceBatch { processed, soft });
}
};
match claim {
HardTimerServiceClaim::Scheduler(event) => {
self.service_expired_scheduler_deadline(cpu.as_mut(), event)?;
}
HardTimerServiceClaim::Park(thread) => {
if let Some(thread) = thread {
let _wake_result =
self.wake_thread_from_current_cpu(&thread, WakeIntent::Normal);
}
}
HardTimerServiceClaim::Kernel(mut execution) => {
let action = unsafe {
execution.invoke_hard()
};
cpu.as_mut()
.complete_hard_kernel_timer_execution(execution, action);
}
}
processed += 1;
}
}
pub(super) fn service_expired_deadline_cbs(
&self,
cpu: Pin<&mut CpuLocal>,
core: Arc<ThreadCore>,
event: ExpiredTaskDeadline,
) -> Result<(), TaskError> {
let owner = cpu.owner();
let mut sched = core.sched().lock();
if !Self::take_expired_registration(&mut sched.deadline.cbs_timer, event) {
return Ok(());
}
if sched.deadline.bandwidth.reservation_owner() != Some(owner) {
return Err(TaskError::CpuOwnerMismatch {
expected: sched
.deadline
.bandwidth
.reservation_owner()
.map_or(u32::MAX, CpuId::as_u32),
actual: owner.as_u32(),
});
}
self.refresh_owner_deadline_timers_locked(&core, &mut sched, cpu);
Ok(())
}
pub(super) fn service_expired_deadline_zero_lag(
&self,
cpu: Pin<&mut CpuLocal>,
core: Arc<ThreadCore>,
event: ExpiredTaskDeadline,
) -> Result<(), TaskError> {
let owner = cpu.owner();
let mut sched = core.sched().lock();
if !Self::take_expired_registration(&mut sched.deadline.zero_lag_timer, event) {
return Ok(());
}
if sched.deadline.bandwidth.reservation_owner() != Some(owner) {
return Err(TaskError::CpuOwnerMismatch {
expected: sched
.deadline
.bandwidth
.reservation_owner()
.map_or(u32::MAX, CpuId::as_u32),
actual: owner.as_u32(),
});
}
self.refresh_owner_deadline_timers_locked(&core, &mut sched, cpu);
Ok(())
}
}