fn initialize_bpf_perf()

in src/samplers/scheduler/mod.rs [146:208]


    fn initialize_bpf_perf(&mut self) -> Result<(), std::io::Error> {
        let cpus = crate::common::hardware_threads().unwrap();
        let interval = self.interval() as u64;
        let frequency = if interval > 1000 {
            1
        } else if interval == 0 {
            1
        } else {
            1000 / interval
        };

        let code = format!(
            "{}\n{}",
            format!("#define NUM_CPU {}", cpus),
            include_str!("perf.c").to_string()
        );

        let mut perf_array_attached = false;
        if let Ok(mut bpf) = bcc::BPF::new(&code) {
            for statistic in &self.statistics {
                if let Some(table) = statistic.perf_table() {
                    if let Some(event) = statistic.event() {
                        perf_array_attached = true;
                        if PerfEventArray::new()
                            .table(&format!("{}_array", table))
                            .event(event)
                            .attach(&mut bpf)
                            .is_err()
                        {
                            if !self.common().config().general().fault_tolerant() {
                                fatal!("failed to initialize perf bpf for event: {:?}", event);
                            } else {
                                error!("failed to initialize perf bpf for event: {:?}", event);
                            }
                        }
                    }
                }
            }
            debug!("attaching software event to drive perf counter sampling");
            if perf_array_attached {
                if PerfEvent::new()
                    .handler("do_count")
                    .event(Event::Software(SoftwareEvent::CpuClock))
                    .sample_frequency(Some(frequency))
                    .attach(&mut bpf)
                    .is_err()
                {
                    if !self.common().config().general().fault_tolerant() {
                        fatal!("failed to initialize perf bpf for cpu");
                    } else {
                        error!("failed to initialize perf bpf for cpu");
                    }
                }
            }

            self.perf = Some(Arc::new(Mutex::new(BPF { inner: bpf })));
        } else if !self.common().config().general().fault_tolerant() {
            fatal!("failed to initialize perf bpf");
        } else {
            error!("failed to initialize perf bpf. skipping scheduler perf telemetry");
        }
        Ok(())
    }