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"
|
||||
|
||||
[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 = []
|
||||
# Exec environemnt basics
|
||||
snapshot_restore = []
|
||||
|
@ -1,7 +1,7 @@
|
||||
#[cfg(target_os = "linux")]
|
||||
mod fuzzer;
|
||||
#[cfg(target_os = "linux")]
|
||||
mod time;
|
||||
pub mod time;
|
||||
#[cfg(target_os = "linux")]
|
||||
pub mod systemstate;
|
||||
#[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)]
|
||||
// pub enum ExecLevel {
|
||||
// APP = 0,
|
||||
|
@ -235,7 +235,7 @@ fn get_releases(trace: &Vec<ExecInterval>, states: &HashMap<u64, ReducedFreeRTOS
|
||||
continue;
|
||||
}
|
||||
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) {
|
||||
let mut start_index=None;
|
||||
for n in 1.._n {
|
||||
@ -267,6 +267,7 @@ fn get_releases(trace: &Vec<ExecInterval>, states: &HashMap<u64, ReducedFreeRTOS
|
||||
}
|
||||
}
|
||||
} else
|
||||
// canonical case, userspace -> isr -> userspace
|
||||
if i.end_capture.0 == CaptureEvent::ISREnd {
|
||||
let start_state = states.get(&i.start_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 {
|
||||
// Nested interrupts. Jump over one interval
|
||||
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 {
|
||||
// Nested interrupts. Fast-forward to the end of the original interrupt, or the first valid state thereafter
|
||||
// TODO: this may cause the same release to be registered multiple times
|
||||
let mut isr_has_ended = false;
|
||||
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() {
|
||||
if let Some(interval_end) = trace.get(n) {
|
||||
if interval_end.end_capture.1 == i.start_capture.1 || isr_has_ended {
|
||||
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