Skip to content

Commit

Permalink
[wasmtime-wasi] fix logic error in monotonic-clock/subscribe (#6993)
Browse files Browse the repository at this point in the history
* [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 <joel.dice@fermyon.com>

* 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 <joel.dice@fermyon.com>

---------

Signed-off-by: Joel Dice <joel.dice@fermyon.com>
  • Loading branch information
dicej committed Sep 11, 2023
1 parent 6084b73 commit 186c3ec
Show file tree
Hide file tree
Showing 9 changed files with 44 additions and 1 deletion.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions crates/test-programs/tests/wasi-cap-std-sync.rs
Expand Up @@ -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()
}
Expand Down
5 changes: 5 additions & 0 deletions crates/test-programs/tests/wasi-preview1-host-in-preview2.rs
Expand Up @@ -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()
}
Expand Down
4 changes: 4 additions & 0 deletions crates/test-programs/tests/wasi-preview2-components-sync.rs
Expand Up @@ -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()
}
Expand Down
4 changes: 4 additions & 0 deletions crates/test-programs/tests/wasi-preview2-components.rs
Expand Up @@ -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()
}
Expand Down
5 changes: 5 additions & 0 deletions crates/test-programs/tests/wasi-tokio.rs
Expand Up @@ -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()
}
Expand Down
3 changes: 3 additions & 0 deletions crates/test-programs/wasi-tests/Cargo.toml
Expand Up @@ -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",
] }
16 changes: 16 additions & 0 deletions 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,
)]);
}
2 changes: 1 addition & 1 deletion crates/wasi/src/preview2/host/clocks.rs
Expand Up @@ -64,7 +64,7 @@ impl<T: WasiView> 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)
};
Expand Down

0 comments on commit 186c3ec

Please sign in to comment.