use super::{RecordId, Task};
#[derive(Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct CtxSwitch {
pub record_id: Option<RecordId>,
pub info: Switch,
}
impl CtxSwitch {
#[cfg(feature = "linux-4.3")]
pub(crate) unsafe fn from_ptr(
mut ptr: *const u8,
cpu_wide: bool,
misc: u16,
sample_id_all: Option<super::SampleType>,
) -> Self {
use super::SampleType;
use crate::ffi::{bindings as b, deref_offset};
let task = cpu_wide.then(|| Task {
pid: deref_offset(&mut ptr),
tid: deref_offset(&mut ptr),
});
let info = if misc as u32 & b::PERF_RECORD_MISC_SWITCH_OUT > 0 {
#[cfg(feature = "linux-4.17")]
let preempt = misc as u32 & b::PERF_RECORD_MISC_SWITCH_OUT_PREEMPT > 0;
#[cfg(not(feature = "linux-4.17"))]
let preempt = false;
Switch::OutTo { task, preempt }
} else {
Switch::InFrom(task)
};
let record_id = sample_id_all.map(|SampleType(ty)| RecordId::from_ptr(ptr, ty));
Self { record_id, info }
}
}
super::from!(CtxSwitch);
super::debug!(CtxSwitch {
{record_id?},
{info},
});
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum Switch {
OutTo {
task: Option<Task>,
preempt: bool,
},
InFrom(Option<Task>),
}