bcc/perf_event/
perf_map.rs1use crate::cpuonline;
2use crate::error::BccError;
3use crate::perf_event::open_perf_buffer;
4use crate::perf_event::perf_reader::PerfReader;
5use crate::table::Table;
6use bcc_sys::bccapi::perf_reader;
7use bcc_sys::bccapi::perf_reader_poll;
8use byteorder::NativeEndian;
9use byteorder::WriteBytesExt;
10use std::io::Cursor;
11
12pub struct PerfMapBuilder<F: Fn() -> Box<dyn FnMut(&[u8]) + Send>> {
14 table: Table,
15 cb: F,
16 page_count: i32,
17}
18
19impl<F: Fn() -> Box<dyn FnMut(&[u8]) + Send>> PerfMapBuilder<F> {
20 pub fn new(table: Table, cb: F) -> Self {
22 Self {
23 table,
24 cb,
25 page_count: super::BPF_PERF_READER_PAGE_CNT,
26 }
27 }
28
29 pub fn page_count(mut self, page_count: i32) -> Self {
31 self.page_count = page_count;
32 self
33 }
34
35 pub fn build(mut self) -> Result<PerfMap, BccError> {
37 let key_size = self.table.key_size();
38 let leaf_size = self.table.leaf_size();
39 let leaf = vec![0; leaf_size];
40
41 if key_size != 4 || leaf_size != 4 {
42 return Err(BccError::TableInvalidSize);
43 }
44
45 let mut readers: Vec<PerfReader> = vec![];
46 let mut cur = Cursor::new(leaf);
47
48 let cpus = cpuonline::get()?;
49 for cpu in cpus.iter() {
50 let mut reader = open_perf_buffer(*cpu, (self.cb)(), self.page_count)?;
51 let perf_fd = reader.fd() as u32;
52 readers.push(reader);
53
54 let mut key = vec![];
55 key.write_u32::<NativeEndian>(*cpu as u32)?;
56 cur.write_u32::<NativeEndian>(perf_fd)?;
57 if self.table.set(&mut key, &mut cur.get_mut()).is_ok() {
58 cur.set_position(0);
59 } else {
60 return Err(BccError::InitializePerfMap);
61 }
62 }
63 Ok(PerfMap { readers })
64 }
65}
66
67#[allow(dead_code)]
68pub struct PerfMap {
69 pub(crate) readers: Vec<PerfReader>,
70}
71
72#[deprecated(
75 since = "0.0.30",
76 note = "Please use PerfMapBuilder to create a new PerfMap instead"
77)]
78pub fn init_perf_map<F>(table: Table, cb: F) -> Result<PerfMap, BccError>
79where
80 F: Fn() -> Box<dyn FnMut(&[u8]) + Send>,
81{
82 PerfMapBuilder::new(table, cb).build()
83}
84
85impl PerfMap {
86 pub fn poll(&mut self, timeout: i32) {
87 unsafe {
88 perf_reader_poll(
89 self.readers.len() as i32,
90 self.readers.as_ptr() as *mut *mut perf_reader,
91 timeout,
92 )
93 };
94 }
95}