Add a sleep function to the WasiSched trait.

This commit is contained in:
Dan Gohman
2021-03-22 11:23:45 -07:00
parent dd7e16762c
commit 2880dab8f8
5 changed files with 32 additions and 2 deletions

View File

@@ -108,6 +108,9 @@ impl WasiSched for SyncSched {
std::thread::yield_now(); std::thread::yield_now();
Ok(()) Ok(())
} }
fn sleep(&self, duration: Duration) {
std::thread::sleep(duration)
}
} }
fn wasi_file_raw_fd(f: &dyn WasiFile) -> Option<RawFd> { fn wasi_file_raw_fd(f: &dyn WasiFile) -> Option<RawFd> {

View File

@@ -128,6 +128,9 @@ impl WasiSched for SyncSched {
thread::yield_now(); thread::yield_now();
Ok(()) Ok(())
} }
fn sleep(&self, duration: Duration) {
std::thread::sleep(duration)
}
} }
fn wasi_file_raw_handle(f: &dyn WasiFile) -> Option<RawHandle> { fn wasi_file_raw_handle(f: &dyn WasiFile) -> Option<RawHandle> {

View File

@@ -10,6 +10,7 @@ use subscription::{MonotonicClockSubscription, RwSubscription, Subscription, Sub
pub trait WasiSched { pub trait WasiSched {
fn poll_oneoff(&self, poll: &Poll) -> Result<(), Error>; fn poll_oneoff(&self, poll: &Poll) -> Result<(), Error>;
fn sched_yield(&self) -> Result<(), Error>; fn sched_yield(&self) -> Result<(), Error>;
fn sleep(&self, duration: Duration);
} }
pub struct Userdata(u64); pub struct Userdata(u64);

View File

@@ -738,6 +738,30 @@ impl<'a> wasi_unstable::WasiUnstable for WasiCtx {
return Err(Error::invalid_argument().context("nsubscriptions must be nonzero")); return Err(Error::invalid_argument().context("nsubscriptions must be nonzero"));
} }
// Special-case a `poll_oneoff` which is just sleeping on a single
// relative timer event, such as what WASI libc uses to implement sleep
// functions. This supports all clock IDs, because POSIX says that
// `clock_settime` doesn't effect relative sleeps.
if nsubscriptions == 1 {
let sub = subs.read()?;
if let types::SubscriptionU::Clock(clocksub) = sub.u {
if !clocksub
.flags
.contains(types::Subclockflags::SUBSCRIPTION_CLOCK_ABSTIME)
{
self.sched.sleep(Duration::from_nanos(clocksub.timeout));
events.write(types::Event {
userdata: sub.userdata,
error: types::Errno::Success,
type_: types::Eventtype::Clock,
fd_readwrite: fd_readwrite_empty(),
})?;
return Ok(1);
}
}
}
let table = self.table(); let table = self.table();
let mut poll = Poll::new(); let mut poll = Poll::new();

View File

@@ -16,7 +16,6 @@ use std::cell::{Ref, RefMut};
use std::convert::{TryFrom, TryInto}; use std::convert::{TryFrom, TryInto};
use std::io::{IoSlice, IoSliceMut}; use std::io::{IoSlice, IoSliceMut};
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
use std::thread;
use tracing::debug; use tracing::debug;
use wiggle::GuestPtr; use wiggle::GuestPtr;
@@ -921,7 +920,7 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
.flags .flags
.contains(types::Subclockflags::SUBSCRIPTION_CLOCK_ABSTIME) .contains(types::Subclockflags::SUBSCRIPTION_CLOCK_ABSTIME)
{ {
thread::sleep(Duration::from_nanos(clocksub.timeout)); self.sched.sleep(Duration::from_nanos(clocksub.timeout));
events.write(types::Event { events.write(types::Event {
userdata: sub.userdata, userdata: sub.userdata,