more scheduler
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
|
use crate::clocks::WasiSystemClock;
|
||||||
use crate::file::WasiFile;
|
use crate::file::WasiFile;
|
||||||
use crate::Error;
|
use crate::Error;
|
||||||
use cap_std::time::{SystemClock, SystemTime};
|
use cap_std::time::SystemTime;
|
||||||
use std::cell::Ref;
|
use std::cell::Ref;
|
||||||
pub mod subscription;
|
pub mod subscription;
|
||||||
|
|
||||||
@@ -9,7 +10,7 @@ use subscription::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub trait WasiSched {
|
pub trait WasiSched {
|
||||||
fn poll_oneoff(&self, subs: SubscriptionSet) -> Result<(), Error>;
|
fn poll_oneoff<'a>(&self, poll: &mut Poll<'a>) -> Result<(), Error>;
|
||||||
fn sched_yield(&self) -> Result<(), Error>;
|
fn sched_yield(&self) -> Result<(), Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -17,7 +18,7 @@ pub trait WasiSched {
|
|||||||
pub struct SyncSched {}
|
pub struct SyncSched {}
|
||||||
|
|
||||||
impl WasiSched for SyncSched {
|
impl WasiSched for SyncSched {
|
||||||
fn poll_oneoff(&self, subs: SubscriptionSet) -> Result<(), Error> {
|
fn poll_oneoff<'a>(&self, poll: &mut Poll<'a>) -> Result<(), Error> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
fn sched_yield(&self) -> Result<(), Error> {
|
fn sched_yield(&self) -> Result<(), Error> {
|
||||||
@@ -58,7 +59,7 @@ impl<'a> Poll<'a> {
|
|||||||
self.subs
|
self.subs
|
||||||
.push((Subscription::Read(RwSubscription::new(file)), ud));
|
.push((Subscription::Read(RwSubscription::new(file)), ud));
|
||||||
}
|
}
|
||||||
pub fn results(self, clock: &SystemClock) -> Vec<(SubscriptionResult, Userdata)> {
|
pub fn results(self, clock: &dyn WasiSystemClock) -> Vec<(SubscriptionResult, Userdata)> {
|
||||||
self.subs
|
self.subs
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|(s, ud)| SubscriptionResult::from_subscription(s, clock).map(|r| (r, ud)))
|
.filter_map(|(s, ud)| SubscriptionResult::from_subscription(s, clock).map(|r| (r, ud)))
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
|
use crate::clocks::WasiSystemClock;
|
||||||
use crate::file::WasiFile;
|
use crate::file::WasiFile;
|
||||||
use crate::Error;
|
use crate::Error;
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
use cap_std::time::{SystemClock, SystemTime};
|
use cap_std::time::{Duration, SystemTime};
|
||||||
use std::cell::{Cell, Ref};
|
use std::cell::{Cell, Ref};
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
@@ -38,8 +39,12 @@ pub struct TimerSubscription {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl TimerSubscription {
|
impl TimerSubscription {
|
||||||
pub fn result(&self, clock: &SystemClock) -> Option<Result<(), Error>> {
|
pub fn result(&self, clock: &dyn WasiSystemClock) -> Option<Result<(), Error>> {
|
||||||
if self.deadline.duration_since(clock.now()).is_ok() {
|
if self
|
||||||
|
.deadline
|
||||||
|
.duration_since(clock.now(Duration::from_secs(0)))
|
||||||
|
.is_ok()
|
||||||
|
{
|
||||||
Some(Ok(()))
|
Some(Ok(()))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@@ -82,7 +87,10 @@ pub enum SubscriptionResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl SubscriptionResult {
|
impl SubscriptionResult {
|
||||||
pub fn from_subscription(s: Subscription, clock: &SystemClock) -> Option<SubscriptionResult> {
|
pub fn from_subscription(
|
||||||
|
s: Subscription,
|
||||||
|
clock: &dyn WasiSystemClock,
|
||||||
|
) -> Option<SubscriptionResult> {
|
||||||
match s {
|
match s {
|
||||||
Subscription::Read(s) => s.result().map(SubscriptionResult::Read),
|
Subscription::Read(s) => s.result().map(SubscriptionResult::Read),
|
||||||
Subscription::Write(s) => s.result().map(SubscriptionResult::Write),
|
Subscription::Write(s) => s.result().map(SubscriptionResult::Write),
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#![allow(unused_variables)]
|
#![allow(unused_variables)]
|
||||||
use crate::dir::{DirCaps, DirEntry, DirFdStat, ReaddirCursor, ReaddirEntity, TableDirExt};
|
use crate::dir::{DirCaps, DirEntry, DirFdStat, ReaddirCursor, ReaddirEntity, TableDirExt};
|
||||||
use crate::file::{FdFlags, FdStat, FileCaps, FileEntry, FileType, Filestat, OFlags};
|
use crate::file::{FdFlags, FdStat, FileCaps, FileEntry, FileType, Filestat, OFlags};
|
||||||
|
use crate::sched::subscription::{RwEventFlags, SubscriptionResult};
|
||||||
|
use crate::sched::Poll;
|
||||||
use crate::{Error, WasiCtx};
|
use crate::{Error, WasiCtx};
|
||||||
use fs_set_times::SystemTimeSpec;
|
use fs_set_times::SystemTimeSpec;
|
||||||
use std::cell::{Ref, RefMut};
|
use std::cell::{Ref, RefMut};
|
||||||
@@ -886,8 +888,98 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
|
|||||||
events: &GuestPtr<types::Event>,
|
events: &GuestPtr<types::Event>,
|
||||||
nsubscriptions: types::Size,
|
nsubscriptions: types::Size,
|
||||||
) -> Result<types::Size, Error> {
|
) -> Result<types::Size, Error> {
|
||||||
self.sched.poll_oneoff(todo!())?;
|
let mut poll = Poll::new();
|
||||||
Ok(0)
|
|
||||||
|
let subs = subs.as_array(nsubscriptions);
|
||||||
|
for sub_elem in subs.iter() {
|
||||||
|
let sub_ptr = sub_elem?;
|
||||||
|
let sub = sub_ptr.read()?;
|
||||||
|
match sub.u {
|
||||||
|
types::SubscriptionU::Clock(clock) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
types::SubscriptionU::FdRead(read) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
types::SubscriptionU::FdWrite(write) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.sched.poll_oneoff(&mut poll)?;
|
||||||
|
|
||||||
|
let results = poll.results(self.clocks.system.deref());
|
||||||
|
let num_results = results.len();
|
||||||
|
assert!(
|
||||||
|
num_results <= nsubscriptions as usize,
|
||||||
|
"results exceeds subscriptions"
|
||||||
|
);
|
||||||
|
let events = events.as_array(
|
||||||
|
num_results
|
||||||
|
.try_into()
|
||||||
|
.expect("not greater than nsubscriptions"),
|
||||||
|
);
|
||||||
|
for ((result, userdata), event_elem) in results.into_iter().zip(events.iter()) {
|
||||||
|
let event_ptr = event_elem?;
|
||||||
|
let userdata: types::Userdata = userdata.into();
|
||||||
|
event_ptr.write(match result {
|
||||||
|
SubscriptionResult::Read(r) => {
|
||||||
|
let type_ = types::Eventtype::FdRead;
|
||||||
|
match r {
|
||||||
|
Ok((nbytes, flags)) => types::Event {
|
||||||
|
userdata,
|
||||||
|
error: types::Errno::Success,
|
||||||
|
type_,
|
||||||
|
fd_readwrite: types::EventFdReadwrite {
|
||||||
|
nbytes,
|
||||||
|
flags: types::Eventrwflags::from(&flags),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Err(e) => types::Event {
|
||||||
|
userdata,
|
||||||
|
error: e.try_into().expect("non-trapping"),
|
||||||
|
type_,
|
||||||
|
fd_readwrite: fd_readwrite_empty(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SubscriptionResult::Write(r) => {
|
||||||
|
let type_ = types::Eventtype::FdWrite;
|
||||||
|
match r {
|
||||||
|
Ok((nbytes, flags)) => types::Event {
|
||||||
|
userdata,
|
||||||
|
error: types::Errno::Success,
|
||||||
|
type_,
|
||||||
|
fd_readwrite: types::EventFdReadwrite {
|
||||||
|
nbytes,
|
||||||
|
flags: types::Eventrwflags::from(&flags),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Err(e) => types::Event {
|
||||||
|
userdata,
|
||||||
|
error: e.try_into().expect("non-trapping"),
|
||||||
|
type_,
|
||||||
|
fd_readwrite: fd_readwrite_empty(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SubscriptionResult::Timer(r) => {
|
||||||
|
let type_ = types::Eventtype::Clock;
|
||||||
|
types::Event {
|
||||||
|
userdata,
|
||||||
|
error: match r {
|
||||||
|
Ok(()) => types::Errno::Success,
|
||||||
|
Err(e) => e.try_into().expect("non-trapping"),
|
||||||
|
},
|
||||||
|
type_,
|
||||||
|
fd_readwrite: fd_readwrite_empty(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(num_results.try_into().expect("results fit into memory"))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn proc_exit(&self, status: types::Exitcode) -> wiggle::Trap {
|
fn proc_exit(&self, status: types::Exitcode) -> wiggle::Trap {
|
||||||
@@ -1319,3 +1411,20 @@ fn dirent_bytes(dirent: types::Dirent) -> Vec<u8> {
|
|||||||
unsafe { ptr.write_unaligned(dirent) };
|
unsafe { ptr.write_unaligned(dirent) };
|
||||||
bytes
|
bytes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<&RwEventFlags> for types::Eventrwflags {
|
||||||
|
fn from(flags: &RwEventFlags) -> types::Eventrwflags {
|
||||||
|
let mut out = types::Eventrwflags::empty();
|
||||||
|
if flags.contains(RwEventFlags::HANGUP) {
|
||||||
|
out = out | types::Eventrwflags::FD_READWRITE_HANGUP;
|
||||||
|
}
|
||||||
|
out
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fd_readwrite_empty() -> types::EventFdReadwrite {
|
||||||
|
types::EventFdReadwrite {
|
||||||
|
nbytes: 0,
|
||||||
|
flags: types::Eventrwflags::empty(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user