processortrace 0.0.3

Rust library to set-up Intel processor trace for getting raw trace data.
use std::fs::File;
use std::io::prelude::*;
use std::process::Command;

use libc;

use alloc::vec::Vec;
use {TraceControllerSettings, TraceDumpControl};

pub struct TraceDump {
    pub data: Vec<u8>,
    settings: TraceControllerSettings,
}

impl TraceDump {
    pub fn new(raw_data: &[u8], settings: TraceControllerSettings) -> TraceDump {
        let mut data = Vec::with_capacity(raw_data.len());
        data.extend_from_slice(raw_data);
        TraceDump {
            data: data,
            settings: settings,
        }
    }
}

impl TraceDumpControl for TraceDump {
    fn save(&self, filename: &str) {
        let mut file = File::create(format!("{}.ptdump", filename)).unwrap();
        file.write_all(self.data.as_slice() as &[u8]).unwrap();

        let mut file = File::create(format!("{}.ptsettings", filename)).unwrap();
        file.write_all(format!("{:?}\n", self.settings).as_bytes())
            .unwrap();

        let mut file = File::create(format!("{}.ptinfo", filename)).unwrap();
        let cpuid = x86::cpuid::CpuId::new();
        let family_id = cpuid.get_feature_info().map_or(0, |s| s.family_id());
        let model_id = cpuid.get_feature_info().map_or(0, |s| s.model_id());
        let stepping = cpuid.get_feature_info().map_or(0, |s| s.stepping_id());
        let nom_freq = cpuid
            .get_processor_frequency_info()
            .map_or(0, |s| s.processor_max_frequency() / 100);
        let tsc_ratio = cpuid
            .get_tsc_info()
            .map_or((0, 0), |s| (s.numerator(), s.denominator()));

        file.write_all(
            format!(
                "meta family {}
meta model {}
meta stepping {}
meta mtc_freq {}
meta nom_freq {}
meta tsc_ratio {} {}\n",
                family_id,
                model_id,
                stepping,
                self.settings.mtc_freq,
                nom_freq,
                tsc_ratio.1,
                tsc_ratio.0
            )
            .as_bytes(),
        )
        .unwrap();

        let pid = unsafe { libc::getpid() };
        Command::new("cp")
            .arg(format!("/proc/{}/maps", pid))
            .arg(format!("{}.ptmap", filename))
            .output()
            .expect("failed to execute process");
    }
}