rust/crates/profile/src/google_cpu_profiler.rs

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

45 lines
1.0 KiB
Rust
Raw Normal View History

2019-08-17 07:29:57 -05:00
//! https://github.com/gperftools/gperftools
use std::{
ffi::CString,
os::raw::c_char,
path::Path,
sync::atomic::{AtomicUsize, Ordering},
};
#[link(name = "profiler")]
#[allow(non_snake_case)]
extern "C" {
fn ProfilerStart(fname: *const c_char) -> i32;
fn ProfilerStop();
}
const OFF: usize = 0;
const ON: usize = 1;
const PENDING: usize = 2;
fn transition(current: usize, new: usize) -> bool {
static STATE: AtomicUsize = AtomicUsize::new(OFF);
STATE.compare_exchange(current, new, Ordering::SeqCst, Ordering::SeqCst).is_ok()
}
pub(crate) fn start(path: &Path) {
if !transition(OFF, PENDING) {
2019-08-17 07:29:57 -05:00
panic!("profiler already started");
}
let path = CString::new(path.display().to_string()).unwrap();
if unsafe { ProfilerStart(path.as_ptr()) } == 0 {
panic!("profiler failed to start")
}
assert!(transition(PENDING, ON));
2019-08-17 07:29:57 -05:00
}
pub(crate) fn stop() {
if !transition(ON, PENDING) {
2019-08-17 07:29:57 -05:00
panic!("profiler is not started")
}
unsafe { ProfilerStop() };
assert!(transition(PENDING, OFF));
2019-08-17 07:29:57 -05:00
}