scx_utils/
perf.rs

1#![allow(non_upper_case_globals)]
2#![allow(non_camel_case_types)]
3#![allow(non_snake_case)]
4
5use libc::pid_t;
6use std::os::raw::{c_int, c_ulong};
7
8/// The `perf_event_open` system call.
9///
10/// See the [`perf_event_open(2) man page`][man] for details.
11///
12/// On error, this returns -1, and the C `errno` value (accessible via
13/// `std::io::Error::last_os_error`) is set to indicate the error.
14///
15/// Note: The `attrs` argument needs to be a `*mut` because if the `size` field
16/// is too small or too large, the kernel writes the size it was expecing back
17/// into that field. It might do other things as well.
18///
19/// # Safety
20///
21/// The `attrs` argument must point to a properly initialized
22/// `perf_event_attr` struct. The measurements and other behaviors its
23/// contents request must be safe.
24///
25/// [man]: https://www.mankier.com/2/perf_event_open
26pub unsafe fn perf_event_open(
27    attrs: *mut bindings::perf_event_attr,
28    pid: pid_t,
29    cpu: c_int,
30    group_fd: c_int,
31    flags: c_ulong,
32) -> c_int {
33    unsafe {
34        libc::syscall(
35            bindings::__NR_perf_event_open as libc::c_long,
36            attrs as *const bindings::perf_event_attr,
37            pid,
38            cpu,
39            group_fd,
40            flags,
41        ) as c_int
42    }
43}
44
45pub mod bindings {
46    include!(concat!(env!("OUT_DIR"), "/perf_bindings.rs"));
47}
48
49pub mod ioctls {
50    use crate::perf;
51    use std::os::raw::{c_int, c_uint};
52
53    #[allow(clippy::missing_safety_doc)]
54    pub unsafe fn enable(fd: c_int, arg: c_uint) -> c_int {
55        unsafe { libc::ioctl(fd, perf::bindings::ENABLE.into(), arg) }
56    }
57
58    #[allow(clippy::missing_safety_doc)]
59    pub unsafe fn reset(fd: c_int, arg: c_uint) -> c_int {
60        unsafe { libc::ioctl(fd, perf::bindings::RESET.into(), arg) }
61    }
62}