add SysMapFeedback

This commit is contained in:
Alwin Berger 2022-03-09 12:30:23 +01:00
parent 8691c77eb2
commit 0693422e44
3 changed files with 144 additions and 1 deletions

View File

@ -23,3 +23,4 @@ nix = "0.23.0"
goblin = "0.4.2"
either = "1.6.1"
num-traits = "0.2"
petgraph = { version="0.6.0", features = ["serde-1"] }

View File

@ -19,6 +19,138 @@ use serde::{Deserialize, Serialize};
use super::MiniFreeRTOSSystemState;
use super::FreeRTOSSystemStateMetadata;
use super::observers::QemuSysStateObserver;
use petgraph::prelude::DiGraph;
use petgraph::graph::NodeIndex;
use petgraph::Direction;
use std::cmp::Ordering;
//============================= Graph Feedback
/// Improved System State Graph
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
pub struct SysMapFeedbackState
{
graph: DiGraph<MiniFreeRTOSSystemState, ()>,
entrypoint: NodeIndex,
name: String,
}
impl SysMapFeedbackState
{
pub fn new() -> Self {
let mut graph = DiGraph::<MiniFreeRTOSSystemState, ()>::new();
let ind = graph.add_node(MiniFreeRTOSSystemState::default());
Self {graph: graph, entrypoint: ind, name: String::from("SysMap")}
}
fn insert(&mut self, list: Vec<MiniFreeRTOSSystemState>) {
let mut current_index = self.entrypoint;
for n in list {
let mut done = false;
for i in self.graph.neighbors_directed(current_index, Direction::Outgoing) {
if n == self.graph[i] {
done = true;
current_index = i;
break;
}
}
if !done {
let j = self.graph.add_node(n);
self.graph.add_edge(current_index, j, ());
current_index = j;
}
}
}
fn update(&mut self, list: &Vec<MiniFreeRTOSSystemState>) -> bool {
let mut current_index = self.entrypoint;
let mut novel = false;
for n in list {
let mut matching : Option<NodeIndex> = None;
for i in self.graph.neighbors_directed(current_index, Direction::Outgoing) {
let tmp = &self.graph[i];
if n == tmp {
matching = Some(i);
current_index = i;
break;
}
}
match matching {
None => {
novel = true;
let j = self.graph.add_node(n.clone());
self.graph.add_edge(current_index, j, ());
current_index = j;
},
Some(i) => {
if n.get_time() > self.graph[i].get_time() {
novel = true;
self.graph[i]=n.clone();
}
}
}
}
return novel;
}
}
impl Named for SysMapFeedbackState
{
#[inline]
fn name(&self) -> &str {
&self.name
}
}
impl FeedbackState for SysMapFeedbackState
{
fn reset(&mut self) -> Result<(), Error> {
self.graph.clear();
self.entrypoint = self.graph.add_node(MiniFreeRTOSSystemState::default());
Ok(())
}
}
/// A Feedback reporting novel System-State Transitions. Depends on [`QemuSysStateObserver`]
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
pub struct SysMapFeedback
{
name: String
}
impl SysMapFeedback {
pub fn new() -> Self {
Self {name: String::from("SysMapFeedback") }
}
}
impl<I, S> Feedback<I, S> for SysMapFeedback
where
I: Input,
S: HasClientPerfMonitor + HasFeedbackStates,
{
fn is_interesting<EM, OT>(
&mut self,
state: &mut S,
_manager: &mut EM,
_input: &I,
observers: &OT,
_exit_kind: &ExitKind,
) -> Result<bool, Error>
where
EM: EventFirer<I>,
OT: ObserversTuple<I, S>,
{
let observer = observers.match_name::<QemuSysStateObserver>("sysstate")
.expect("QemuSysStateObserver not found");
let feedbackstate = state
.feedback_states_mut()
.match_name_mut::<SysMapFeedbackState>("SysMap")
.unwrap();
Ok(feedbackstate.update(&observer.last_run))
}
}
impl Named for SysMapFeedback
{
#[inline]
fn name(&self) -> &str {
&self.name
}
}
//============================= Feedback

View File

@ -30,7 +30,7 @@ pub struct FreeRTOSSystemStateRaw {
static mut CURRENT_SYSSTATE_VEC: Vec<FreeRTOSSystemStateRaw> = vec![];
/// A reduced version of freertos::TCB_t
#[derive(Debug, Default, Serialize, Deserialize, Clone)]
#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
pub struct MiniTCB {
task_name: String,
priority: u32,
@ -89,6 +89,11 @@ pub struct MiniFreeRTOSSystemState {
current_task: MiniTCB,
ready_list_after: Vec<MiniTCB>,
}
impl PartialEq for MiniFreeRTOSSystemState {
fn eq(&self, other: &Self) -> bool {
self.current_task == other.current_task && self.ready_list_after == other.ready_list_after
}
}
impl Hash for MiniFreeRTOSSystemState {
fn hash<H: Hasher>(&self, state: &mut H) {
@ -96,6 +101,11 @@ impl Hash for MiniFreeRTOSSystemState {
// self.ready_list_after.hash(state);
}
}
impl MiniFreeRTOSSystemState {
fn get_time(&self) -> u64 {
self.end_tick-self.start_tick
}
}
// Wrapper around Vec<MiniFreeRTOSSystemState> to attach as Metadata
#[derive(Debug, Default, Serialize, Deserialize, Clone)]