diff --git a/srp_analysis/Cargo.toml b/srp_analysis/Cargo.toml index 2ffa9443aa21086a1bccfef0958561522ee89b6d..ecc718b979526e3b664f1280dc29db7b21d0052b 100644 --- a/srp_analysis/Cargo.toml +++ b/srp_analysis/Cargo.toml @@ -8,3 +8,5 @@ edition = "2018" [dependencies] structopt = { version = "0.3"} +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" diff --git a/srp_analysis/analysis.json b/srp_analysis/analysis.json new file mode 100644 index 0000000000000000000000000000000000000000..347b242596fc92e21f1c6da33f64d9db961f0e69 --- /dev/null +++ b/srp_analysis/analysis.json @@ -0,0 +1 @@ +[{"id":"T1","prio":1,"deadline":100,"inter_arrival":100,"trace":{"id":"T1","start":0,"end":10,"inner":[]}},{"id":"T2","prio":2,"deadline":200,"inter_arrival":200,"trace":{"id":"T2","start":0,"end":30,"inner":[{"id":"R1","start":10,"end":20,"inner":[{"id":"R2","start":12,"end":16,"inner":[]}]},{"id":"R1","start":22,"end":28,"inner":[]}]}},{"id":"T3","prio":3,"deadline":50,"inter_arrival":50,"trace":{"id":"T3","start":0,"end":30,"inner":[{"id":"R2","start":10,"end":20,"inner":[]}]}}] diff --git a/srp_analysis/src/common.rs b/srp_analysis/src/common.rs index 48cebacf4e28f43d3a4f51dc2b12199bd4dd838c..dd0a0462728c109f2443cc5fcfdc9ae6144905d7 100644 --- a/srp_analysis/src/common.rs +++ b/srp_analysis/src/common.rs @@ -1,8 +1,10 @@ use std::collections::{HashMap, HashSet}; +use serde::{Serialize, Deserialize}; + // common data structures -#[derive(Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone)] pub struct Task { pub id: String, pub prio: u8, @@ -11,7 +13,7 @@ pub struct Task { pub trace: Trace, } -#[derive(Debug, Clone)] +#[derive(Serialize, Deserialize, 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 d303ec278ff3970999f231794c81b565b3ff0bd4..b4a52257014976836917402bd5505679053182ca 100644 --- a/srp_analysis/src/main.rs +++ b/srp_analysis/src/main.rs @@ -7,6 +7,9 @@ use srp_analyser::*; use std::path::PathBuf; use structopt::StructOpt; +use std::fs::File; +use std::io::prelude::*; + #[derive(Debug, StructOpt)] #[structopt(name = "srp_analysis", about = "Preforms srp analysis.")] @@ -31,7 +34,7 @@ fn main() { println!("{:?}", opt); let tasks: Tasks = match opt.input { - Some(_file) => create_tasks(), // TODO: Implement so that the tasks can be read from file. + Some(file) => load_tasks(file), None => create_tasks(), }; @@ -39,7 +42,9 @@ fn main() { let analysis = analyse(&tasks, &ip, &tr, opt.approx); match opt.output { - Some(_file) => (), // TODO: Implement so that the analysis can be saved to file. + Some(file) => { + write_to_file(serde_json::to_string(&analysis).unwrap(), file); + }, // TODO: Implement so that the analysis can be saved to html. None => { println!("tasks {:?}", &tasks); println!("tot_util {}", total_load_factor(&tasks)); @@ -55,6 +60,25 @@ fn main() { } +fn write_to_file(contents: String, file: PathBuf) -> std::io::Result<()> { + let mut file = File::create(file)?; + file.write_all(contents.as_bytes())?; + Ok(()) +} + +fn load_tasks(file: PathBuf) -> Tasks { + let mut serialized = String::new(); + read_from_file(&mut serialized, file); + return serde_json::from_str(&serialized).unwrap(); +} + +fn read_from_file(contents: &mut String, filename: PathBuf) -> std::io::Result<()> { + let mut file = File::open(filename)?; + file.read_to_string(contents)?; + Ok(()) +} + + fn create_tasks() -> Tasks { let t1 = Task { id: "T1".to_string(), diff --git a/srp_analysis/src/srp_analyser.rs b/srp_analysis/src/srp_analyser.rs index 4cb4524b94f1e87aeba526ccfb1590d193f671d8..8047622117c80fa672d08fc114b9bb1eba9ba6fa 100644 --- a/srp_analysis/src/srp_analyser.rs +++ b/srp_analysis/src/srp_analyser.rs @@ -1,4 +1,15 @@ use super::common::*; +use serde::{Serialize, Deserialize}; + + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct AnalysedTask { + pub task: Task, + pub response_time: u32, + pub wcet: u32, + pub block_time: u32, + pub preemtion_time: u32, +} /* @@ -170,14 +181,16 @@ pub fn interference_time(task: &Task, tasks: &Tasks, ip: &IdPrio, tr: &TaskResou * Note: Finally, make a function that iterates over the task set and returns a vector with containing: Vec<Task, R(t), C(t), B(t), I(t)>. Just a simple println! of that vector gives the essential information on the analysis. */ -pub fn analyse(tasks: &Tasks, ip: &IdPrio, tr: &TaskResources, approx: bool) -> Vec<(Task, u32, u32, u32, u32)> { - let mut analysis: Vec<(Task, u32, u32, u32, u32)> = vec!(); +pub fn analyse(tasks: &Tasks, ip: &IdPrio, tr: &TaskResources, approx: bool) -> Vec<AnalysedTask> { + let mut analysis: Vec<AnalysedTask> = vec!(); for t in tasks { - let r_t = response_time(t, tasks, ip, tr, approx); - let c_t = wcet(&t.trace); - let b_t = block_time(t, tasks, ip, tr); - let i_t = interference_time(t, tasks, ip, tr, approx).unwrap(); - analysis.push((t.clone(), r_t, c_t, b_t, i_t)); + analysis.push(AnalysedTask { + task: t.clone(), + response_time: response_time(t, tasks, ip, tr, approx), + wcet: wcet(&t.trace), + block_time: block_time(t, tasks, ip, tr), + preemtion_time: interference_time(t, tasks, ip, tr, approx).unwrap(), + }); } return analysis; }