@@ -5,7 +5,7 @@ use core::hint::black_box;
55use core:: mem:: MaybeUninit ;
66use core:: task:: Poll ;
77
8- use hermit_sync:: InterruptTicketMutex ;
8+ use hermit_sync:: { InterruptTicketMutex , Lazy } ;
99use wasi:: * ;
1010use wasmtime:: * ;
1111use zerocopy:: IntoBytes ;
@@ -25,6 +25,9 @@ fn native_fibonacci(n: u64) -> u64 {
2525 }
2626}
2727
28+ #[ inline( never) ]
29+ fn native_foo ( ) { }
30+
2831pub fn measure_fibonacci ( n : u64 ) {
2932 const RUNS : u64 = 100 ;
3033 info ! ( "Measure native_fibonacci({})" , n) ;
@@ -73,6 +76,7 @@ pub(crate) struct WasmManager {
7376
7477impl WasmManager {
7578 pub fn new ( data : & [ u8 ] ) -> Self {
79+ static MODULE_AND_ARGS : Lazy < Vec < & [ u8 ] > > = Lazy :: new ( || vec ! [ b"dummy\0 " ] ) ;
7680 let mut config: Config = Config :: new ( ) ;
7781 config. memory_init_cow ( false ) ;
7882 config. memory_guard_size ( 8192 ) ;
@@ -235,6 +239,122 @@ impl WasmManager {
235239 } ,
236240 )
237241 . unwrap ( ) ;
242+ linker
243+ . func_wrap (
244+ "wasi_snapshot_preview1" ,
245+ "args_get" ,
246+ |mut caller : Caller < ' _ , _ > , argv_ptr : i32 , argv_buf_ptr : i32 | {
247+ if let Some ( Extern :: Memory ( mem) ) = caller. get_export ( "memory" ) {
248+ let mut pos: u32 = argv_buf_ptr as u32 ;
249+ for ( i, element) in MODULE_AND_ARGS . iter ( ) . enumerate ( ) {
250+ let _ = mem. write (
251+ caller. as_context_mut ( ) ,
252+ ( argv_ptr + ( i * size_of :: < u32 > ( ) ) as i32 )
253+ . try_into ( )
254+ . unwrap ( ) ,
255+ pos. as_bytes ( ) ,
256+ ) ;
257+
258+ let _ = mem. write (
259+ caller. as_context_mut ( ) ,
260+ pos. try_into ( ) . unwrap ( ) ,
261+ element,
262+ ) ;
263+
264+ pos += element. len ( ) as u32 ;
265+ }
266+ }
267+ ERRNO_SUCCESS . raw ( ) as i32
268+ } ,
269+ )
270+ . unwrap ( ) ;
271+ linker
272+ . func_wrap (
273+ "wasi_snapshot_preview1" ,
274+ "args_sizes_get" ,
275+ move |mut caller : Caller < ' _ , _ > , number_args_ptr : i32 , args_size_ptr : i32 | {
276+ let nargs: u32 = MODULE_AND_ARGS . len ( ) . try_into ( ) . unwrap ( ) ;
277+ // Currently, we ignore the arguments
278+ if let Some ( Extern :: Memory ( mem) ) = caller. get_export ( "memory" ) {
279+ let _ = mem. write (
280+ caller. as_context_mut ( ) ,
281+ number_args_ptr. try_into ( ) . unwrap ( ) ,
282+ nargs. as_bytes ( ) ,
283+ ) ;
284+
285+ let nargs_size: u32 = MODULE_AND_ARGS
286+ . iter ( )
287+ . fold ( 0 , |acc, arg| acc + arg. len ( ) )
288+ . try_into ( )
289+ . unwrap ( ) ;
290+ let _ = mem. write (
291+ caller. as_context_mut ( ) ,
292+ args_size_ptr. try_into ( ) . unwrap ( ) ,
293+ nargs_size. as_bytes ( ) ,
294+ ) ;
295+
296+ return ERRNO_SUCCESS . raw ( ) as i32 ;
297+ }
298+
299+ ERRNO_INVAL . raw ( ) as i32
300+ } ,
301+ )
302+ . unwrap ( ) ;
303+ linker
304+ . func_wrap (
305+ "wasi_snapshot_preview1" ,
306+ "clock_time_get" ,
307+ |mut caller : Caller < ' _ , _ > , clock_id : i32 , _precision : i64 , timestamp_ptr : i32 | {
308+ match clock_id {
309+ 0 => {
310+ let usec = crate :: arch:: kernel:: systemtime:: now_micros ( ) ;
311+ if let Some ( Extern :: Memory ( mem) ) = caller. get_export ( "memory" ) {
312+ let nanos = usec * 1000 ;
313+ let _ = mem. write (
314+ caller. as_context_mut ( ) ,
315+ timestamp_ptr. try_into ( ) . unwrap ( ) ,
316+ nanos. as_bytes ( ) ,
317+ ) ;
318+
319+ return ERRNO_SUCCESS . raw ( ) as i32 ;
320+ }
321+
322+ ERRNO_INVAL . raw ( ) as i32
323+ }
324+ 1 => {
325+ warn ! ( "Unsupported clock_id" ) ;
326+ ERRNO_INVAL . raw ( ) as i32
327+ }
328+ _ => ERRNO_INVAL . raw ( ) as i32 ,
329+ }
330+ } ,
331+ )
332+ . unwrap ( ) ;
333+ linker
334+ . func_wrap ( "wasi_snapshot_preview1" , "fd_close" , |_fd : i32 | {
335+ ERRNO_SUCCESS . raw ( ) as i32
336+ } )
337+ . unwrap ( ) ;
338+ linker
339+ . func_wrap (
340+ "wasi_snapshot_preview1" ,
341+ "fd_fdstat_get" ,
342+ |_: i32 , _: i32 | {
343+ warn ! ( "Unsupported function fd_fdstat_get" ) ;
344+ ERRNO_SUCCESS . raw ( ) as i32
345+ } ,
346+ )
347+ . unwrap ( ) ;
348+ linker
349+ . func_wrap (
350+ "wasi_snapshot_preview1" ,
351+ "fd_seek" ,
352+ |_: i32 , _: i64 , _: i32 , _: i32 | {
353+ warn ! ( "Unsupported function fd_seek" ) ;
354+ ERRNO_SUCCESS . raw ( ) as i32
355+ } ,
356+ )
357+ . unwrap ( ) ;
238358 linker
239359 . func_wrap ( "wasi_snapshot_preview1" , "proc_exit" , |_: i32 | {
240360 error ! ( "Panic in WASM module" )
@@ -298,10 +418,13 @@ async fn wasm_run() {
298418pub extern "C" fn sys_load_binary ( ptr : * const u8 , len : usize ) -> i32 {
299419 info ! ( "Loading WebAssembly binary..." ) ;
300420
421+ let start = now_micros ( ) ;
301422 let slice = unsafe { core:: slice:: from_raw_parts ( ptr, len) } ;
302423 let wasm_manager = WasmManager :: new ( slice) ;
303424
304425 * WASM_MANAGER . lock ( ) = Some ( wasm_manager) ;
426+ let end = now_micros ( ) ;
427+ info ! ( "Time to initiate WASM module {} usec" , end - start) ;
305428
306429 if let Some ( ref mut wasm_manager) = crate :: wasm:: WASM_MANAGER . lock ( ) . as_mut ( ) {
307430 let _ = wasm_manager. call_func :: < ( ) , ( ) > ( "hello_world" , ( ) ) ;
@@ -312,6 +435,53 @@ pub extern "C" fn sys_load_binary(ptr: *const u8, len: usize) -> i32 {
312435 0
313436}
314437
438+ #[ hermit_macro:: system]
439+ #[ unsafe( no_mangle) ]
440+ pub extern "C" fn sys_dhrystone ( ) -> i32 {
441+ if let Some ( ref mut wasm_manager) = WASM_MANAGER . lock ( ) . as_mut ( ) {
442+ // And finally we can call the wasm function
443+ info ! ( "Call function dhrystone" ) ;
444+ let _result = wasm_manager. call_func :: < ( ) , ( ) > ( "_start" , ( ) ) . unwrap ( ) ;
445+ }
446+
447+ 0
448+ }
449+
450+ #[ hermit_macro:: system]
451+ #[ unsafe( no_mangle) ]
452+ pub extern "C" fn sys_foo ( ) -> i32 {
453+ if let Some ( ref mut wasm_manager) = WASM_MANAGER . lock ( ) . as_mut ( ) {
454+ // And finally we can call the wasm function
455+ info ! ( "Call function foo" ) ;
456+ let _result = wasm_manager. call_func :: < ( ) , ( ) > ( "foo" , ( ) ) . unwrap ( ) ;
457+
458+ const RUNS : u64 = 1000000 ;
459+ let start = now_micros ( ) ;
460+ for _ in 0 ..RUNS {
461+ black_box ( wasm_manager. call_func :: < ( ) , ( ) > ( "foo" , ( ) ) . unwrap ( ) ) ;
462+ }
463+ let end = now_micros ( ) ;
464+ info ! (
465+ "Average time to call the WASM function foo: {} nsec" ,
466+ ( 1000 * ( end - start) ) / RUNS
467+ ) ;
468+
469+ let start = now_micros ( ) ;
470+ for _ in 0 ..RUNS {
471+ black_box ( native_foo ( ) ) ;
472+ }
473+ let end = now_micros ( ) ;
474+
475+ info ! (
476+ "Time to call {} times the function foo: {} nsec" ,
477+ RUNS ,
478+ 1000 * ( end - start)
479+ ) ;
480+ }
481+
482+ 0
483+ }
484+
315485#[ hermit_macro:: system]
316486#[ unsafe( no_mangle) ]
317487pub extern "C" fn sys_fibonacci ( ) -> i32 {
0 commit comments