wasmtime_c_api/
profiling.rs

1use crate::{
2    wasm_byte_vec_t, wasm_engine_t, wasm_name_t, wasmtime_error_t, wasmtime_module_t,
3    wasmtime_store_t,
4};
5use std::slice;
6use std::str::from_utf8;
7use std::time::Duration;
8use wasmtime::GuestProfiler;
9
10pub struct wasmtime_guestprofiler_t {
11    guest_profiler: GuestProfiler,
12}
13
14wasmtime_c_api_macros::declare_own!(wasmtime_guestprofiler_t);
15
16#[repr(C)]
17pub struct wasmtime_guestprofiler_modules_t<'a> {
18    name: &'a wasm_name_t,
19    module: &'a wasmtime_module_t,
20}
21
22#[unsafe(no_mangle)]
23pub unsafe extern "C" fn wasmtime_guestprofiler_new(
24    engine: &wasm_engine_t,
25    module_name: &wasm_name_t,
26    interval_nanos: u64,
27    modules: *const wasmtime_guestprofiler_modules_t,
28    modules_len: usize,
29) -> Box<wasmtime_guestprofiler_t> {
30    let module_name = from_utf8(&module_name.as_slice()).expect("not valid utf-8");
31    let list = slice::from_raw_parts(modules, modules_len)
32        .iter()
33        .map(|entry| {
34            (
35                from_utf8(entry.name.as_slice())
36                    .expect("not valid utf-8")
37                    .to_owned(),
38                entry.module.module.clone(),
39            )
40        })
41        .collect::<Vec<_>>();
42    Box::new(wasmtime_guestprofiler_t {
43        guest_profiler: GuestProfiler::new(
44            &engine.engine,
45            module_name,
46            Duration::from_nanos(interval_nanos),
47            list,
48        )
49        .unwrap(),
50    })
51}
52
53#[unsafe(no_mangle)]
54pub extern "C" fn wasmtime_guestprofiler_sample(
55    guestprofiler: &mut wasmtime_guestprofiler_t,
56    store: &wasmtime_store_t,
57    delta_nanos: u64,
58) {
59    guestprofiler
60        .guest_profiler
61        .sample(&store.store, Duration::from_nanos(delta_nanos));
62}
63
64#[unsafe(no_mangle)]
65pub extern "C" fn wasmtime_guestprofiler_finish(
66    guestprofiler: Box<wasmtime_guestprofiler_t>,
67    out: &mut wasm_byte_vec_t,
68) -> Option<Box<wasmtime_error_t>> {
69    let mut buf = vec![];
70    match guestprofiler.guest_profiler.finish(&mut buf) {
71        Ok(()) => {
72            out.set_buffer(buf);
73            None
74        }
75        Err(e) => Some(Box::new(e.into())),
76    }
77}