in src/data/interrupts.rs [136:227]
fn process_collected_raw_data(buffer: Data) -> Result<ProcessedData> {
let mut interrupt_data = InterruptData::new();
let raw_value = match buffer {
Data::InterruptDataRaw(ref value) => value,
_ => panic!("Invalid Data type in raw file"),
};
let mut reader = BufReader::new(raw_value.data.as_bytes());
/* Collect the CPUs from the 1st line */
let mut cpus_string = String::new();
reader.read_line(&mut cpus_string)?;
let cpus = cpus_string.split_whitespace();
/* Create a vec to hold CPU # to be use later */
let cpus_nr: Vec<u64> = cpus
.into_iter()
.map(|string| string[3..].parse::<u64>().unwrap())
.collect();
let cpu_count = cpus_nr.len() as u64;
let mut interrupt_line_datas = Vec::new();
for line in reader.lines() {
let mut interrupt_line_data = InterruptLineData::new();
interrupt_line_data.set_time(raw_value.time);
let line = line?;
let mut split = line
.split(|c: char| c.is_whitespace() || c == ':')
.filter(|s| !s.is_empty());
/* Get type of interrupt line */
let intr_line = get_intr_line(split.next().unwrap())?;
interrupt_line_data.set_interrupt_line(intr_line.clone());
match intr_line {
InterruptLine::InterruptStr(ref value) => {
/* Interrupts of type MIS/ERR are not per cpu */
if value.to_uppercase() == "MIS" || value.to_uppercase() == "ERR" {
let interrupt_cpu_data = get_interrupt_cpu_data(split.next().unwrap(), 0)?;
interrupt_line_data.push_to_per_cpu(interrupt_cpu_data);
interrupt_line_data.set_type(value.to_string());
} else {
/* Other named INTRs are per-cpu */
for cpu in 0..cpu_count {
let interrupt_cpu_data = get_interrupt_cpu_data(
split.next().unwrap(),
*cpus_nr.get(cpu as usize).unwrap(),
)?;
interrupt_line_data.push_to_per_cpu(interrupt_cpu_data);
}
/*
* Their names can contain spaces. Use this until as_str is
* merged and available in stable Rust.
* https://github.com/rust-lang/rust/issues/77998
*
* as_str - Get the remaining data as is
*/
let mut type_name = Vec::<&str>::new();
loop {
let s = split.next();
match s {
Some(value) => type_name.push(value),
None => break,
}
}
interrupt_line_data.set_type(type_name.join(" ").to_string());
}
}
InterruptLine::InterruptNr(_) => {
/* Numbered interrupt lines are per-cpu */
for cpu in 0..cpu_count {
let interrupt_cpu_data = get_interrupt_cpu_data(
split.next().unwrap(),
*cpus_nr.get(cpu as usize).unwrap(),
)?;
interrupt_line_data.push_to_per_cpu(interrupt_cpu_data);
}
/* They also contain additional information about type, edge and device name */
let intr_type = split.next().unwrap();
let device_name = split.last().unwrap();
interrupt_line_data.set_type(intr_type.to_string());
interrupt_line_data.set_device(device_name.to_string());
}
_ => error!("Invalid interrupt type"),
}
interrupt_line_datas.push(interrupt_line_data);
}
trace!("{:#?}", interrupt_line_datas);
interrupt_data.set_interrupt_data(interrupt_line_datas);
let processed_data = ProcessedData::InterruptData(interrupt_data);
Ok(processed_data)
}