1 use crate::{ 2 wasm_byte_vec_t, wasm_engine_t, wasm_name_t, wasmtime_error_t, wasmtime_module_t, 3 wasmtime_store_t, 4 }; 5 use std::slice; 6 use std::str::from_utf8; 7 use std::time::Duration; 8 use wasmtime::GuestProfiler; 9 10 pub struct wasmtime_guestprofiler_t { 11 guest_profiler: GuestProfiler, 12 } 13 14 wasmtime_c_api_macros::declare_own!(wasmtime_guestprofiler_t); 15 16 #[repr(C)] 17 pub struct wasmtime_guestprofiler_modules_t<'a> { 18 name: &'a wasm_name_t, 19 module: &'a wasmtime_module_t, 20 } 21 22 #[unsafe(no_mangle)] 23 pub 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)] 54 pub 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)] 65 pub 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 } 78