use super::*;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
enum DeadlineBandwidthActivity {
Inactive,
Contending,
NonContending { zero_lag: SchedulerTimestamp },
}
#[derive(Debug)]
pub(in crate::sched::system) struct DeadlineBandwidthState {
reservation_owner: Option<CpuId>,
reservation_scaled: u64,
activity: DeadlineBandwidthActivity,
}
impl DeadlineBandwidthState {
const fn new(reservation_scaled: u64) -> Self {
Self {
reservation_owner: None,
reservation_scaled,
activity: DeadlineBandwidthActivity::Inactive,
}
}
pub(in crate::sched::system) const fn reservation_owner(&self) -> Option<CpuId> {
self.reservation_owner
}
pub(in crate::sched::system) const fn reservation_scaled(&self) -> u64 {
self.reservation_scaled
}
pub(in crate::sched::system) const fn activity(&self) -> DeadlineActivity {
match self.activity {
DeadlineBandwidthActivity::Inactive => DeadlineActivity::Inactive,
DeadlineBandwidthActivity::Contending => DeadlineActivity::ActiveContending,
DeadlineBandwidthActivity::NonContending { .. } => {
DeadlineActivity::ActiveNonContending
}
}
}
pub(in crate::sched::system) const fn is_active(&self) -> bool {
!matches!(self.activity, DeadlineBandwidthActivity::Inactive)
}
pub(in crate::sched::system) const fn is_contending(&self) -> bool {
matches!(self.activity, DeadlineBandwidthActivity::Contending)
}
pub(in crate::sched::system) const fn zero_lag(&self) -> Option<SchedulerTimestamp> {
match self.activity {
DeadlineBandwidthActivity::NonContending { zero_lag } => Some(zero_lag),
DeadlineBandwidthActivity::Inactive | DeadlineBandwidthActivity::Contending => None,
}
}
pub(in crate::sched::system) fn attach(&mut self, owner: CpuId) {
assert!(
self.reservation_owner.replace(owner).is_none(),
"one Deadline reservation cannot belong to two runqueues"
);
}
pub(in crate::sched::system) fn detach(&mut self, owner: CpuId) {
assert_eq!(
self.reservation_owner.take(),
Some(owner),
"Deadline reservation detach must name its owner rq"
);
}
pub(in crate::sched::system) fn activate_contending(&mut self) {
self.activity = DeadlineBandwidthActivity::Contending;
}
pub(in crate::sched::system) fn mark_non_contending(&mut self, zero_lag: SchedulerTimestamp) {
assert!(
self.is_contending(),
"only a contending Deadline reservation can become non-contending"
);
self.activity = DeadlineBandwidthActivity::NonContending { zero_lag };
}
pub(in crate::sched::system) fn deactivate(&mut self) {
self.activity = DeadlineBandwidthActivity::Inactive;
}
pub(in crate::sched::system) fn replace_detached_reservation(
&mut self,
reservation_scaled: u64,
) {
assert!(
self.reservation_owner.is_none(),
"Deadline policy replacement requires detached rq bandwidth"
);
self.reservation_scaled = reservation_scaled;
self.activity = DeadlineBandwidthActivity::Inactive;
}
}
#[derive(Debug)]
pub(in crate::sched::system) struct ThreadDeadlineState {
pub(in crate::sched::system) server: crate::thread::DeadlineServer,
pub(in crate::sched::system) bandwidth: DeadlineBandwidthState,
pub(in crate::sched::system) cbs_timer: Option<TaskDeadlineRegistration>,
pub(in crate::sched::system) zero_lag_timer: Option<TaskDeadlineRegistration>,
pub(in crate::sched::system) overrun_events: u64,
}
impl ThreadDeadlineState {
pub(super) fn new(server: crate::thread::DeadlineServer, reservation: u64) -> Self {
Self {
server,
bandwidth: DeadlineBandwidthState::new(reservation),
cbs_timer: None,
zero_lag_timer: None,
overrun_events: 0,
}
}
}