From f9e3c6a0441fe2f71b5c6a5d2966b40d6b47640d Mon Sep 17 00:00:00 2001 From: Alwin Berger Date: Tue, 29 Oct 2024 14:09:12 +0100 Subject: [PATCH] update state2gantt --- state2gantt/Cargo.lock | 31 +++++++++++++++++---- state2gantt/Cargo.toml | 1 + state2gantt/src/main.rs | 60 ++++++++++++++++++++++++++++++++--------- 3 files changed, 75 insertions(+), 17 deletions(-) diff --git a/state2gantt/Cargo.lock b/state2gantt/Cargo.lock index 4803461..942f225 100644 --- a/state2gantt/Cargo.lock +++ b/state2gantt/Cargo.lock @@ -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", ] diff --git a/state2gantt/Cargo.toml b/state2gantt/Cargo.toml index aa50c44..e992a29 100644 --- a/state2gantt/Cargo.toml +++ b/state2gantt/Cargo.toml @@ -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" diff --git a/state2gantt/src/main.rs b/state2gantt/src/main.rs index 8be131e..9ca3f4d 100644 --- a/state2gantt/src/main.rs +++ b/state2gantt/src/main.rs @@ -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, + /// Output abbs by task + #[arg(short, long, value_name = "FILE")] + per_task: Option, + /// Focussed Task #[arg(short, long, value_name = "TASK")] task: Option, + + /// Translate times to microseconds + #[arg(short, long, default_value = "false")] + micros: bool, } fn main() { // let args : Vec = 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, HashMap, Vec<(u64, u64, String)>) = ron::from_str(&String::from_utf8_lossy(&raw_input)).expect("Can not parse HashMap"); + let mut trace : (Vec, HashMap, Vec, HashMap>) = 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"); + }); } } }