Skip to content

Commit

Permalink
Remove resource abstraction from clocks (bytecodealliance#129)
Browse files Browse the repository at this point in the history
* wit: remove resource index from monotonic-clocks and wall-clocks, delete instance-*-clock interfaces

At this time, we don't have use cases for providing multiple wall clocks
or multiple monotonic clocks to the same component. So, according to the
principle of following preview 1's design as close as possible, we are
changing these interfaces to being provided by ambient functions, rather
than methods on a resource.

* adapter: unresourcify clocks

* host: de-resourcify clocks
  • Loading branch information
pchickey committed Apr 4, 2023
1 parent b2792b9 commit 146f576
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 169 deletions.
61 changes: 12 additions & 49 deletions host/src/clocks.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
#![allow(unused_variables)]

use crate::command::wasi::{
instance_monotonic_clock, instance_wall_clock,
monotonic_clock::{self, Instant, MonotonicClock},
monotonic_clock::{self, Instant},
poll::Pollable,
timezone::{self, Timezone, TimezoneDisplay},
wall_clock::{self, Datetime, WallClock},
wall_clock::{self, Datetime},
};
use crate::poll::PollableEntry;
use crate::WasiCtx;
use cap_std::time::SystemTime;
use wasi_common::clocks::{TableMonotonicClockExt, TableWallClockExt};

impl TryFrom<SystemTime> for Datetime {
type Error = anyhow::Error;
Expand All @@ -26,74 +24,39 @@ impl TryFrom<SystemTime> for Datetime {
}
}

#[async_trait::async_trait]
impl instance_wall_clock::Host for WasiCtx {
async fn instance_wall_clock(&mut self) -> anyhow::Result<WallClock> {
// Create a new handle to the default wall clock.
let new = self.clocks.instance_wall_clock.dup();
Ok(self.table_mut().push(Box::new(new))?)
}
}

#[async_trait::async_trait]
impl instance_monotonic_clock::Host for WasiCtx {
async fn instance_monotonic_clock(&mut self) -> anyhow::Result<MonotonicClock> {
// Create a new handle to the default monotonic clock.
let new = self.clocks.instance_monotonic_clock.dup();
Ok(self.table_mut().push(Box::new(new))?)
}
}

#[async_trait::async_trait]
impl wall_clock::Host for WasiCtx {
async fn now(&mut self, fd: WallClock) -> anyhow::Result<Datetime> {
let clock = self.table().get_wall_clock(fd)?;
let now = clock.now();
async fn now(&mut self) -> anyhow::Result<Datetime> {
let now = self.clocks.wall.now();
Ok(Datetime {
seconds: now.as_secs(),
nanoseconds: now.subsec_nanos(),
})
}

async fn resolution(&mut self, fd: WallClock) -> anyhow::Result<Datetime> {
let clock = self.table().get_wall_clock(fd)?;
let res = clock.resolution();
async fn resolution(&mut self) -> anyhow::Result<Datetime> {
let res = self.clocks.wall.resolution();
Ok(Datetime {
seconds: res.as_secs(),
nanoseconds: res.subsec_nanos(),
})
}

async fn drop_wall_clock(&mut self, clock: WallClock) -> anyhow::Result<()> {
Ok(self.table_mut().delete_wall_clock(clock)?)
}
}

#[async_trait::async_trait]
impl monotonic_clock::Host for WasiCtx {
async fn now(&mut self, fd: MonotonicClock) -> anyhow::Result<Instant> {
Ok(self.table().get_monotonic_clock(fd)?.now())
async fn now(&mut self) -> anyhow::Result<Instant> {
Ok(self.clocks.monotonic.now())
}

async fn resolution(&mut self, fd: MonotonicClock) -> anyhow::Result<Instant> {
Ok(self.table().get_monotonic_clock(fd)?.now())
async fn resolution(&mut self) -> anyhow::Result<Instant> {
Ok(self.clocks.monotonic.resolution())
}

async fn drop_monotonic_clock(&mut self, clock: MonotonicClock) -> anyhow::Result<()> {
Ok(self.table_mut().delete_monotonic_clock(clock)?)
}

async fn subscribe(
&mut self,
clock: MonotonicClock,
when: Instant,
absolute: bool,
) -> anyhow::Result<Pollable> {
async fn subscribe(&mut self, when: Instant, absolute: bool) -> anyhow::Result<Pollable> {
Ok(self
.table_mut()
.push(Box::new(PollableEntry::MonotonicClock(
clock, when, absolute,
)))?)
.push(Box::new(PollableEntry::MonotonicClock(when, absolute)))?)
}
}

Expand Down
2 changes: 0 additions & 2 deletions host/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ pub fn add_to_linker<T: Send>(
wasi::wall_clock::add_to_linker(l, f)?;
wasi::monotonic_clock::add_to_linker(l, f)?;
wasi::timezone::add_to_linker(l, f)?;
wasi::instance_monotonic_clock::add_to_linker(l, f)?;
wasi::instance_wall_clock::add_to_linker(l, f)?;
wasi::filesystem::add_to_linker(l, f)?;
wasi::poll::add_to_linker(l, f)?;
wasi::streams::add_to_linker(l, f)?;
Expand Down
10 changes: 4 additions & 6 deletions host/src/poll.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use crate::{
command,
command::wasi::monotonic_clock::{Instant, MonotonicClock},
command::wasi::monotonic_clock::Instant,
command::wasi::poll::Pollable,
command::wasi::streams::{InputStream, OutputStream, StreamError},
command::wasi::tcp::TcpSocket,
proxy, WasiCtx,
};
use wasi_common::clocks::TableMonotonicClockExt;
use wasi_common::stream::TableStreamExt;
use wasi_common::tcp_socket::TableTcpSocketExt;

Expand All @@ -26,7 +25,7 @@ pub(crate) enum PollableEntry {
/// Poll for write events.
Write(OutputStream),
/// Poll for a monotonic-clock timer.
MonotonicClock(MonotonicClock, Instant, bool),
MonotonicClock(Instant, bool),
/// Poll for a tcp-socket.
TcpSocket(TcpSocket),
}
Expand Down Expand Up @@ -58,9 +57,8 @@ async fn poll_oneoff(ctx: &mut WasiCtx, futures: Vec<Pollable>) -> anyhow::Resul
ctx.table().get_output_stream(stream).map_err(convert)?;
poll.subscribe_write(wasi_stream, userdata);
}
PollableEntry::MonotonicClock(clock, when, absolute) => {
let wasi_clock = ctx.table().get_monotonic_clock(clock).map_err(convert)?;
poll.subscribe_monotonic_clock(wasi_clock, when, absolute, userdata);
PollableEntry::MonotonicClock(when, absolute) => {
poll.subscribe_monotonic_clock(&*ctx.clocks.monotonic, when, absolute, userdata);
}
PollableEntry::TcpSocket(tcp_socket) => {
let wasi_tcp_socket: &dyn wasi_common::WasiTcpSocket =
Expand Down
16 changes: 2 additions & 14 deletions host/tests/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,6 @@ async fn run_time(mut store: Store<WasiCtx>, wasi: Command) -> Result<()> {
fn now(&self) -> Duration {
Duration::new(1431648000, 100)
}

fn dup(&self) -> Box<dyn WasiWallClock + Send + Sync> {
Box::new(Self)
}
}

struct FakeMonotonicClock {
Expand All @@ -148,18 +144,10 @@ async fn run_time(mut store: Store<WasiCtx>, wasi: Command) -> Result<()> {
*now += 42 * 1_000_000_000;
then
}

fn dup(&self) -> Box<dyn WasiMonotonicClock + Send + Sync> {
let now = *self.now.lock().unwrap();
Box::new(Self {
now: Mutex::new(now),
})
}
}

store.data_mut().clocks.instance_wall_clock = Box::new(FakeWallClock);
store.data_mut().clocks.instance_monotonic_clock =
Box::new(FakeMonotonicClock { now: Mutex::new(0) });
store.data_mut().clocks.wall = Box::new(FakeWallClock);
store.data_mut().clocks.monotonic = Box::new(FakeMonotonicClock { now: Mutex::new(0) });

wasi.call_run(&mut store)
.await?
Expand Down
41 changes: 4 additions & 37 deletions wasi-common/cap-std-sync/src/clocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,12 @@ use wasi_common::clocks::{WasiClocks, WasiMonotonicClock, WasiWallClock};
pub struct WallClock {
/// The underlying system clock.
clock: cap_std::time::SystemClock,

/// The ambient authority used to create this `WallClock` and
/// which we use to create clones of it.
ambient_authority: AmbientAuthority,
}

impl WallClock {
pub fn new(ambient_authority: AmbientAuthority) -> Self {
Self {
clock: cap_std::time::SystemClock::new(ambient_authority),
ambient_authority,
}
}
}
Expand All @@ -33,14 +28,6 @@ impl WasiWallClock for WallClock {
.duration_since(SystemClock::UNIX_EPOCH)
.unwrap()
}

fn dup(&self) -> Box<dyn WasiWallClock + Send + Sync> {
let clock = cap_std::time::SystemClock::new(self.ambient_authority);
Box::new(Self {
clock,
ambient_authority: self.ambient_authority,
})
}
}

pub struct MonotonicClock {
Expand All @@ -50,21 +37,13 @@ pub struct MonotonicClock {
/// The `Instant` this clock was created. All returned times are
/// durations since that time.
initial: Instant,

/// The ambient authority used to create this `MonotonicClock` and
/// which we use to create clones of it.
ambient_authority: AmbientAuthority,
}

impl MonotonicClock {
pub fn new(ambient_authority: AmbientAuthority) -> Self {
let clock = cap_std::time::MonotonicClock::new(ambient_authority);
let initial = clock.now();
Self {
clock,
initial,
ambient_authority,
}
Self { clock, initial }
}
}

Expand All @@ -83,24 +62,12 @@ impl WasiMonotonicClock for MonotonicClock {
.try_into()
.unwrap()
}

fn dup(&self) -> Box<dyn WasiMonotonicClock + Send + Sync> {
let clock = cap_std::time::MonotonicClock::new(self.ambient_authority);
Box::new(Self {
clock,
initial: self.initial,
ambient_authority: self.ambient_authority,
})
}
}

pub fn clocks_ctx() -> WasiClocks {
// Create the per-instance clock resources.
let instance_monotonic_clock = Box::new(MonotonicClock::new(ambient_authority()));
let instance_wall_clock = Box::new(WallClock::new(ambient_authority()));
let monotonic = Box::new(MonotonicClock::new(ambient_authority()));
let wall = Box::new(WallClock::new(ambient_authority()));

WasiClocks {
instance_monotonic_clock,
instance_wall_clock,
}
WasiClocks { monotonic, wall }
}
63 changes: 2 additions & 61 deletions wasi-common/src/clocks.rs
Original file line number Diff line number Diff line change
@@ -1,75 +1,16 @@
use crate::Error;
use cap_std::time::Duration;

pub trait WasiWallClock: Send + Sync {
fn resolution(&self) -> Duration;
fn now(&self) -> Duration;
fn dup(&self) -> Box<dyn WasiWallClock + Send + Sync>;
}

pub trait WasiMonotonicClock: Send + Sync {
fn resolution(&self) -> u64;
fn now(&self) -> u64;
fn dup(&self) -> Box<dyn WasiMonotonicClock + Send + Sync>;
}

pub struct WasiClocks {
pub instance_wall_clock: Box<dyn WasiWallClock + Send + Sync>,
pub instance_monotonic_clock: Box<dyn WasiMonotonicClock + Send + Sync>,
}

pub trait TableWallClockExt {
fn get_wall_clock(&self, fd: u32) -> Result<&(dyn WasiWallClock + Send + Sync), Error>;
fn get_wall_clock_mut(
&mut self,
fd: u32,
) -> Result<&mut Box<dyn WasiWallClock + Send + Sync>, Error>;
fn delete_wall_clock(&mut self, fd: u32) -> Result<(), Error>;
}
impl TableWallClockExt for crate::table::Table {
fn get_wall_clock(&self, fd: u32) -> Result<&(dyn WasiWallClock + Send + Sync), Error> {
self.get::<Box<dyn WasiWallClock + Send + Sync>>(fd)
.map(|f| f.as_ref())
}
fn get_wall_clock_mut(
&mut self,
fd: u32,
) -> Result<&mut Box<dyn WasiWallClock + Send + Sync>, Error> {
self.get_mut::<Box<dyn WasiWallClock + Send + Sync>>(fd)
}
fn delete_wall_clock(&mut self, fd: u32) -> Result<(), Error> {
self.delete::<Box<dyn WasiWallClock + Send + Sync>>(fd)
.map(|_old| ())
}
}

pub trait TableMonotonicClockExt {
fn get_monotonic_clock(
&self,
fd: u32,
) -> Result<&(dyn WasiMonotonicClock + Send + Sync), Error>;
fn get_monotonic_clock_mut(
&mut self,
fd: u32,
) -> Result<&mut Box<dyn WasiMonotonicClock + Send + Sync>, Error>;
fn delete_monotonic_clock(&mut self, fd: u32) -> Result<(), Error>;
}
impl TableMonotonicClockExt for crate::table::Table {
fn get_monotonic_clock(
&self,
fd: u32,
) -> Result<&(dyn WasiMonotonicClock + Send + Sync), Error> {
self.get::<Box<dyn WasiMonotonicClock + Send + Sync>>(fd)
.map(|f| f.as_ref())
}
fn get_monotonic_clock_mut(
&mut self,
fd: u32,
) -> Result<&mut Box<dyn WasiMonotonicClock + Send + Sync>, Error> {
self.get_mut::<Box<dyn WasiMonotonicClock + Send + Sync>>(fd)
}
fn delete_monotonic_clock(&mut self, fd: u32) -> Result<(), Error> {
self.delete::<Box<dyn WasiMonotonicClock + Send + Sync>>(fd)
.map(|_old| ())
}
pub wall: Box<dyn WasiWallClock + Send + Sync>,
pub monotonic: Box<dyn WasiMonotonicClock + Send + Sync>,
}

0 comments on commit 146f576

Please sign in to comment.