Enum SampleOn

Source
pub enum SampleOn {
    Freq(u64),
    Count(u64),
}
Expand description

Controls when to generate a sample record.

Defaults to Count(0) (no sample mode in perf record command), set it to the desired rate to generate sample records.

The maximum sample rate is specified in /proc/sys/kernel/perf_event_max_sample_rate, Throttle record will be generated if the limit has been reached.

Meanwhile, /proc/sys/kernel/perf_cpu_time_max_percent limits the CPU time allowed to handle sampling (0 means unlimited). Sampling also will be throttled if this limit has been reached.

§Event overflow

The kernel maintains an unsigned counter with an appropriate negative initial value, which will finally overflows since every event increase it by one. Then sampling will be triggered and that counter will be reset to prepare for the next overflow. This is what this option actually controls.

In addition to asynchronous iterators with wake up option, overflow can also be captured by enabling I/O signaling from the perf event fd, which indicates POLL_IN on each overflow.

Here is an example:

// Fork to avoid signal handler conflicts.
use std::mem::MaybeUninit;
use std::os::fd::AsRawFd;
use std::ptr::null_mut;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering;

use perf_event_open::config::{Cpu, Opts, Proc, SampleOn};
use perf_event_open::count::Counter;
use perf_event_open::event::sw::Software;

static IN: AtomicBool = AtomicBool::new(false);

let event = Software::TaskClock;
let target = (Proc::CURRENT, Cpu::ALL);
let mut opts = Opts::default();
opts.sample_on = SampleOn::Count(1_000_000); // 1ms

let counter = Counter::new(event, target, opts).unwrap();

// Enable I/O signals from perf event fd to the current process.
let fd = counter.file().as_raw_fd();
unsafe {
    libc::fcntl(fd, libc::F_SETFL, libc::O_ASYNC);
    // The value of `F_SETSIG` is 10, and libc crate does not have
    // that binding (same as `POLL_IN` below).
    libc::fcntl(fd, 10, libc::SIGIO);
    libc::fcntl(fd, libc::F_SETOWN, libc::getpid());
}

fn handler(num: i32, info: *const libc::siginfo_t) {
    assert_eq!(num, libc::SIGIO);
    let si_code = unsafe { *info }.si_code;
    assert_eq!(si_code, 1); // POLL_IN
    IN.store(true, Ordering::Relaxed);
}
let act = libc::sigaction {
    sa_sigaction: handler as _,
    sa_mask: unsafe { MaybeUninit::zeroed().assume_init() },
    sa_flags: libc::SA_SIGINFO,
    sa_restorer: None,
};
unsafe { libc::sigaction(libc::SIGIO, &act as _, null_mut()) };

let sampler = counter.sampler(5).unwrap();
counter.enable().unwrap();

while !IN.load(Ordering::Relaxed) {
    std::hint::spin_loop();
}

println!("{:-?}", sampler.iter().next());

For more information on I/O signals, see also Sampler::enable_counter_with.

Variants§

§

Freq(u64)

Sample on frequency (Hz).

The kernel will adjust the sampling period to try and achieve the desired rate.

Freq(0) means no overflow, i.e., sample records will never be generated.

§

Count(u64)

Sample on every N event counts.

It is referred to sample period.

Count(0) is the default value for SampleOn, it has the same meaning as Freq(0).

Trait Implementations§

Source§

impl Clone for SampleOn

Source§

fn clone(&self) -> SampleOn

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for SampleOn

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for SampleOn

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.