Skip to content
Snippets Groups Projects
Commit ef19c8cd authored by Edvin Åkerfeldt's avatar Edvin Åkerfeldt
Browse files

Implementations done

parent 714e35fe
No related branches found
No related tags found
No related merge requests found
// Auxillerary functions used by the home-exam
use crate::common::*;
use std::collections::{HashMap, HashSet};
pub enum Attribute {
A_TASK(Task),
R(u32), // Response time
C(u32), // WCET (Worse excecution time)
B(u32), // Blocking time
I(u32) // Preumtion time
#[derive(Debug, Clone)]
pub struct TaskTimes {
pub id: String,
pub r: u32, // Response time
pub c: u32, // WCET (Worse excecution time)
pub b: u32, // Blocking time
pub i: u32 // Preumtion time
}
/// Returns the total load factor, L(t) = C(t) / A(t) (Where C(t) is WCET and A(t) is the inter-arrival time of the task).
......@@ -23,7 +22,7 @@ pub enum Attribute {
pub fn total_cpu_load(tasks: &Vec<Task>) -> f32 {
let mut total_l: f32 = 0.0;
for task in tasks {
total_l += (task.trace.end - task.trace.start) as f32 / task.inter_arrival as f32;
total_l += task.get_wcet() as f32 / task.inter_arrival as f32;
}
return total_l;
}
......@@ -54,10 +53,10 @@ pub fn blocking_time(task: &Task, task_set: &Tasks) -> u32 {
// Sort out all that can't block us.
let high_ceiling_r = their_resources.iter().filter(|&r| prio_map.get(r).unwrap_or(&0) >= &task.prio ); // Retrives all resources with a ceiling higher then the task prio
println!("Checking against {:?}",other_task.id);
//println!("Checking against {:?}",other_task.id);
//println!("{:?}",&high_ceiling_r);
for resource in high_ceiling_r {
println!("Conflict {:?}", resource);
//println!("Conflict {:?}", resource);
// Fetch the longest critical section in the task that uses this resource
let c_length = find_longest_critical(&other_task.trace, &resource).expect("Check on your hashmap function, it bronk"); // Lets just unwrap couse this shouldn't happen att this stage TODO: Make a test to check that the pre_analysis function functions correctly
// Is it longer then the current?
......@@ -131,11 +130,11 @@ pub fn find_longest_critical(trace: &Trace, r_id: &String) -> Option<u32> {
/// # Arguments
///
/// * `task` - A predefined task
/// * `task_set` - The complete task set in the analysis
/// * `bp_approx` - Use over approximation of the busy_period ( Bp(t) = D(t) )?
///
pub fn preemption_time(task: &Task, task_set: &Tasks) -> u32 {
let (prio_map, task_map) = pre_analysis(task_set); // No need to clutter the function definition, this function takes no time at all.
// Asuming the worst allowed busy-period
pub fn preemption_time(task: &Task, task_set: &Tasks, bp_approx: bool) -> Result<u32, &'static str> {
if bp_approx {
let busy_period = task.deadline;
let mut preemp_t = 0;
......@@ -143,10 +142,38 @@ pub fn preemption_time(task: &Task, task_set: &Tasks) -> u32 {
// Due to safe over approximation mentioned here: https://gitlab.henriktjader.com/ironedde/klee_tutorial/-/blob/master/HOME_EXAM.md#L120
// we can safely use P(other_task) >= P(task)
for other_task in task_set.iter().filter(|&t| t.prio >= task.prio && t.id != task.id) {
preemp_t += (other_task.trace.end - other_task.trace.start) * (busy_period as f64 / other_task.inter_arrival as f64).ceil() as u32;
preemp_t += other_task.get_wcet() * (busy_period as f64 / other_task.inter_arrival as f64).ceil() as u32;
}
return Ok(preemp_t);
} else {
let wcet = task.get_wcet();
let block_t = blocking_time(&task, &task_set);
// Give us the first estimate
let mut r_estimate = wcet + block_t;
loop {
// Last R(t) estimate -> current Bp(t)
let prev_r_est = r_estimate;
if prev_r_est > task.deadline {
// Our busy period is deviating, break it of
return Err("The busy period deviated....")
}
let mut preemp_t_est = 0;
for other_task in task_set.iter().filter(|&t| t.prio >= task.prio && t.id != task.id) {
preemp_t_est += (prev_r_est as f32 / other_task.inter_arrival as f32).ceil() as u32 * other_task.get_wcet();
}
r_estimate = wcet + block_t + preemp_t_est;
return preemp_t;
if r_estimate - prev_r_est == 0 {
// Is this too agressive?
return Ok(preemp_t_est);
}
}
}
}
/// Returns the total response time of the task, R(t).
......@@ -158,28 +185,34 @@ pub fn preemption_time(task: &Task, task_set: &Tasks) -> u32 {
/// # Arguments
///
/// * `task` - A predefined task
/// * `task_set` - The complete task set in the analysis
/// * `bp_approx` - Use over approximation of the busy_period ( Bp(t) = D(t) )?
///
pub fn response_time(task: &Task, task_set: &Tasks) -> u32 {
let crit_t = task.trace.end - task.trace.start;
pub fn response_time(task: &Task, task_set: &Tasks, bp_approx: bool) -> Result<u32, &'static str> {
let crit_t = task.get_wcet();
let block_t = blocking_time(&task, &task_set);
let preemp_t = preemption_time(&task, &task_set);
let preemp_t = preemption_time(&task, &task_set, bp_approx);
return block_t + crit_t + preemp_t;
return Ok(block_t + crit_t + preemp_t?);
}
/// Returns a vector containing all the times useful for analysis, Vec<Task, R(t), C(t), B(t), I(t)>.
pub fn times_as_vec(task: Task) -> Vec<Attribute> {
let resp_t =1; // response_time(&task);
let block_t = 1; // blocking_time(&task);
let preemp_t = 1; //preemption_time(&task);
return vec![
Attribute::A_TASK(task),
Attribute::R(resp_t),
Attribute::C(1337), // Not implemented
Attribute::B(block_t),
Attribute::I(preemp_t)];
pub fn times_as_vec(task_set: &Tasks, bp_approx: bool) -> Result<Vec<TaskTimes>, &'static str> {
let mut time_vec: Vec<TaskTimes> = vec![];
for task in task_set {
let times: TaskTimes = TaskTimes {
id: task.id.clone(),
r: response_time(&task, &task_set, bp_approx)?,
c: task.get_wcet(),
b: blocking_time(&task, &task_set),
i: preemption_time(&task, &task_set, bp_approx)?
};
time_vec.push(times);
}
return Ok(time_vec);
}
/*
/// Traverses the trace tree and checks that a resource is never re-claimed in the same critical section
/// returns true if there is a reclaiming of a resource.
/// OBS, can't get this to work, assume no re-claims
......@@ -200,7 +233,7 @@ pub fn check_for_reclaim(trace: &Trace, hm: &mut HashMap<String, ()>) -> bool {
}
}
return false;
}
}*/
/*
fn r_dig(trace_base: &Trace, id: &String) -> Vec<&Trace> {
......
......@@ -11,6 +11,12 @@ pub struct Task {
pub trace: Trace,
}
impl Task {
pub fn get_wcet(&self) -> u32 {
return self.trace.end - self.trace.start;
}
}
//#[derive(Debug, Clone)]
#[derive(Debug, Clone)]
pub struct Trace {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment