From 2227ce09a4dd638b01cbac28d821ed47f034972b Mon Sep 17 00:00:00 2001 From: rubenasplund <ruben.asplund@hotmail.com> Date: Tue, 12 Jan 2021 19:24:31 +0100 Subject: [PATCH] Moved functions from main to analysis.rs --- srp_analysis/src/analysis.rs | 143 +++++++++++++++++++++++++++++++++ srp_analysis/src/main.rs | 148 ++--------------------------------- 2 files changed, 148 insertions(+), 143 deletions(-) create mode 100644 srp_analysis/src/analysis.rs diff --git a/srp_analysis/src/analysis.rs b/srp_analysis/src/analysis.rs new file mode 100644 index 0000000..6571084 --- /dev/null +++ b/srp_analysis/src/analysis.rs @@ -0,0 +1,143 @@ +use crate::common::*; +use std::collections::HashSet; + +// Prints out vector with [task id, response time, wcet time, blocking time, preemption time] +pub fn print_analysis(tasks: &Tasks) { + 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) + } +} + +pub fn response_time(task: &Task, tasks: &Tasks, exact_solution: bool) -> u32 { + let b = blocking(task, &tasks); + let c = wcet(task); + let p = preemptions(task, &tasks, exact_solution).unwrap(); + return b + c + p; +} + +pub fn wcet(task: &Task) -> u32 { + let c = task.trace.end.wrapping_sub(task.trace.start); + return c +} + +pub fn load_factor(tasks: &Tasks) -> f32{ + let mut l_tot: f32 = 0.0; + for t in tasks { + let c = wcet(t); + let a = t.inter_arrival; + l_tot = l_tot + (c as f32)/(a as f32); + } + return l_tot; +} + +pub fn preemptions_approx(task: &Task, tasks: &Tasks) -> u32 { + let mut p_time = 0; + let mut 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); + } + } + return p_time; + +} + +pub fn preemptions_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; + if busy_period == 0 { + busy_period = base_case; + } + for t in tasks { + if t.prio >= task.prio && (t.id != task.id) { + new_busy_period = new_busy_period + wcet(t)*(((busy_period as f32) / (t.inter_arrival as f32)).ceil() as u32); + } + } + // println!("nb {}, b {}", new_busy_period, busy_period); + if new_busy_period.wrapping_sub(base_case) == 0 { + return Ok(0); + } else if new_busy_period > task.deadline { + return Err("Deadline miss!".to_string()); + } else if new_busy_period == busy_period { + return Ok(new_busy_period - base_case); + } else { + return preemptions_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); + } else { + return Ok(preemptions_approx(task, &tasks)); + } +} + +pub fn blocking(task: &Task, tasks: &Tasks) -> u32 { + let (ip, tr) = pre_analysis(&tasks); + // Checks if the Task is claming a resource + if !tr.contains_key(&task.id) { + return 0; + } + // Find lower prio tasks that holds a resource + let mut lower_prio_tasks = HashSet::new(); + for t in tasks { + if t.prio < task.prio && tr.contains_key(&t.id) { + lower_prio_tasks.insert(t.id.to_string()); + } + } + if lower_prio_tasks.len() == 0 { + return 0; + } + let resources = &tr[&task.id]; + 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]; + // Iterate through lower prio task resources + for r2 in lower_prio_task_resources { + // When current task use the same resource as a task + if r1 == r2 { + // Takes forward the blocking task + for t in tasks { + if &t.id == t_id { + // Finds the longest blocking time + max_block = longest_blocking(&t.trace, r1); + + } + } + } + } + } + } + return max_block; +} + +fn longest_blocking(trace: &Trace, r: &str) -> u32 { + let mut max_block = 0; + if trace.id == r { + max_block = trace.end.wrapping_sub(trace.start); + } + if trace.inner.len() != 0 { + for inner in &trace.inner { + let block = longest_blocking(&inner, r); + if max_block < block { + max_block = block; + } + } + } + return max_block; +} \ No newline at end of file diff --git a/srp_analysis/src/main.rs b/srp_analysis/src/main.rs index 9677550..5fcc58b 100644 --- a/srp_analysis/src/main.rs +++ b/srp_analysis/src/main.rs @@ -1,6 +1,7 @@ mod common; +mod analysis; +use analysis::*; use common::*; -use std::collections::HashSet; fn main() { let t1 = Task { @@ -68,152 +69,13 @@ fn main() { // builds a vector of tasks t1, t2, t3 let tasks: Tasks = vec![t1, t2, t3]; - // println!("tasks {:?}", &tasks); - println!("tot_util {}", load_factor(&tasks)); + let (ip, tr) = pre_analysis(&tasks); println!("ip: {:?}", ip); println!("tr: {:?}", tr); - print_analysis(&tasks, &ip, &tr); - -} -// Prints out vector with [task id, response time, wcet time, blocking time, preemption time] -fn print_analysis(tasks: &Tasks, ip: &IdPrio, tr: &TaskResources) { - for t in tasks { - let b = blocking(t, &tasks, &ip, &tr); - // let p = preemptions(t, &tasks); - let p = preemptions(t, &tasks, &ip, &tr, true).unwrap(); - let r = response_time(t, &tasks, &ip, &tr, 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) - } -} - -fn response_time(task: &Task, tasks: &Tasks, ip: &IdPrio, tr: &TaskResources, exact_solution: bool) -> u32 { - let b = blocking(task, &tasks, &ip, &tr); - let c = wcet(task); - let p = preemptions(task, &tasks, &ip, &tr, exact_solution).unwrap(); - return b + c + p; -} - -fn wcet(task: &Task) -> u32 { - let c = task.trace.end.wrapping_sub(task.trace.start); - return c -} - -fn load_factor(tasks: &Tasks) -> f32{ - let mut l_tot: f32 = 0.0; - for t in tasks { - let c = wcet(t); - let a = t.inter_arrival; - l_tot = l_tot + (c as f32)/(a as f32); - } - return l_tot; -} - -fn preemptions_approx(task: &Task, tasks: &Tasks, ip: &IdPrio, tr: &TaskResources) -> u32 { - let mut p_time = 0; - let mut 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); - } - } - return p_time; - -} - -fn preemptions_exact(task: &Task, tasks: &Tasks, ip: &IdPrio, tr: &TaskResources, busy_period: u32) -> Result<u32, String> { - let base_case = wcet(task) + blocking(task, &tasks, &ip, &tr); - let mut new_busy_period = base_case; - let mut busy_period = busy_period; - if busy_period == 0 { - busy_period = base_case; - } - for t in tasks { - if t.prio >= task.prio && (t.id != task.id) { - new_busy_period = new_busy_period + wcet(t)*(((busy_period as f32) / (t.inter_arrival as f32)).ceil() as u32); - } - } - // println!("nb {}, b {}", new_busy_period, busy_period); - if new_busy_period.wrapping_sub(base_case) == 0 { - return Ok(0); - } else if new_busy_period > task.deadline { - return Err("Deadline miss!".to_string()); - } else if new_busy_period == busy_period { - return Ok(new_busy_period - base_case); - } else { - return preemptions_exact(task, &tasks, ip, tr, new_busy_period); - } -} - -fn preemptions(task: &Task, tasks: &Tasks, ip: &IdPrio, tr: &TaskResources, exact: bool) -> Result<u32, String> { - if exact { - return preemptions_exact(task, &tasks, ip, tr, 0); - } else { - return Ok(preemptions_approx(task, &tasks, ip, tr)); - } -} - -fn blocking(task: &Task, tasks: &Tasks, ip: &IdPrio, tr: &TaskResources) -> u32 { - // Checks if the Task is claming a resource - if !tr.contains_key(&task.id) { - return 0; - } - // Find lower prio tasks that holds a resource - let mut lower_prio_tasks = HashSet::new(); - for t in tasks { - if t.prio < task.prio && tr.contains_key(&t.id) { - lower_prio_tasks.insert(t.id.to_string()); - } - } - if lower_prio_tasks.len() == 0 { - return 0; - } - let resources = &tr[&task.id]; - 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]; - // Iterate through lower prio task resources - for r2 in lower_prio_task_resources { - // When current task use the same resource as a task - if r1 == r2 { - // Takes forward the blocking task - for t in tasks { - if &t.id == t_id { - max_block = longest_blocking(&t.trace, r1); - - } - } - } - } - } - } - return max_block; -} + println!("tot_util {}", load_factor(&tasks)); + print_analysis(&tasks); -fn longest_blocking(trace: &Trace, r: &str) -> u32 { - let mut max_block = 0; - if trace.id == r { - max_block = trace.end.wrapping_sub(trace.start); - } - if trace.inner.len() != 0 { - for inner in &trace.inner { - let block = longest_blocking(&inner, r); - if max_block < block { - max_block = block; - } - } - } - return max_block; } \ No newline at end of file -- GitLab