Skip to content

Commit

Permalink
feat(async): add WaitCell (#158)
Browse files Browse the repository at this point in the history
This commit adds a `WaitCell` primitive to `mycelium-async`, which
stores a single waiter and notifies it.

Signed-off-by: Eliza Weisman <[email protected]>
  • Loading branch information
hawkw authored May 25, 2022
1 parent 7a3cede commit e9cd123
Show file tree
Hide file tree
Showing 10 changed files with 448 additions and 4 deletions.
51 changes: 51 additions & 0 deletions Cargo.lock

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

3 changes: 2 additions & 1 deletion async/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ features = ["attributes"]
git = "https://github.com/tokio-rs/tracing"

[target.'cfg(loom)'.dev-dependencies]
loom = "0.5.5"
loom = { version = "0.5.5", features = ["futures"] }
tracing_01 = { package = "tracing", version = "0.1", default_features = false, features = ["attributes"] }
tracing_subscriber_03 = { package = "tracing-subscriber", version = "0.3.11", features = ["fmt"] }
futures-util = "0.3"
3 changes: 2 additions & 1 deletion async/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
extern crate alloc;

#[macro_use]
mod util;
pub(crate) mod util;
pub(crate) mod loom;

pub mod scheduler;
pub mod task;
pub mod wait;
2 changes: 1 addition & 1 deletion async/src/loom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ pub(crate) use self::inner::*;

#[cfg(loom)]
mod inner {
pub use loom::{alloc, cell, hint, model, sync, thread};
pub use loom::{alloc, cell, future, hint, model, sync, thread};
}

#[cfg(not(loom))]
Expand Down
10 changes: 10 additions & 0 deletions async/src/task/task_list.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use super::Task;
use mycelium_util::{intrusive::list, sync::spin};
pub(crate) struct TaskList {
inner: spin::Mutex<Inner>,
}

struct Inner {
list: list::List<Task>,
closed: bool,
}
27 changes: 27 additions & 0 deletions async/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,33 @@ macro_rules! test_dbg {
};
}

#[cfg(not(test))]
macro_rules! test_trace {
($($args:tt)+) => {};
}

#[cfg(test)]
macro_rules! test_trace {
($($args:tt)+) => {
crate::util::tracing::debug!($($args)+);
};
}

macro_rules! fmt_bits {
($self: expr, $f: expr, $has_states: ident, $($name: ident),+) => {
$(
if $self.contains(Self::$name) {
if $has_states {
$f.write_str(" | ")?;
}
$f.write_str(stringify!($name))?;
$has_states = true;
}
)+

};
}

/// Helper to construct a `NonNull<T>` from a raw pointer to `T`, with null
/// checks elided in release mode.
#[cfg(debug_assertions)]
Expand Down
30 changes: 30 additions & 0 deletions async/src/wait.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//! Waiter cells and queues to allow tasks to wait for notifications.
//!
//! This module implements two types of structure for waiting: a [`WaitCell`],
//! which stores a *single* waiting task, and a wait *queue*, which
//! stores a queue of waiting tasks.
mod cell;
pub use cell::WaitCell;

use core::task::Poll;

/// An error indicating that a [`WaitCell`] or queue was closed while attempting
/// register a waiter.
#[derive(Clone, Debug)]
pub struct Closed(());

pub type WaitResult = Result<(), Closed>;

pub(in crate::wait) const fn closed() -> Poll<WaitResult> {
Poll::Ready(Err(Closed::new()))
}

pub(in crate::wait) const fn notified() -> Poll<WaitResult> {
Poll::Ready(Ok(()))
}

impl Closed {
pub(in crate::wait) const fn new() -> Self {
Self(())
}
}
Loading

0 comments on commit e9cd123

Please sign in to comment.