From acbea30e22ecd166b7335fb0b5a17fa78f9c3d5f Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 11 Sep 2023 10:01:13 -0600 Subject: [PATCH 1/2] [wasmtime-wasi] fix logic error in `monotonic-clock/subscribe` When calculating the number of nanoseconds to wait, we should subtract the current time from the deadline, not vice-versa. This was causing guests to sleep indefinitely due to integer underflow. Signed-off-by: Joel Dice --- crates/wasi/src/preview2/host/clocks.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/wasi/src/preview2/host/clocks.rs b/crates/wasi/src/preview2/host/clocks.rs index c8c1afc4df87..2c461bd804c8 100644 --- a/crates/wasi/src/preview2/host/clocks.rs +++ b/crates/wasi/src/preview2/host/clocks.rs @@ -64,7 +64,7 @@ impl monotonic_clock::Host for T { })))?) } else { let duration = if absolute { - Duration::from_nanos(clock_now - when) + Duration::from_nanos(when - clock_now) } else { Duration::from_nanos(when) }; From f2d69dcc011fba2397b3795b911d460777445755 Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Mon, 11 Sep 2023 11:04:41 -0600 Subject: [PATCH 2/2] add `sleep` test to `wasi-tests` Note that this is annotated `should_panic` when testing preview1 scenarios, since those won't have preview2 imports. Signed-off-by: Joel Dice --- Cargo.lock | 1 + crates/test-programs/tests/wasi-cap-std-sync.rs | 5 +++++ .../tests/wasi-preview1-host-in-preview2.rs | 5 +++++ .../tests/wasi-preview2-components-sync.rs | 4 ++++ .../tests/wasi-preview2-components.rs | 4 ++++ crates/test-programs/tests/wasi-tokio.rs | 5 +++++ crates/test-programs/wasi-tests/Cargo.toml | 3 +++ crates/test-programs/wasi-tests/src/bin/sleep.rs | 16 ++++++++++++++++ 8 files changed, 43 insertions(+) create mode 100644 crates/test-programs/wasi-tests/src/bin/sleep.rs diff --git a/Cargo.lock b/Cargo.lock index 4fc8a705b905..5fe0859d37dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3077,6 +3077,7 @@ dependencies = [ "libc", "once_cell", "wasi", + "wit-bindgen", ] [[package]] diff --git a/crates/test-programs/tests/wasi-cap-std-sync.rs b/crates/test-programs/tests/wasi-cap-std-sync.rs index 6b7143f3b540..860da98024bb 100644 --- a/crates/test-programs/tests/wasi-cap-std-sync.rs +++ b/crates/test-programs/tests/wasi-cap-std-sync.rs @@ -250,6 +250,11 @@ fn sched_yield() { run("sched_yield", true).unwrap() } #[test_log::test] +#[should_panic] +fn sleep() { + run("sleep", true).unwrap() +} +#[test_log::test] fn stdio() { run("stdio", true).unwrap() } diff --git a/crates/test-programs/tests/wasi-preview1-host-in-preview2.rs b/crates/test-programs/tests/wasi-preview1-host-in-preview2.rs index 05dbd32717d9..639504fbe121 100644 --- a/crates/test-programs/tests/wasi-preview1-host-in-preview2.rs +++ b/crates/test-programs/tests/wasi-preview1-host-in-preview2.rs @@ -294,6 +294,11 @@ async fn sched_yield() { run("sched_yield", false).await.unwrap() } #[test_log::test(tokio::test(flavor = "multi_thread"))] +#[should_panic] +async fn sleep() { + run("sleep", false).await.unwrap() +} +#[test_log::test(tokio::test(flavor = "multi_thread"))] async fn stdio() { run("stdio", false).await.unwrap() } diff --git a/crates/test-programs/tests/wasi-preview2-components-sync.rs b/crates/test-programs/tests/wasi-preview2-components-sync.rs index 08b60217be62..df0c995c1578 100644 --- a/crates/test-programs/tests/wasi-preview2-components-sync.rs +++ b/crates/test-programs/tests/wasi-preview2-components-sync.rs @@ -272,6 +272,10 @@ fn sched_yield() { run("sched_yield", false).unwrap() } #[test_log::test] +fn sleep() { + run("sleep", false).unwrap() +} +#[test_log::test] fn stdio() { run("stdio", false).unwrap() } diff --git a/crates/test-programs/tests/wasi-preview2-components.rs b/crates/test-programs/tests/wasi-preview2-components.rs index 77a3e71ff6d8..ffcda698eeff 100644 --- a/crates/test-programs/tests/wasi-preview2-components.rs +++ b/crates/test-programs/tests/wasi-preview2-components.rs @@ -280,6 +280,10 @@ async fn sched_yield() { run("sched_yield", false).await.unwrap() } #[test_log::test(tokio::test(flavor = "multi_thread"))] +async fn sleep() { + run("sleep", false).await.unwrap() +} +#[test_log::test(tokio::test(flavor = "multi_thread"))] async fn stdio() { run("stdio", false).await.unwrap() } diff --git a/crates/test-programs/tests/wasi-tokio.rs b/crates/test-programs/tests/wasi-tokio.rs index 9f8390c917bd..ae7bc15c0388 100644 --- a/crates/test-programs/tests/wasi-tokio.rs +++ b/crates/test-programs/tests/wasi-tokio.rs @@ -256,6 +256,11 @@ async fn sched_yield() { run("sched_yield", true).await.unwrap() } #[test_log::test(tokio::test(flavor = "multi_thread"))] +#[should_panic] +async fn sleep() { + run("sleep", true).await.unwrap() +} +#[test_log::test(tokio::test(flavor = "multi_thread"))] async fn stdio() { run("stdio", true).await.unwrap() } diff --git a/crates/test-programs/wasi-tests/Cargo.toml b/crates/test-programs/wasi-tests/Cargo.toml index 1cf5c4949bcd..bf72d58ea313 100644 --- a/crates/test-programs/wasi-tests/Cargo.toml +++ b/crates/test-programs/wasi-tests/Cargo.toml @@ -9,3 +9,6 @@ publish = false libc = "0.2.65" wasi = "0.11.0" once_cell = "1.12" +wit-bindgen = { workspace = true, default-features = false, features = [ + "macros", +] } diff --git a/crates/test-programs/wasi-tests/src/bin/sleep.rs b/crates/test-programs/wasi-tests/src/bin/sleep.rs new file mode 100644 index 000000000000..a80f11bbff6a --- /dev/null +++ b/crates/test-programs/wasi-tests/src/bin/sleep.rs @@ -0,0 +1,16 @@ +use crate::wasi::{clocks::monotonic_clock, poll::poll}; + +wit_bindgen::generate!({ + path: "../../wasi/wit", + world: "wasmtime:wasi/command-extended", +}); + +fn main() { + // Sleep ten milliseconds. Note that we call the relevant host functions directly rather than go through + // libstd, since we want to ensure we're calling `monotonic_clock::subscribe` with an `absolute` parameter of + // `true`, which libstd won't necessarily do (but which e.g. CPython _will_ do). + poll::poll_oneoff(&[monotonic_clock::subscribe( + monotonic_clock::now() + 10_000_000, + true, + )]); +}