Commit 7f8c3101 authored by Marco Perronet's avatar Marco Perronet
Browse files

Add trace-sched-events

parent fd68ebc0
#!/bin/bash
sudo ../../target/debug/trace-sched-event "$@"
use structopt::StructOpt;
use serde_yaml;
use std::fs::{
OpenOptions,
remove_file,
};
use std::path::PathBuf;
use std::io::Write;
use rbf_trace::util::helpers::*;
use rbf_trace::events_generation::evg::{
EventsGenerator,
};
use rbf_trace::events_generation::ftrace::FTraceEVG;
use rbf_trace::feature_detection::system::get_pids_with_policy;
use rbf_trace::feature_detection::features::SchedPolicy;
fn main() {
let args = Opt::from_args();
let traced_pids: Vec<Pid>;
let target_pids: Vec<Pid>;
/* Parsing */
if let Some(pids) = args.pids {
traced_pids = pids;
} else {
traced_pids = get_pids_with_policy(vec!(SchedPolicy::FIFO, SchedPolicy::RR), false);
}
if let Some(ref pids) = args.target_pids {
target_pids = pids.clone();
} else {
target_pids = traced_pids.clone();
}
/* Tracing */
let mut evg = FTraceEVG::new(&target_pids, &traced_pids, args.ftrace_len, args.ftrace_bufsize);
let mut outputfile = None;
if let Some(ref path) = args.output {
if path.exists() {
remove_file(path).unwrap();
}
let file = OpenOptions::new()
.create_new(true)
.append(true)
.open(path)
.expect("Can't initialize file.");
outputfile = Some(file);
}
evg.setup();
eprintln!("Traced pids: {:#?}", traced_pids);
if let Some(ref target_pids) = args.target_pids {
eprintln!("Target pids: {:#?}", target_pids);
}
while let Some(event) = evg.next_event() {
let serialized = serde_yaml::to_string(&event).expect("Can't serialize.");
if let Some(ref mut file) = outputfile {
write!(file, "{}", serialized).expect("I/O error.");
} else {
print!("{}", serialized);
}
}
}
#[derive(Debug, StructOpt)]
pub struct Opt {
/// Trace only the specified pids. By default, all real-time threads are traced.
#[structopt(short = "p", long)]
pub pids: Option<Vec<Pid>>,
/// Trace until the specified pids are dead.
#[structopt(short = "t", long)]
pub target_pids: Option<Vec<Pid>>,
/// Trace for the specified duration (in seconds).
#[structopt(short = "l", long, default_value = "0")]
pub ftrace_len: Time,
/// Set ftrace buffer size (in kb).
#[structopt(short = "b", long, default_value = "65536")]
pub ftrace_bufsize: u32,
/// Output file, stdout if not present.
#[structopt(short = "o", long, parse(from_os_str))]
pub output: Option<PathBuf>,
}
......@@ -14,9 +14,12 @@ pub struct FTraceEVG {
processed_events: u64, // Only useful events
processed_events_all: u64,
start_time: std::time::Instant,
duration: u64, // Seconds
recorders_stopped: bool,
extra_event: Option<TraceEvent>,
/* User-defined parameters */
duration: u64, // In seconds
ftrace_bufsize: u32, // In kb
/* Needed to parse the events */
ids: EventsId,
......@@ -42,7 +45,7 @@ impl EventsGenerator for FTraceEVG {
After this, read_stream_parse() returns Some until the pipes are empty */
if !self.recorders_stopped &&
(self.targets_are_dead() ||
crate::params::ftrace_stop_on_timeout() && self.duration_reached()) {
self.duration > 0 && self.duration_reached()) {
self.disable_tracing_stop_recorders();
}
......@@ -100,7 +103,7 @@ impl EventsGenerator for FTraceEVG {
wrappers::set_event_fork(self.tracefs);
wrappers::set_pids(self.tracefs, &self.rt_pids);
wrappers::set_events(self.tracefs);
wrappers::set_buffer_size(self.tracefs, crate::params::ftrace_buf_size());
wrappers::set_buffer_size(self.tracefs, self.ftrace_bufsize);
/*** Activate tracing ***/
wrappers::start_tracing(self.tracefs);
......@@ -127,7 +130,7 @@ impl EventsGenerator for FTraceEVG {
}
impl FTraceEVG {
pub fn new(target_pids: &Vec<Pid>, rt_pids: &Vec<Pid>) -> Self {
pub fn new(target_pids: &Vec<Pid>, rt_pids: &Vec<Pid>, duration: u64, bufsize: u32) -> Self {
let tracefs = wrappers::create_tracefs();
let cpu_cnt = wrappers::get_cpu_cnt();
let recorders = wrappers::init_recorders(tracefs, cpu_cnt);
......@@ -139,9 +142,11 @@ impl FTraceEVG {
processed_events: 0,
processed_events_all: 0,
start_time: std::time::Instant::now(), // Will be set when reading the first event
duration: crate::params::ftrace_lifetime_sec(),
recorders_stopped: false,
extra_event: None,
duration: duration,
ftrace_bufsize: bufsize,
ids: EventsId::from_tracefs(tracefs),
......@@ -277,7 +282,7 @@ fn is_preemption(raw_event: &bindings::rbftrace_event_raw) -> bool {
}
/* Cleanup on ctrl+C */
// TODO this is very ugly, but rust won't let the use the EVG instance because of the presence of raw pointers
// TODO this is very ugly, but rust won't let us use the EVG instance because of the presence of raw pointers
fn sigint_handle() {
// Stop tracing
fs::write("/sys/kernel/debug/tracing/tracing_on", "0").expect("Can't write to file 'tracing_on'");
......
......@@ -28,7 +28,7 @@ pub static mut PRINT_PJITTER_ANALYSIS_PROGRESS: bool = false;
pub static mut FTRACE_BUF_SIZE: u32 = 65536;
// Use RBFtrace as a wrapper for ftrace, trace for FTRACE_LIFETIME_SEC seconds.
pub static mut FTRACE_ONLY: bool = false;
pub static mut FTRACE_LIFETIME_SEC: Time = 180;
pub static mut FTRACE_LIFETIME_SEC: Time = 0;
// Normally we stop when all target pids died. If this is true, we will stop after FTRACE_LIFETIME_SEC
pub static mut FTRACE_STOP_ON_TIMEOUT: bool = false;
// Trace every pid, not only rt pids
......
......@@ -47,7 +47,7 @@ fn run_replay(tx_evp: Sender<EventUpdate>, sys_conf: &SysConf) {
fn run_ftrace(tx_evp: Sender<EventUpdate>, sys_conf: &SysConf) {
println!("Target pids: {:?}", sys_conf.target_pids);
let mut evg = events_generation::ftrace::FTraceEVG::new(&sys_conf.target_pids, &sys_conf.rt_pids);
let mut evg = events_generation::ftrace::FTraceEVG::new(&sys_conf.target_pids, &sys_conf.rt_pids, crate::params::ftrace_lifetime_sec(), crate::params::ftrace_buf_size());
rbf_trace(&mut evg, &sys_conf.target_pids, tx_evp);
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment