update state2gantt

This commit is contained in:
Alwin Berger 2024-10-29 14:09:12 +01:00
parent 160f3873cc
commit f9e3c6a044
3 changed files with 75 additions and 17 deletions

31
state2gantt/Cargo.lock generated
View File

@ -159,7 +159,7 @@ dependencies = [
"bitflags 2.4.0",
"cexpr",
"clang-sys",
"itertools",
"itertools 0.12.1",
"lazy_static",
"lazycell",
"log",
@ -572,6 +572,7 @@ dependencies = [
"clap",
"csv",
"hashbrown 0.14.0",
"itertools 0.13.0",
"libafl",
"libafl_bolts",
"libafl_qemu",
@ -581,6 +582,7 @@ dependencies = [
"ron",
"serde",
"serde_json",
"simple_moving_average",
]
[[package]]
@ -711,6 +713,15 @@ dependencies = [
"either",
]
[[package]]
name = "itertools"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "1.0.5"
@ -1079,9 +1090,9 @@ dependencies = [
[[package]]
name = "num-traits"
version = "0.2.15"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
@ -1284,7 +1295,7 @@ dependencies = [
"cassowary",
"compact_str",
"crossterm",
"itertools",
"itertools 0.12.1",
"lru",
"paste",
"stability",
@ -1554,6 +1565,15 @@ dependencies = [
"libc",
]
[[package]]
name = "simple_moving_average"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a4b144ad185430cd033299e2c93e465d5a7e65fbb858593dc57181fa13cd310"
dependencies = [
"num-traits",
]
[[package]]
name = "smallvec"
version = "1.10.0"
@ -1582,6 +1602,7 @@ version = "0.1.0"
dependencies = [
"clap",
"fret",
"itertools 0.13.0",
"rand",
"ron",
"serde",
@ -1799,7 +1820,7 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5fbabedabe362c618c714dbefda9927b5afc8e2a8102f47f081089a9019226"
dependencies = [
"itertools",
"itertools 0.12.1",
"unicode-width",
]

View File

@ -13,3 +13,4 @@ serde = { version = "1.0", default-features = false, features = ["alloc"] } # se
ron = "0.7" # write serialized data - including hashmaps
rand = "0.5"
clap = "4.5.17"
itertools = "0.13.0"

View File

@ -1,9 +1,10 @@
use std::collections::HashMap;
use std::path::PathBuf;
use std::{env,fs};
use fret::systemstate::{ExecInterval, ReducedFreeRTOSSystemState};
use fret::systemstate::{ExecInterval, JobInstance, ReducedFreeRTOSSystemState};
use std::io::Write;
use clap::Parser;
use itertools::Itertools;
#[derive(Parser)]
struct Config {
@ -19,21 +20,31 @@ struct Config {
#[arg(short, long, value_name = "FILE")]
response: Option<PathBuf>,
/// Output abbs by task
#[arg(short, long, value_name = "FILE")]
per_task: Option<PathBuf>,
/// Focussed Task
#[arg(short, long, value_name = "TASK")]
task: Option<String>,
/// Translate times to microseconds
#[arg(short, long, default_value = "false")]
micros: bool,
}
fn main() {
// let args : Vec<String> = env::args().collect();
let conf = Config::parse();
let mut conf = Config::parse();
let input_path = conf.input_trace;
let raw_input = fs::read(input_path).expect("Can not read dumped traces");
let activation_path = conf.activation;
let instance_path = conf.response;
let abb_path = conf.per_task;
/* Write all execution intervals */
let mut activation_file = activation_path.map(|x| std::fs::OpenOptions::new()
.read(false)
.write(true)
@ -44,19 +55,19 @@ fn main() {
let mut level_per_task : HashMap<&String, u32> = HashMap::new();
let mut trace : (Vec<ExecInterval>, HashMap<u64, ReducedFreeRTOSSystemState>, Vec<(u64, u64, String)>) = ron::from_str(&String::from_utf8_lossy(&raw_input)).expect("Can not parse HashMap");
let mut trace : (Vec<ExecInterval>, HashMap<u64, ReducedFreeRTOSSystemState>, Vec<JobInstance>, HashMap<String, HashMap<u32, (usize, usize, u64)>>) = ron::from_str(&String::from_utf8_lossy(&raw_input)).expect("Can not parse HashMap");
for s in &trace.0 {
if s.level == 0 {
level_per_task.insert(&trace.1[&s.start_state].current_task.task_name,trace.1[&s.start_state].current_task.priority);
}
}
let limits = conf.task.as_ref().map(|task| trace.2.iter().filter_map(move |x| if &x.2 == task {Some(x)} else {None}).max_by_key(|x| x.1-x.0)).flatten().map(|x| x.0..x.1);
let limits = conf.task.as_ref().map(|task| trace.2.iter().filter_map(move |x| if &x.name == task {Some(x)} else {None}).max_by_key(|x| x.response-x.release)).flatten().map(|x| x.release..x.response);
if let Some(limits) = &limits {
println!("Limits: {} - {}",limits.start,limits.end);
}
activation_file.as_mut().map(|x| writeln!(x,"start,end,prio,name").expect("Could not write to file"));
activation_file.as_mut().map(|x| writeln!(x,"start,end,prio,name,state_id,state").expect("Could not write to file"));
for s in trace.0.iter_mut() {
if let Some(l) = &limits {
if s.start_tick > l.end || s.end_tick < l.start {
@ -65,13 +76,17 @@ fn main() {
s.start_tick = s.start_tick.max(l.start);
s.end_tick = s.end_tick.min(l.end);
}
let start_tick = if conf.micros {s.start_tick / fret::time::clock::QEMU_ISNS_PER_USEC as u64} else {s.start_tick};
let end_tick = if conf.micros {s.end_tick / fret::time::clock::QEMU_ISNS_PER_USEC as u64} else {s.end_tick};
let state = &trace.1[&s.start_state];
if s.level == 0 {
activation_file.as_mut().map(|x| writeln!(x,"{},{},{},{}",s.start_tick,s.end_tick,trace.1[&s.start_state].current_task.priority,trace.1[&s.start_state].current_task.task_name).expect("Could not write to file"));
activation_file.as_mut().map(|x| writeln!(x,"{},{},{},{},{:X},{}",start_tick,end_tick,trace.1[&s.start_state].current_task.priority,trace.1[&s.start_state].current_task.task_name, state.get_hash()>>48, state).expect("Could not write to file"));
} else {
activation_file.as_mut().map(|x| writeln!(x,"{},{},-{},{}",s.start_tick,s.end_tick,s.level,s.start_capture.1).expect("Could not write to file"));
activation_file.as_mut().map(|x| writeln!(x,"{},{},-{},{},{:X},{}",start_tick,end_tick,s.level,s.start_capture.1, state.get_hash()>>48, state).expect("Could not write to file"));
}
}
/* Write all job instances from release to response */
let instance_file = instance_path.map(|x| std::fs::OpenOptions::new()
.read(false)
.write(true)
@ -82,17 +97,38 @@ fn main() {
if let Some(mut file) = instance_file {
writeln!(file,"start,end,prio,name").expect("Could not write to file");
for s in trace.2.iter_mut() {
if limits.as_ref().map(|x| !x.contains(&s.0) && !x.contains(&s.1) ).unwrap_or(false) {
if limits.as_ref().map(|x| !x.contains(&s.release) && !x.contains(&s.response) ).unwrap_or(false) {
continue;
}
if let Some(l) = &limits {
if s.0 > l.end || s.1 < l.start {
if s.release > l.end || s.response < l.start {
continue;
}
s.0 = s.0.max(l.start);
s.1 = s.1.min(l.end);
s.release = s.release.max(l.start);
s.response = s.response.min(l.end);
}
writeln!(file,"{},{},{},{}",s.0,s.1,level_per_task[&s.2],s.2).expect("Could not write to file");
writeln!(file,"{},{},{},{}",s.release,s.response,level_per_task[&s.name],s.name).expect("Could not write to file");
}
}
/* Write all abbs per task */
let abb_file = abb_path.map(|x| std::fs::OpenOptions::new()
.read(false)
.write(true)
.create(true)
.append(false)
.open(x).expect("Could not create file"));
if let Some(mut file) = abb_file {
conf.micros = true;
if trace.3.is_empty() {
return;
}
writeln!(file,"name,addr,active,finish,micros").expect("Could not write to file");
for (name, rest) in trace.3.iter_mut().sorted_by_key(|x| x.0) {
rest.iter().sorted_by_key(|x| x.0).for_each(|(addr, (active, finish, time))| {
writeln!(file,"{},{},{},{},{:.1}",name,addr,active,finish,if conf.micros {*time as f64 / fret::time::clock::QEMU_ISNS_PER_USEC as f64} else {*time as f64}).expect("Could not write to file");
});
}
}
}