rework release detection with nested interrupts
This commit is contained in:
parent
fb3837f725
commit
5ffac514ca
@ -5,7 +5,7 @@ authors = ["Alwin Berger <alwin.berger@tu-dortmund.de>"]
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["std", "snapshot_restore", "snapshot_fast", "singlecore", "restarting", "do_hash_notify_state", "config_stg", "fuzz_int", "trace_job_response_times", "shortcut" ]
|
default = ["std", "snapshot_fast", "restarting", "do_hash_notify_state", "config_stg", "fuzz_int", "trace_job_response_times", "shortcut" ]
|
||||||
std = []
|
std = []
|
||||||
# Exec environemnt basics
|
# Exec environemnt basics
|
||||||
snapshot_restore = []
|
snapshot_restore = []
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
mod fuzzer;
|
mod fuzzer;
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
mod time;
|
pub mod time;
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
pub mod systemstate;
|
pub mod systemstate;
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
|
@ -171,6 +171,14 @@ impl ReducedFreeRTOSSystemState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for ReducedFreeRTOSSystemState {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
let ready = self.ready_list_after.iter().map(|x| x.task_name.clone()).collect::<Vec<_>>().join(" ");
|
||||||
|
let delay = self.delay_list_after.iter().map(|x| x.task_name.clone()).collect::<Vec<_>>().join(" ");
|
||||||
|
write!(f, "Valid: {} | Current: {} | Ready: {} | Delay: {}", u32::from(!self.read_invalid), self.current_task.task_name, ready, delay)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// #[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq, Eq, Hash)]
|
// #[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq, Eq, Hash)]
|
||||||
// pub enum ExecLevel {
|
// pub enum ExecLevel {
|
||||||
// APP = 0,
|
// APP = 0,
|
||||||
|
@ -235,7 +235,7 @@ fn get_releases(trace: &Vec<ExecInterval>, states: &HashMap<u64, ReducedFreeRTOS
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if i.start_capture.0 == CaptureEvent::ISRStart && ( i.start_capture.1 == "xPortSysTickHandler" || USR_ISR_SYMBOLS.contains(&i.start_capture.1.as_str()) ) {
|
if i.start_capture.0 == CaptureEvent::ISRStart && ( i.start_capture.1 == "xPortSysTickHandler" || USR_ISR_SYMBOLS.contains(&i.start_capture.1.as_str()) ) {
|
||||||
// detect race-conditions, get start adn end state from the nearest valid intervals
|
// detect race-conditions, get start and end state from the nearest valid intervals
|
||||||
if states.get(&i.start_state).map(|x| x.read_invalid).unwrap_or(true) {
|
if states.get(&i.start_state).map(|x| x.read_invalid).unwrap_or(true) {
|
||||||
let mut start_index=None;
|
let mut start_index=None;
|
||||||
for n in 1.._n {
|
for n in 1.._n {
|
||||||
@ -267,6 +267,7 @@ fn get_releases(trace: &Vec<ExecInterval>, states: &HashMap<u64, ReducedFreeRTOS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
|
// canonical case, userspace -> isr -> userspace
|
||||||
if i.end_capture.0 == CaptureEvent::ISREnd {
|
if i.end_capture.0 == CaptureEvent::ISREnd {
|
||||||
let start_state = states.get(&i.start_state).expect("State not found");
|
let start_state = states.get(&i.start_state).expect("State not found");
|
||||||
let end_state = states.get(&i.end_state).expect("State not found");
|
let end_state = states.get(&i.end_state).expect("State not found");
|
||||||
@ -281,18 +282,37 @@ fn get_releases(trace: &Vec<ExecInterval>, states: &HashMap<u64, ReducedFreeRTOS
|
|||||||
// }
|
// }
|
||||||
// });
|
// });
|
||||||
} else if i.end_capture.0 == CaptureEvent::ISRStart {
|
} else if i.end_capture.0 == CaptureEvent::ISRStart {
|
||||||
// Nested interrupts. Jump over one interval
|
// Nested interrupts. Fast-forward to the end of the original interrupt, or the first valid state thereafter
|
||||||
if let Some(interval_end) = trace.get(_n+2) {
|
// TODO: this may cause the same release to be registered multiple times
|
||||||
if interval_end.start_capture.0 == CaptureEvent::ISREnd && interval_end.end_capture.0 == CaptureEvent::ISREnd && interval_end.end_capture.1 == i.start_capture.1 {
|
let mut isr_has_ended = false;
|
||||||
let start_state = states.get(&i.start_state).expect("State not found");
|
let start_state = states.get(&i.start_state).expect("State not found");
|
||||||
let end_state = states.get(&interval_end.end_state).expect("State not found");
|
for n in (_n+1)..trace.len() {
|
||||||
end_state.ready_list_after.iter().for_each(|x| {
|
if let Some(interval_end) = trace.get(n) {
|
||||||
if x.task_name != end_state.current_task.task_name && x.task_name != start_state.current_task.task_name && !start_state.ready_list_after.iter().any(|y| x.task_name == y.task_name) {
|
if interval_end.end_capture.1 == i.start_capture.1 || isr_has_ended {
|
||||||
ret.push((i.end_tick, x.task_name.clone()));
|
let end_state = states.get(&interval_end.end_state).unwrap();
|
||||||
|
isr_has_ended = true;
|
||||||
|
if !end_state.read_invalid {
|
||||||
|
end_state.ready_list_after.iter().for_each(|x| {
|
||||||
|
if x.task_name != end_state.current_task.task_name && x.task_name != start_state.current_task.task_name && !start_state.ready_list_after.iter().any(|y| x.task_name == y.task_name) {
|
||||||
|
ret.push((i.end_tick, x.task_name.clone()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
} else {break;}
|
||||||
}
|
};
|
||||||
|
// if let Some(interval_end) = trace.get(_n+2) {
|
||||||
|
// if interval_end.start_capture.0 == CaptureEvent::ISREnd && interval_end.end_capture.0 == CaptureEvent::ISREnd && interval_end.end_capture.1 == i.start_capture.1 {
|
||||||
|
// let start_state = states.get(&i.start_state).expect("State not found");
|
||||||
|
// let end_state = states.get(&interval_end.end_state).expect("State not found");
|
||||||
|
// end_state.ready_list_after.iter().for_each(|x| {
|
||||||
|
// if x.task_name != end_state.current_task.task_name && x.task_name != start_state.current_task.task_name && !start_state.ready_list_after.iter().any(|y| x.task_name == y.task_name) {
|
||||||
|
// ret.push((i.end_tick, x.task_name.clone()));
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user