use core::{marker::PhantomData, mem}; use crate::{ bindings::{bpf_map_def, bpf_map_type::BPF_MAP_TYPE_PERF_EVENT_ARRAY, BPF_F_CURRENT_CPU}, helpers::bpf_perf_event_output, BpfContext, }; #[repr(transparent)] pub struct PerfMap { def: bpf_map_def, _t: PhantomData, } impl PerfMap { pub const fn new(flags: u32) -> PerfMap { PerfMap::with_max_entries(0, flags) } pub const fn with_max_entries(max_entries: u32, flags: u32) -> PerfMap { PerfMap { def: bpf_map_def { type_: BPF_MAP_TYPE_PERF_EVENT_ARRAY, key_size: mem::size_of::() as u32, value_size: mem::size_of::() as u32, max_entries, map_flags: flags, }, _t: PhantomData, } } pub fn output(&mut self, ctx: &C, data: &T) { self.output_at_index(ctx, None, data, 0) } pub fn output_at_index( &mut self, ctx: &C, index: Option, data: &T, flags: u32, ) { let index = index.map(|i| (i as u64) << 32).unwrap_or(BPF_F_CURRENT_CPU); let flags = index | flags as u64; unsafe { bpf_perf_event_output( ctx.as_ptr(), &mut self.def as *mut _ as *mut _, flags, data as *const _ as *mut _, mem::size_of::() as u64, ); } } }