Skip to content

Commit

Permalink
High-level module reorganization
Browse files Browse the repository at this point in the history
- Renames "list.rs" and the "list" folder to "no_std"
- Uses `no_std` as the `sys` module in preparation for the `std` module
- Inlines `sync.rs` into `lib.rs`
  • Loading branch information
notgull committed Mar 31, 2023
1 parent 5c83b86 commit 0c76968
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 93 deletions.
190 changes: 107 additions & 83 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ extern crate alloc;
#[cfg(feature = "std")]
extern crate std;

mod list;
mod sync;
#[path = "no_std.rs"]
mod sys;

use alloc::sync::Arc;

Expand All @@ -88,83 +88,6 @@ use std::panic::{RefUnwindSafe, UnwindSafe};
#[cfg(feature = "std")]
use std::time::{Duration, Instant};

#[cfg(feature = "std")]
use parking::Unparker;

/// An asynchronous waker or thread unparker that can be used to notify a task or thread.
#[derive(Debug)]
enum Task {
/// A waker that can be used to notify a task.
Waker(Waker),

/// An unparker that can be used to notify a thread.
#[cfg(feature = "std")]
Thread(Unparker),
}

impl Task {
fn as_task_ref(&self) -> TaskRef<'_> {
match self {
Self::Waker(waker) => TaskRef::Waker(waker),
#[cfg(feature = "std")]
Self::Thread(unparker) => TaskRef::Unparker(unparker),
}
}

/// Notifies the task or thread.
fn wake(self) {
match self {
Task::Waker(waker) => waker.wake(),
#[cfg(feature = "std")]
Task::Thread(unparker) => {
unparker.unpark();
}
}
}
}

impl PartialEq for Task {
fn eq(&self, other: &Self) -> bool {
self.as_task_ref().will_wake(other.as_task_ref())
}
}

/// A reference to a task.
#[derive(Debug, Clone, Copy)]
enum TaskRef<'a> {
/// A waker that wakes up a future.
Waker(&'a Waker),

/// An unparker that wakes up a thread.
#[cfg(feature = "std")]
Unparker(&'a parking::Unparker),
}

impl TaskRef<'_> {
/// Tells if this task will wake up the other task.
fn will_wake(self, other: Self) -> bool {
match (self, other) {
(Self::Waker(a), Self::Waker(b)) => a.will_wake(b),
#[cfg(feature = "std")]
(Self::Unparker(_), Self::Unparker(_)) => {
// TODO: Use unreleased will_unpark API.
false
}
#[cfg(feature = "std")]
_ => false,
}
}

/// Converts this task reference to a task by cloning.
fn into_task(self) -> Task {
match self {
Self::Waker(waker) => Task::Waker(waker.clone()),
#[cfg(feature = "std")]
Self::Unparker(unparker) => Task::Thread(unparker.clone()),
}
}
}

/// Inner state of [`Event`].
struct Inner {
/// The number of notified entries, or `usize::MAX` if all of them have been notified.
Expand All @@ -173,15 +96,15 @@ struct Inner {
notified: AtomicUsize,

/// Inner queue of event listeners.
list: list::List,
list: sys::List,
}

impl Inner {
/// Create a new `Inner`.
fn new() -> Self {
Self {
notified: AtomicUsize::new(core::usize::MAX),
list: list::List::new(),
list: sys::List::new(),
}
}
}
Expand Down Expand Up @@ -255,7 +178,7 @@ impl Event {
// Register the listener.
let mut listener = EventListener {
inner: unsafe { Arc::clone(&ManuallyDrop::new(Arc::from_raw(inner))) },
state: list::Listener::Discarded,
state: sys::Listener::Discarded,
};

listener.inner.insert(&mut listener.state);
Expand Down Expand Up @@ -525,7 +448,7 @@ pub struct EventListener {
inner: Arc<Inner>,

/// The current state of the listener.
state: list::Listener,
state: sys::Listener,
}

#[cfg(feature = "std")]
Expand Down Expand Up @@ -784,6 +707,80 @@ impl State {
}
}

/// An asynchronous waker or thread unparker that can be used to notify a task or thread.
#[derive(Debug)]
enum Task {
/// A waker that can be used to notify a task.
Waker(Waker),

/// An unparker that can be used to notify a thread.
#[cfg(feature = "std")]
Unparker(parking::Unparker),
}

impl Task {
fn as_task_ref(&self) -> TaskRef<'_> {
match self {
Self::Waker(waker) => TaskRef::Waker(waker),
#[cfg(feature = "std")]
Self::Unparker(unparker) => TaskRef::Unparker(unparker),
}
}

/// Notifies the task or thread.
fn wake(self) {
match self {
Task::Waker(waker) => waker.wake(),
#[cfg(feature = "std")]
Task::Unparker(unparker) => {
unparker.unpark();
}
}
}
}

impl PartialEq for Task {
fn eq(&self, other: &Self) -> bool {
self.as_task_ref().will_wake(other.as_task_ref())
}
}

/// A reference to a task.
#[derive(Debug, Clone, Copy)]
enum TaskRef<'a> {
/// A waker that wakes up a future.
Waker(&'a Waker),

/// An unparker that wakes up a thread.
#[cfg(feature = "std")]
Unparker(&'a parking::Unparker),
}

impl TaskRef<'_> {
/// Tells if this task will wake up the other task.
fn will_wake(self, other: Self) -> bool {
match (self, other) {
(Self::Waker(a), Self::Waker(b)) => a.will_wake(b),
#[cfg(feature = "std")]
(Self::Unparker(_), Self::Unparker(_)) => {
// TODO: Use unreleased will_unpark API.
false
}
#[cfg(feature = "std")]
_ => false,
}
}

/// Converts this task reference to a task by cloning.
fn into_task(self) -> Task {
match self {
Self::Waker(waker) => Task::Waker(waker.clone()),
#[cfg(feature = "std")]
Self::Unparker(unparker) => Task::Unparker(unparker.clone()),
}
}
}

/// Equivalent to `atomic::fence(Ordering::SeqCst)`, but in some cases faster.
#[inline]
fn full_fence() {
Expand Down Expand Up @@ -811,3 +808,30 @@ fn full_fence() {
atomic::fence(Ordering::SeqCst);
}
}

/// Synchronization primitive implementation.
mod sync {
pub(super) use alloc::sync::Arc;
pub(super) use core::cell;
pub(super) use core::sync::atomic;

pub(super) trait WithMut {
type Output;

fn with_mut<F, R>(&mut self, f: F) -> R
where
F: FnOnce(&mut Self::Output) -> R;
}

impl<T> WithMut for atomic::AtomicPtr<T> {
type Output = *mut T;

#[inline]
fn with_mut<F, R>(&mut self, f: F) -> R
where
F: FnOnce(&mut Self::Output) -> R,
{
f(self.get_mut())
}
}
}
4 changes: 2 additions & 2 deletions src/list.rs → src/no_std.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
//! The inner list of listeners.

#[path = "list/node.rs"]
#[path = "no_std/node.rs"]
mod node;

#[path = "list/queue.rs"]
#[path = "no_std/queue.rs"]
mod queue;

use node::{Node, TaskWaiting};
Expand Down
2 changes: 1 addition & 1 deletion src/list/node.rs → src/no_std/node.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! The node that makes up queues.

use crate::list::{Listener, ListenerSlab};
use super::{Listener, ListenerSlab};
use crate::sync::atomic::{AtomicPtr, AtomicUsize, Ordering};
use crate::sync::Arc;
use crate::{State, Task};
Expand Down
File renamed without changes.
7 changes: 0 additions & 7 deletions src/sync.rs

This file was deleted.

0 comments on commit 0c76968

Please sign in to comment.