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