-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(wasi): add support for
wasi:[email protected]
Signed-off-by: Roman Volosatovs <[email protected]>
- Loading branch information
1 parent
3ba676b
commit 3cd9340
Showing
21 changed files
with
364 additions
and
9 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -46,6 +46,7 @@ make_vendor "wasi/src/p2" " | |
" | ||
|
||
make_vendor "wasi/src/p3" " | ||
clocks@[email protected] | ||
random@[email protected] | ||
" | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
use core::future::Future as _; | ||
use core::pin::pin; | ||
use core::ptr; | ||
use core::task::{Context, Poll, RawWaker, RawWakerVTable, Waker}; | ||
|
||
use test_programs::wasi::clocks0_3_0::monotonic_clock; | ||
|
||
// Adapted from https://github.com/rust-lang/rust/blob/cd805f09ffbfa3896c8f50a619de9b67e1d9f3c3/library/core/src/task/wake.rs#L63-L77 | ||
// TODO: Replace by `Waker::noop` once MSRV is raised to 1.85 | ||
const NOOP_RAW_WAKER: RawWaker = { | ||
const VTABLE: RawWakerVTable = RawWakerVTable::new( | ||
// Cloning just returns a new no-op raw waker | ||
|_| NOOP_RAW_WAKER, | ||
// `wake` does nothing | ||
|_| {}, | ||
// `wake_by_ref` does nothing | ||
|_| {}, | ||
// Dropping does nothing as we don't allocate anything | ||
|_| {}, | ||
); | ||
RawWaker::new(ptr::null(), &VTABLE) | ||
}; | ||
|
||
const NOOP_WAKER: &'static Waker = &unsafe { Waker::from_raw(NOOP_RAW_WAKER) }; | ||
|
||
#[tokio::main(flavor = "current_thread")] | ||
async fn main() { | ||
sleep_10ms().await; | ||
sleep_0ms(); | ||
sleep_backwards_in_time(); | ||
} | ||
|
||
async fn sleep_10ms() { | ||
let dur = 10_000_000; | ||
monotonic_clock::wait_until(monotonic_clock::now() + dur).await; | ||
monotonic_clock::wait_for(dur).await; | ||
} | ||
|
||
fn sleep_0ms() { | ||
let mut cx = Context::from_waker(NOOP_WAKER); | ||
|
||
assert_eq!( | ||
pin!(monotonic_clock::wait_until(monotonic_clock::now())).poll(&mut cx), | ||
Poll::Ready(()), | ||
"waiting until now() is ready immediately", | ||
); | ||
assert_eq!( | ||
pin!(monotonic_clock::wait_for(0)).poll(&mut cx), | ||
Poll::Ready(()), | ||
"waiting for 0 is ready immediately", | ||
); | ||
} | ||
|
||
fn sleep_backwards_in_time() { | ||
let mut cx = Context::from_waker(NOOP_WAKER); | ||
|
||
assert_eq!( | ||
pin!(monotonic_clock::wait_until(monotonic_clock::now() - 1)).poll(&mut cx), | ||
Poll::Ready(()), | ||
"waiting until instant which has passed is ready immediately", | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,7 @@ wit_bindgen::generate!({ | |
include wasi:config/[email protected]; | ||
include wasi:keyvalue/[email protected]; | ||
include wasi:clocks/[email protected]; | ||
include wasi:random/[email protected]; | ||
} | ||
", | ||
|
@@ -24,6 +25,12 @@ wit_bindgen::generate!({ | |
], | ||
world: "wasmtime:test/test", | ||
features: ["cli-exit-with-code"], | ||
async: { | ||
imports: [ | ||
"wasi:clocks/[email protected]#wait-for", | ||
"wasi:clocks/[email protected]#wait-until", | ||
], | ||
}, | ||
generate_all, | ||
}); | ||
|
||
|
@@ -43,8 +50,8 @@ pub mod proxy { | |
"wasi:cli/[email protected]": crate::wasi::cli::stdout, | ||
"wasi:cli/[email protected]": crate::wasi::cli::stderr, | ||
"wasi:cli/[email protected]": crate::wasi::cli::stdin, | ||
"wasi:clocks/[email protected]": crate::wasi::clocks::monotonic_clock, | ||
"wasi:clocks/[email protected]": crate::wasi::clocks::wall_clock, | ||
"wasi:clocks/[email protected]": crate::wasi::clocks0_2_3::monotonic_clock, | ||
"wasi:clocks/[email protected]": crate::wasi::clocks0_2_3::wall_clock, | ||
}, | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,9 +24,10 @@ | |
//! inline: " | ||
//! package example:wasi; | ||
//! | ||
//! // An example of extending the `wasi:random/imports` world with a | ||
//! // An example of extending the `wasi:cli/command` world with a | ||
//! // custom host interface. | ||
//! world my-world { | ||
//! include wasi:clocks/[email protected]; | ||
//! include wasi:random/[email protected]; | ||
//! | ||
//! import custom-host; | ||
|
@@ -96,9 +97,10 @@ | |
/// inline: " | ||
/// package example:wasi; | ||
/// | ||
/// // An example of extending the `wasi:random/imports` world with a | ||
/// // An example of extending the `wasi:cli/command` world with a | ||
/// // custom host interface. | ||
/// world my-world { | ||
/// include wasi:clocks/[email protected]; | ||
/// include wasi:random/[email protected]; | ||
/// | ||
/// import custom-host; | ||
|
@@ -157,6 +159,7 @@ pub mod sync { | |
package inline:wasi; | ||
world command { | ||
include wasi:clocks/[email protected]; | ||
include wasi:random/[email protected]; | ||
} | ||
", | ||
|
@@ -166,6 +169,7 @@ pub mod sync { | |
// These interfaces come from the outer module, as it's | ||
// sync/async agnostic. | ||
"wasi:random": crate::p3::bindings::random, | ||
"wasi:clocks/wall-clock": crate::p3::bindings::clocks::wall_clock, | ||
}, | ||
require_store_data_send: true, | ||
}); | ||
|
@@ -324,6 +328,7 @@ mod async_io { | |
package inline:wasi; | ||
world command { | ||
include wasi:clocks/[email protected]; | ||
include wasi:random/[email protected]; | ||
} | ||
", | ||
|
@@ -338,6 +343,8 @@ mod async_io { | |
// which in theory can be shared across interfaces, so this may | ||
// need fancier syntax in the future. | ||
only_imports: [ | ||
"wait-for", | ||
"wait-until", | ||
], | ||
}, | ||
}); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
use crate::p3::bindings::{ | ||
clocks::monotonic_clock::{self, Duration as WasiDuration, Instant}, | ||
clocks::wall_clock::{self, Datetime}, | ||
}; | ||
use crate::{WasiImpl, WasiView}; | ||
use cap_std::time::SystemTime; | ||
use std::time::Duration; | ||
use tokio::time::sleep; | ||
|
||
mod sync; | ||
|
||
impl TryFrom<SystemTime> for Datetime { | ||
type Error = anyhow::Error; | ||
|
||
fn try_from(time: SystemTime) -> Result<Self, Self::Error> { | ||
let duration = | ||
time.duration_since(SystemTime::from_std(std::time::SystemTime::UNIX_EPOCH))?; | ||
|
||
Ok(Self { | ||
seconds: duration.as_secs(), | ||
nanoseconds: duration.subsec_nanos(), | ||
}) | ||
} | ||
} | ||
|
||
impl<T> wall_clock::Host for WasiImpl<T> | ||
where | ||
T: WasiView, | ||
{ | ||
fn now(&mut self) -> anyhow::Result<Datetime> { | ||
let now = self.ctx().wall_clock.now(); | ||
Ok(Datetime { | ||
seconds: now.as_secs(), | ||
nanoseconds: now.subsec_nanos(), | ||
}) | ||
} | ||
|
||
fn resolution(&mut self) -> anyhow::Result<Datetime> { | ||
let res = self.ctx().wall_clock.resolution(); | ||
Ok(Datetime { | ||
seconds: res.as_secs(), | ||
nanoseconds: res.subsec_nanos(), | ||
}) | ||
} | ||
} | ||
|
||
impl<T> monotonic_clock::Host for WasiImpl<T> | ||
where | ||
T: WasiView, | ||
{ | ||
fn now(&mut self) -> anyhow::Result<Instant> { | ||
Ok(self.ctx().monotonic_clock.now()) | ||
} | ||
|
||
fn resolution(&mut self) -> anyhow::Result<Instant> { | ||
Ok(self.ctx().monotonic_clock.resolution()) | ||
} | ||
|
||
async fn wait_until(&mut self, when: Instant) -> anyhow::Result<()> { | ||
let clock_now = self.ctx().monotonic_clock.now(); | ||
if when > clock_now { | ||
sleep(Duration::from_nanos(when - clock_now)).await; | ||
}; | ||
Ok(()) | ||
} | ||
|
||
async fn wait_for(&mut self, duration: WasiDuration) -> anyhow::Result<()> { | ||
if duration > 0 { | ||
sleep(Duration::from_nanos(duration)).await; | ||
} | ||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
use crate::p3::bindings::clocks as async_clocks; | ||
use crate::p3::bindings::sync::clocks as sync_clocks; | ||
use crate::p3::bindings::sync::clocks::monotonic_clock::{Duration, Instant}; | ||
use crate::runtime::in_tokio; | ||
use crate::{WasiImpl, WasiView}; | ||
|
||
impl<T> sync_clocks::monotonic_clock::Host for WasiImpl<T> | ||
where | ||
T: WasiView, | ||
{ | ||
fn now(&mut self) -> anyhow::Result<Instant> { | ||
async_clocks::monotonic_clock::Host::now(self) | ||
} | ||
|
||
fn resolution(&mut self) -> anyhow::Result<Instant> { | ||
async_clocks::monotonic_clock::Host::resolution(self) | ||
} | ||
|
||
fn wait_until(&mut self, when: Instant) -> anyhow::Result<()> { | ||
in_tokio(async_clocks::monotonic_clock::Host::wait_until(self, when)) | ||
} | ||
|
||
fn wait_for(&mut self, duration: Duration) -> anyhow::Result<()> { | ||
in_tokio(async_clocks::monotonic_clock::Host::wait_for( | ||
self, duration, | ||
)) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
mod clocks; | ||
mod random; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
45 changes: 45 additions & 0 deletions
45
crates/wasi/src/p3/wit/deps/clocks@[email protected]/monotonic-clock.wit
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package wasi:clocks@0.3.0; | ||
/// WASI Monotonic Clock is a clock API intended to let users measure elapsed | ||
/// time. | ||
/// | ||
/// It is intended to be portable at least between Unix-family platforms and | ||
/// Windows. | ||
/// | ||
/// A monotonic clock is a clock which has an unspecified initial value, and | ||
/// successive reads of the clock will produce non-decreasing values. | ||
@since(version = 0.3.0) | ||
interface monotonic-clock { | ||
/// An instant in time, in nanoseconds. An instant is relative to an | ||
/// unspecified initial value, and can only be compared to instances from | ||
/// the same monotonic-clock. | ||
@since(version = 0.3.0) | ||
type instant = u64; | ||
|
||
/// A duration of time, in nanoseconds. | ||
@since(version = 0.3.0) | ||
type duration = u64; | ||
|
||
/// Read the current value of the clock. | ||
/// | ||
/// The clock is monotonic, therefore calling this function repeatedly will | ||
/// produce a sequence of non-decreasing values. | ||
@since(version = 0.3.0) | ||
now: func() -> instant; | ||
|
||
/// Query the resolution of the clock. Returns the duration of time | ||
/// corresponding to a clock tick. | ||
@since(version = 0.3.0) | ||
resolution: func() -> duration; | ||
|
||
/// Wait until the specified instant has occurred. | ||
@since(version = 0.3.0) | ||
wait-until: func( | ||
when: instant, | ||
); | ||
|
||
/// Wait for the specified duration has elapsed. | ||
@since(version = 0.3.0) | ||
wait-for: func( | ||
how-long: duration, | ||
); | ||
} |
Oops, something went wrong.