Skip to content

Commit 9725151

Browse files
committed
handle wasm io to a asynchronous task
1 parent 87c04a7 commit 9725151

File tree

1 file changed

+44
-23
lines changed

1 file changed

+44
-23
lines changed

src/wasm/mod.rs

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
use alloc::collections::VecDeque;
22
use alloc::vec::Vec;
3+
use core::future;
34
use core::hint::black_box;
45
use core::mem::MaybeUninit;
6+
use core::task::Poll;
57

68
use hermit_sync::InterruptTicketMutex;
79
use wasi::*;
810
use wasmtime::*;
911
use zerocopy::IntoBytes;
1012

11-
use crate::fd;
13+
use crate::console::CONSOLE;
14+
use crate::executor::{WakerRegistration, spawn};
1215
use crate::kernel::systemtime::now_micros;
1316

1417
mod capi;
@@ -42,6 +45,26 @@ pub(crate) static WASM_MANAGER: InterruptTicketMutex<Option<WasmManager>> =
4245
InterruptTicketMutex::new(None);
4346
pub(crate) static INPUT: InterruptTicketMutex<VecDeque<Vec<u8>>> =
4447
InterruptTicketMutex::new(VecDeque::new());
48+
static OUTPUT: InterruptTicketMutex<WasmStdout> = InterruptTicketMutex::new(WasmStdout::new());
49+
50+
struct WasmStdout {
51+
pub data: VecDeque<Vec<u8>>,
52+
pub waker: WakerRegistration,
53+
}
54+
55+
impl WasmStdout {
56+
pub const fn new() -> Self {
57+
Self {
58+
data: VecDeque::new(),
59+
waker: WakerRegistration::new(),
60+
}
61+
}
62+
63+
pub fn write(&mut self, buf: &[u8]) {
64+
self.data.push_back(buf.to_vec());
65+
self.waker.wake();
66+
}
67+
}
4568

4669
pub(crate) struct WasmManager {
4770
store: Store<u32>,
@@ -79,7 +102,6 @@ impl WasmManager {
79102
panic!("fd_read: invalid file descriptor {}", fd);
80103
};
81104

82-
info!("fd {}", fd);
83105
if let Some(Extern::Memory(mem)) = caller.get_export("memory") {
84106
let mut iovs = vec![0i32; (2 * iovs_len).try_into().unwrap()];
85107
let _ = mem.read(
@@ -89,21 +111,18 @@ impl WasmManager {
89111
);
90112

91113
let mut nread_bytes: i32 = 0;
92-
let mut i = 0;
114+
let i = 0;
93115
if let Some(data) = INPUT.lock().pop_front() {
94-
let len = iovs[i + 1];
95-
info!("len = {}, {}", len, data.len());
116+
let _len = iovs[i + 1];
96117

97-
while i < iovs.len() {
118+
if !data.is_empty() {
98119
let _ = mem.write(
99120
caller.as_context_mut(),
100121
iovs[i].try_into().unwrap(),
101122
&data,
102123
);
103124

104125
nread_bytes += data.len() as i32;
105-
106-
i += 2;
107126
}
108127
}
109128

@@ -125,16 +144,10 @@ impl WasmManager {
125144
"wasi_snapshot_preview1",
126145
"fd_write",
127146
|mut caller: Caller<'_, u32>,
128-
fd: i32,
147+
_fd: i32,
129148
iovs_ptr: i32,
130149
iovs_len: i32,
131150
nwritten_ptr: i32| {
132-
let fd = if fd <= 2 {
133-
fd
134-
} else {
135-
panic!("fd_write: invalid file descriptor {}", fd);
136-
};
137-
138151
if let Some(Extern::Memory(mem)) = caller.get_export("memory") {
139152
let mut iovs = vec![0i32; (2 * iovs_len).try_into().unwrap()];
140153
let _ = mem.read(
@@ -165,14 +178,8 @@ impl WasmManager {
165178
iovs[i].try_into().unwrap(),
166179
unsafe { data.assume_init_mut() },
167180
);
168-
let result = fd::write(fd, unsafe { data.assume_init_ref() });
169-
170-
match result {
171-
Ok(n) => {
172-
nwritten_bytes += n as i32;
173-
}
174-
Err(err) => return -i32::from(err),
175-
}
181+
OUTPUT.lock().write(unsafe { data.assume_init_mut() });
182+
nwritten_bytes += len;
176183

177184
i += 2;
178185
}
@@ -263,6 +270,18 @@ pub extern "C" fn sys_unload_binary() -> i32 {
263270
0
264271
}
265272

273+
async fn wasm_run() {
274+
future::poll_fn(|cx| {
275+
let mut guard = OUTPUT.lock();
276+
while let Some(data) = guard.data.pop_front() {
277+
CONSOLE.lock().write(&data);
278+
}
279+
guard.waker.register(cx.waker());
280+
Poll::<()>::Pending
281+
})
282+
.await;
283+
}
284+
266285
#[hermit_macro::system]
267286
#[unsafe(no_mangle)]
268287
pub extern "C" fn sys_load_binary(ptr: *const u8, len: usize) -> i32 {
@@ -277,6 +296,8 @@ pub extern "C" fn sys_load_binary(ptr: *const u8, len: usize) -> i32 {
277296
let _ = wasm_manager.call_func::<(), ()>("hello_world", ());
278297
}
279298

299+
spawn(wasm_run());
300+
280301
0
281302
}
282303

0 commit comments

Comments
 (0)