use crate::arrival::ArrivalBound;
use crate::demand::{self, RequestBound};
use crate::time::{Duration, Offset, Service};
use crate::{fixed_point, supply, wcet};
pub struct TaskUnderAnalysis<'a, AB: ArrivalBound + ?Sized> {
pub wcet: wcet::Scalar,
pub arrivals: &'a AB,
pub last_np_segment: Service,
pub blocking_bound: Service,
}
#[allow(non_snake_case)]
pub fn dedicated_uniproc_rta<InterferingRBF, AB>(
tua: &TaskUnderAnalysis<AB>,
interfering_tasks: &[InterferingRBF],
limit: Duration,
) -> fixed_point::SearchResult
where
InterferingRBF: RequestBound,
AB: ArrivalBound + ?Sized,
{
let proc = supply::Dedicated::new();
let tua_rbf = demand::RBF::new(tua.arrivals, tua.wcet);
let L = fixed_point::search(&proc, limit, |L| {
let interference_bound: Service = interfering_tasks
.iter()
.map(|rbf| rbf.service_needed(L))
.sum();
tua.blocking_bound + interference_bound + tua_rbf.service_needed(L)
})?;
let rtct = tua.wcet.wcet - (tua.last_np_segment - Service::epsilon());
let rem_cost = tua.wcet.wcet - rtct;
let rta = |A: Offset| {
let rhs = |AF: Duration| {
let self_interference = tua_rbf.service_needed(A.closed_since_time_zero());
let tua_demand = self_interference - rem_cost;
let interfering_demand = interfering_tasks
.iter()
.map(|rbf| rbf.service_needed(AF))
.sum();
tua.blocking_bound + tua_demand + interfering_demand
};
let AF = fixed_point::search(&proc, limit, rhs)?;
let F = AF - A.since_time_zero();
Ok(F + Duration::from(rem_cost))
};
let max_offset = Offset::from_time_zero(L);
let search_space = demand::step_offsets(&tua_rbf).take_while(|A| *A < max_offset);
fixed_point::max_response_time(search_space.map(rta))
}