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