use perf_event::events::Breakpoint; use perf_event::Builder; // Need a function that will not be optimized away or inlined by the compiler. #[inline(never)] fn use_data(data: &[u8]) { for byte in data { // Use a volatile read here to ensure that the resulting program // actually does the read from data and it doesn't get optimized away. unsafe { std::ptr::read_volatile(byte) }; } } #[test] fn data() { let data = b"TEST DATA".to_vec(); let mut counter = Builder::new(Breakpoint::read_write(data.as_ptr() as usize as _, 1)) .observe_self() .build() .expect("Unable to build performance counter"); counter.enable().unwrap(); for _ in 0..1000 { use_data(&data); } counter.disable().unwrap(); assert_eq!(counter.read().unwrap(), 1000); } #[test] fn execute() { let data = b"TEST DATA".to_vec(); let fnptr = use_data as fn(_) -> _; let mut counter = Builder::new(Breakpoint::execute(fnptr as usize as u64)) .observe_self() .build() .expect("Unable to build performance counter"); counter.enable().unwrap(); for _ in 0..1000 { use_data(&data); } counter.disable().unwrap(); assert_eq!(counter.read().unwrap(), 1000); }