Skip to content
Snippets Groups Projects
Commit 63f1e012 authored by Ruben Asplund's avatar Ruben Asplund
Browse files

Added command-line interface

parent 3138e1f1
No related branches found
No related tags found
No related merge requests found
...@@ -7,3 +7,6 @@ edition = "2018" ...@@ -7,3 +7,6 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
serde = { version = "1.0", features = ["derive"] }
structopt = { version = "0.3"}
serde_json = "1.0"
...@@ -18,7 +18,7 @@ pub fn analysis(tasks: &Tasks, exact: bool) -> Vec<TaskData>{ ...@@ -18,7 +18,7 @@ pub fn analysis(tasks: &Tasks, exact: bool) -> Vec<TaskData>{
// Checks if the analysis is schedulable // Checks if the analysis is schedulable
// returns false if it is not schedulable // returns false if it is not schedulable
pub fn schedulable_check(analysis: Vec<TaskData>) -> bool{ pub fn schedulable_check(analysis: &Vec<TaskData>) -> bool{
// check if response time is less then deadline // check if response time is less then deadline
for a in analysis { for a in analysis {
if a.task.deadline < a.response_time { if a.task.deadline < a.response_time {
......
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TaskData { pub struct TaskData {
pub task: Task, pub task: Task,
pub response_time: u32, pub response_time: u32,
...@@ -9,7 +10,7 @@ pub struct TaskData { ...@@ -9,7 +10,7 @@ pub struct TaskData {
pub preemption_time: u32 pub preemption_time: u32
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Task { pub struct Task {
pub id: String, pub id: String,
pub prio: u8, pub prio: u8,
...@@ -18,8 +19,7 @@ pub struct Task { ...@@ -18,8 +19,7 @@ pub struct Task {
pub trace: Trace, pub trace: Trace,
} }
//#[derive(Debug, Clone)] #[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone)]
pub struct Trace { pub struct Trace {
pub id: String, pub id: String,
pub start: u32, pub start: u32,
......
...@@ -2,27 +2,136 @@ mod common; ...@@ -2,27 +2,136 @@ mod common;
mod analysis; mod analysis;
use analysis::*; use analysis::*;
use common::*; use common::*;
use structopt::StructOpt;
use std::path::PathBuf;
fn main() { use std::fs::File;
use std::io::prelude::*;
let tasks = taskset_2(); #[derive(Debug, StructOpt)]
#[structopt(name = "srp analysis", about = "Example:
cargo run -- -e
cargo run -- -e -o analysis_1.json
cargo run -- -e -i tasks_1.json
cargo run -- -e -i tasks_2.json -o analysis_2.json")]
struct Opt {
#[structopt(short, long)]
exact: bool,
#[structopt(short, long)]
output_analysis: Option<PathBuf>,
#[structopt(short, long)]
input_tasks: Option<PathBuf>,
}
fn main() -> std::io::Result<()> {
let opt = Opt::from_args();
// println!("{:?}", opt);
/* SAVES DOWN THE TASKS SET 1 and 2 to json
let tasks_1 = &taskset_1();
let tasks_2 = &taskset_2();
let tasks_1_json: String = serde_json::to_string(&tasks_1).unwrap();
let tasks_2_json: String = serde_json::to_string(&tasks_2).unwrap();
write_file_string(tasks_1_json, "tasks_1.json".to_string());
write_file_string(tasks_2_json, "tasks_2.json".to_string());
*/
// Default task set
let mut tasks: Tasks = taskset_1();
// Tasks input, if no input a default task input taskset_1 is used
match opt.input_tasks {
Some(file) => {
let mut file = File::open(file)?;
let mut contents = String::new();
file.read_to_string(&mut contents)?;
tasks = serde_json::from_str(&contents).unwrap();
println!("\nTask set is loaded from {:?}", file);
}
None => println!("\nA default task set is loaded!")
};
// Print out tasks
println!("---------------------------- Tasks ----------------------------\n");
for t in &tasks {
println!("Task {} | Prio {} | Deadline {} | Inter_arrival {} |",
t.id, t.prio, t.deadline, t.inter_arrival);
println!("{:?} \n", t.trace);
}
println!("----------------------------------------------------------------\n");
// let (ip, tr) = pre_analysis(&tasks); // let (ip, tr) = pre_analysis(&tasks);
// println!("{:?}", ip); // println!("{:?}", ip);
// println!("{:?}", tr); // println!("{:?}", tr);
println!("CPU load {}", load_factor(&tasks)); // Calculate and print load factor for the CPU
let analysis = analysis(&tasks, true); let load_f = load_factor(&tasks);
println!("\nCPU load: {}\n", load_f);
// Prints out if exact or apporoximated preemptions calculation
if opt.exact {
println!("Exact preemption calculation: YES\n");
} else {
println!("Exact preemption calculation: NO\n");
}
// Makes the analysis
let analysis = analysis(&tasks, opt.exact);
// Prints out the results of the analysis
println!("---------------------------- Results of the analysis ----------------------------\n");
for a in &analysis { for a in &analysis {
println!("{:?} Response time {} | WCET {} | Blocking time {} | Preemption time {}", println!("Task {:?} | Response time {} | WCET {} | Blocking time {} | Preemption time {} |\n",
a.task.id, a.response_time, a.wcet, a.blocking_time, a.preemption_time); a.task.id, a.response_time, a.wcet, a.blocking_time, a.preemption_time);
} }
if schedulable_check(analysis) { println!("---------------------------------------------------------------------------------\n");
println!("OK! The taskset is schedulable!")
// Checks if the analysis is schedulable and prints out the results
let schedule_check = schedulable_check(&analysis);
if schedule_check && !(load_f > 1.0) {
println!("The taskset is schedulable: YES\n")
} else { } else {
println!("ERROR! The taskset is NOT schedulable!") println!("The taskset is schedulable: NO\n");
println!("Reasons:");
if load_f > 1.0 {
println!("- The CPU is overloaded!\n");
}
if schedule_check {
println!("- Deadline miss!\n")
}
}
// Output analysis saved as json?
let analysis_json: String = serde_json::to_string(&analysis).unwrap();
match opt.output_analysis {
Some(file) => {
match write_file(analysis_json, file) {
Ok(()) => (),
Err(err) => panic!(err),
}
println!("The Analysis is saved: YES\n");
}
None => println!("The Analysis is saved: NO\n"),
};
Ok(())
}
fn write_file_string(contents: String, file_name: String) -> std::io::Result<()> {
let mut file = File::create(file_name)?;
file.write_all(contents.as_bytes())?;
Ok(())
} }
fn write_file(contents: String, file_name: PathBuf) -> std::io::Result<()> {
let mut file = File::create(file_name)?;
file.write_all(contents.as_bytes())?;
Ok(())
} }
fn taskset_1() -> Tasks { fn taskset_1() -> Tasks {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment