diff --git a/srp_analysis/src/analysis.rs b/srp_analysis/src/analysis.rs index 657108484fd4cbde6be8c79b6c796e384a4401a4..43d79aa417d51573d06ef890724973b419a38308 100644 --- a/srp_analysis/src/analysis.rs +++ b/srp_analysis/src/analysis.rs @@ -1,16 +1,40 @@ use crate::common::*; use std::collections::HashSet; +#[derive(Debug, Clone)] +pub struct TaskData { + pub task: Task, + pub response_time: u32, + pub wcet: u32, + pub blocking_time: u32, + pub preemption_time: u32 +} + // Prints out vector with [task id, response time, wcet time, blocking time, preemption time] -pub fn print_analysis(tasks: &Tasks) { +pub fn analysis(tasks: &Tasks, exact: bool) -> Vec<TaskData>{ + let mut analysis: Vec<TaskData> = vec!(); for t in tasks { - let b = blocking(t, &tasks); - let p = preemptions(t, &tasks, true).unwrap(); - let r = response_time(t, &tasks, true); - let c = wcet(t); - let tasks_analysis = vec![t.id.to_string(), r.to_string(), c.to_string(), b.to_string(), p.to_string()]; - println!("{:?}", tasks_analysis) + analysis.push(TaskData { + task: t.clone(), + response_time: response_time(t, &tasks, exact), + wcet: wcet(t), + blocking_time: blocking(t, &tasks), + preemption_time: preemptions(t, &tasks, exact).unwrap() + }) + } + return analysis; +} + +// Checks if the analysis is schedulable +// returns false if it is not schedulable +pub fn schedulable_check(analysis: Vec<TaskData>) -> bool{ + // check if response time is less then deadline + for a in analysis { + if a.task.deadline < a.response_time { + return false + } } + return true; } pub fn response_time(task: &Task, tasks: &Tasks, exact_solution: bool) -> u32 { @@ -35,9 +59,9 @@ pub fn load_factor(tasks: &Tasks) -> f32{ return l_tot; } -pub fn preemptions_approx(task: &Task, tasks: &Tasks) -> u32 { +pub fn preemption_approx(task: &Task, tasks: &Tasks) -> u32 { let mut p_time = 0; - let mut busy_period = task.deadline; + let busy_period = task.deadline; for t in tasks { if (t.prio >= task.prio) && (t.id != task.id) { p_time = p_time + wcet(t)*(((busy_period as f32) / (t.inter_arrival as f32)).ceil() as u32); @@ -47,7 +71,7 @@ pub fn preemptions_approx(task: &Task, tasks: &Tasks) -> u32 { } -pub fn preemptions_exact(task: &Task, tasks: &Tasks, busy_period: u32) -> Result<u32, String> { +pub fn preemption_exact(task: &Task, tasks: &Tasks, busy_period: u32) -> Result<u32, String> { let base_case = wcet(task) + blocking(task, &tasks); let mut new_busy_period = base_case; let mut busy_period = busy_period; @@ -67,20 +91,20 @@ pub fn preemptions_exact(task: &Task, tasks: &Tasks, busy_period: u32) -> Result } else if new_busy_period == busy_period { return Ok(new_busy_period - base_case); } else { - return preemptions_exact(task, &tasks, new_busy_period); + return preemption_exact(task, &tasks, new_busy_period); } } pub fn preemptions(task: &Task, tasks: &Tasks, exact: bool) -> Result<u32, String> { if exact { - return preemptions_exact(task, &tasks, 0); + return preemption_exact(task, &tasks, 0); } else { - return Ok(preemptions_approx(task, &tasks)); + return Ok(preemption_approx(task, &tasks)); } } pub fn blocking(task: &Task, tasks: &Tasks) -> u32 { - let (ip, tr) = pre_analysis(&tasks); + let (_ip, tr) = pre_analysis(&tasks); // Checks if the Task is claming a resource if !tr.contains_key(&task.id) { return 0; @@ -96,17 +120,16 @@ pub fn blocking(task: &Task, tasks: &Tasks) -> u32 { return 0; } let resources = &tr[&task.id]; - println!("{}", &task.id); - println!("{:?}", tr); - println!("{:?}", resources); + // println!("{}", &task.id); + // println!("{:?}", tr); + // println!("{:?}", resources); // Checking every resource it holds let mut max_block = 0; - let mut current_block = 0; // Iterate through current task resources for r1 in resources { // Iterate through lower prio tasks for t_id in &lower_prio_tasks { - let mut lower_prio_task_resources = &tr[t_id]; + let lower_prio_task_resources = &tr[t_id]; // Iterate through lower prio task resources for r2 in lower_prio_task_resources { // When current task use the same resource as a task diff --git a/srp_analysis/src/common.rs b/srp_analysis/src/common.rs index d6f92b1c405f22fe9cccaba059151492354431e8..c98b28ce2cac83e0760a511d92bb18b4c5f472ad 100644 --- a/srp_analysis/src/common.rs +++ b/srp_analysis/src/common.rs @@ -2,7 +2,7 @@ use std::collections::{HashMap, HashSet}; // common data structures -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct Task { pub id: String, pub prio: u8, @@ -12,7 +12,7 @@ pub struct Task { } //#[derive(Debug, Clone)] -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct Trace { pub id: String, pub start: u32, diff --git a/srp_analysis/src/main.rs b/srp_analysis/src/main.rs index 5fcc58be88d8dfb83b6a84ca373f4aa4f7d243e3..cf4fafa27664a0e2ee96470fc57421078a1f79f0 100644 --- a/srp_analysis/src/main.rs +++ b/srp_analysis/src/main.rs @@ -4,6 +4,26 @@ use analysis::*; use common::*; fn main() { + + let tasks = taskset_1(); + + println!("CPU load {}", load_factor(&tasks)); + let analysis = analysis(&tasks, true); + for a in &analysis { + println!("{:?} Response time {} | WCET {} | Blocking time {} | Preemption time {}", + a.task.id, a.response_time, a.wcet, a.blocking_time, a.preemption_time); + } + if schedulable_check(analysis) { + println!("The taskset is schedulable!") + } else { + println!("The taskset is NOT schedulable!") + } + + + +} + +fn taskset_1() -> Tasks { let t1 = Task { id: "T1".to_string(), prio: 1, @@ -65,17 +85,77 @@ fn main() { }], }, }; - - // builds a vector of tasks t1, t2, t3 let tasks: Tasks = vec![t1, t2, t3]; + return tasks; +} - - - let (ip, tr) = pre_analysis(&tasks); - println!("ip: {:?}", ip); - println!("tr: {:?}", tr); - - println!("tot_util {}", load_factor(&tasks)); - print_analysis(&tasks); - +fn taskset_2() -> Tasks { + let t1 = Task { + id: "T1".to_string(), + prio: 1, + deadline: 200, + inter_arrival: 200, + trace: Trace { + id: "T1".to_string(), + start: 0, + end: 15, + inner: vec![Trace { + id: "R1".to_string(), + start: 2, + end: 8, + inner: vec![], + }], + }, + }; + + let t2 = Task { + id: "T2".to_string(), + prio: 2, + deadline: 200, + inter_arrival: 200, + trace: Trace { + id: "T2".to_string(), + start: 0, + end: 37, + inner: vec![ + Trace { + id: "R1".to_string(), + start: 10, + end: 18, + inner: vec![Trace { + id: "R2".to_string(), + start: 12, + end: 16, + inner: vec![], + }], + }, + Trace { + id: "R1".to_string(), + start: 22, + end: 25, + inner: vec![], + }, + ], + }, + }; + + let t3 = Task { + id: "T3".to_string(), + prio: 3, + deadline: 100, + inter_arrival: 100, + trace: Trace { + id: "T3".to_string(), + start: 0, + end: 20, + inner: vec![Trace { + id: "R2".to_string(), + start: 8, + end: 20, + inner: vec![], + }], + }, + }; + let tasks: Tasks = vec![t1, t2, t3]; + return tasks; } \ No newline at end of file