add SysMapFeedback
This commit is contained in:
parent
8691c77eb2
commit
0693422e44
@ -23,3 +23,4 @@ nix = "0.23.0"
|
|||||||
goblin = "0.4.2"
|
goblin = "0.4.2"
|
||||||
either = "1.6.1"
|
either = "1.6.1"
|
||||||
num-traits = "0.2"
|
num-traits = "0.2"
|
||||||
|
petgraph = { version="0.6.0", features = ["serde-1"] }
|
@ -19,6 +19,138 @@ use serde::{Deserialize, Serialize};
|
|||||||
use super::MiniFreeRTOSSystemState;
|
use super::MiniFreeRTOSSystemState;
|
||||||
use super::FreeRTOSSystemStateMetadata;
|
use super::FreeRTOSSystemStateMetadata;
|
||||||
use super::observers::QemuSysStateObserver;
|
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
|
//============================= Feedback
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ pub struct FreeRTOSSystemStateRaw {
|
|||||||
static mut CURRENT_SYSSTATE_VEC: Vec<FreeRTOSSystemStateRaw> = vec![];
|
static mut CURRENT_SYSSTATE_VEC: Vec<FreeRTOSSystemStateRaw> = vec![];
|
||||||
|
|
||||||
/// A reduced version of freertos::TCB_t
|
/// A reduced version of freertos::TCB_t
|
||||||
#[derive(Debug, Default, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq)]
|
||||||
pub struct MiniTCB {
|
pub struct MiniTCB {
|
||||||
task_name: String,
|
task_name: String,
|
||||||
priority: u32,
|
priority: u32,
|
||||||
@ -89,6 +89,11 @@ pub struct MiniFreeRTOSSystemState {
|
|||||||
current_task: MiniTCB,
|
current_task: MiniTCB,
|
||||||
ready_list_after: Vec<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 {
|
impl Hash for MiniFreeRTOSSystemState {
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
@ -96,6 +101,11 @@ impl Hash for MiniFreeRTOSSystemState {
|
|||||||
// self.ready_list_after.hash(state);
|
// 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
|
// Wrapper around Vec<MiniFreeRTOSSystemState> to attach as Metadata
|
||||||
#[derive(Debug, Default, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Default, Serialize, Deserialize, Clone)]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user