From 208b7bd7ba687fb570feb1b89219f14c63712ce8 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 12 Aug 2020 16:32:36 +0200 Subject: Rename ra_prof -> profile --- crates/profile/src/google_cpu_profiler.rs | 39 +++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 crates/profile/src/google_cpu_profiler.rs (limited to 'crates/profile/src/google_cpu_profiler.rs') diff --git a/crates/profile/src/google_cpu_profiler.rs b/crates/profile/src/google_cpu_profiler.rs new file mode 100644 index 000000000..db865c65b --- /dev/null +++ b/crates/profile/src/google_cpu_profiler.rs @@ -0,0 +1,39 @@ +//! 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(); +} + +static PROFILER_STATE: AtomicUsize = AtomicUsize::new(OFF); +const OFF: usize = 0; +const ON: usize = 1; +const PENDING: usize = 2; + +pub fn start(path: &Path) { + if PROFILER_STATE.compare_and_swap(OFF, PENDING, Ordering::SeqCst) != OFF { + 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!(PROFILER_STATE.compare_and_swap(PENDING, ON, Ordering::SeqCst) == PENDING); +} + +pub fn stop() { + if PROFILER_STATE.compare_and_swap(ON, PENDING, Ordering::SeqCst) != ON { + panic!("profiler is not started") + } + unsafe { ProfilerStop() }; + assert!(PROFILER_STATE.compare_and_swap(PENDING, OFF, Ordering::SeqCst) == PENDING); +} -- cgit v1.2.3