fix task releases with nested interrupts

This commit is contained in:
Alwin Berger 2024-08-28 14:16:03 +02:00
parent 461731cc5a
commit 2c00f82d39

View File

@ -220,10 +220,10 @@ fn refine_system_states(mut input: Vec<RawFreeRTOSSystemState>) -> (Vec<ReducedF
// Find all task release times. A release is SysTickHandler isr block that moves a task from the delay list to the ready list // Find all task release times. A release is SysTickHandler isr block that moves a task from the delay list to the ready list
fn get_releases(tarce: &Vec<ExecInterval>, states: &HashMap<u64, ReducedFreeRTOSSystemState>) -> Vec<(u64, String)> { fn get_releases(trace: &Vec<ExecInterval>, states: &HashMap<u64, ReducedFreeRTOSSystemState>) -> Vec<(u64, String)> {
let mut ret = Vec::new(); let mut ret = Vec::new();
let mut initial_released = false; let mut initial_released = false;
for (_n, i) in tarce.iter().enumerate() { for (_n, i) in trace.iter().enumerate() {
if !initial_released && i.start_capture.0 == CaptureEvent::ISREnd && i.start_capture.1 == "xPortPendSVHandler" { if !initial_released && i.start_capture.0 == CaptureEvent::ISREnd && i.start_capture.1 == "xPortPendSVHandler" {
let start_state = states.get(&i.start_state).expect("State not found"); let start_state = states.get(&i.start_state).expect("State not found");
initial_released = true; initial_released = true;
@ -232,7 +232,8 @@ fn get_releases(tarce: &Vec<ExecInterval>, states: &HashMap<u64, ReducedFreeRTOS
}); });
continue; continue;
} }
if i.start_capture.0 == CaptureEvent::ISRStart && ( i.start_capture.1 == "xPortSysTickHandler" || i.start_capture.1 == "isr_starter" ) && i.end_capture.0 == CaptureEvent::ISREnd { if i.start_capture.0 == CaptureEvent::ISRStart && ( i.start_capture.1 == "xPortSysTickHandler" || i.start_capture.1 == "isr_starter" ) {
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");
end_state.ready_list_after.iter().for_each(|x| { end_state.ready_list_after.iter().for_each(|x| {
@ -245,6 +246,20 @@ fn get_releases(tarce: &Vec<ExecInterval>, states: &HashMap<u64, ReducedFreeRTOS
// ret.push((i.end_tick, x.task_name.clone())); // ret.push((i.end_tick, x.task_name.clone()));
// } // }
// }); // });
} 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 {
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()));
}
});
}
}
}
} }
} }
ret ret