Skip to content

Commit

Permalink
Remove the crossbeam-utils dependency
Browse files Browse the repository at this point in the history
Everything from that crate can either be inlined or ignored.

I also fix a bug with the list implementation as well.
  • Loading branch information
notgull committed Mar 31, 2023
1 parent 1188962 commit 5c83b86
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 16 deletions.
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ default = ["std"]
std = ["parking"]

[dependencies]
crossbeam-utils = { version = "0.8.12", default-features = false }
parking = { version = "2.0.0", optional = true }

[dev-dependencies]
Expand Down
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ impl Event {
// Notify if there is at least one unnotified listener and the number of notified
// listeners is less than `n`.
if inner.notified.load(Ordering::Acquire) < n {
inner.notify(n, false);
inner.notify(n, false);
}
}
}
Expand Down Expand Up @@ -435,7 +435,7 @@ impl Event {
if let Some(inner) = self.try_inner() {
// Notify if there is at least one unnotified listener.
if inner.notified.load(Ordering::Acquire) < usize::MAX {
inner.notify(n, true);
inner.notify(n, true);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ impl ListenerSlab {
_ => return None,
};

let entry = self.listeners.remove(key.get());
let entry = &self.listeners[key.get()];
let prev = entry.prev().get();
let next = entry.next().get();

Expand Down
50 changes: 44 additions & 6 deletions src/list/node.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
//! The node that makes up queues.

use crate::list::{Listener, ListenerSlab};
use crate::sync::atomic::{AtomicUsize, Ordering};
use crate::sync::atomic::{AtomicPtr, AtomicUsize, Ordering};
use crate::sync::Arc;
use crate::{State, Task};

use alloc::boxed::Box;

use core::num::NonZeroUsize;
use crossbeam_utils::atomic::AtomicCell;
use core::ptr;

/// A node in the backup queue.
pub(crate) enum Node {
Expand Down Expand Up @@ -42,7 +44,7 @@ pub(crate) enum Node {

pub(crate) struct TaskWaiting {
/// The task that is being waited on.
task: AtomicCell<Option<Task>>,
task: AtomicCell<Task>,

/// The ID of the new entry.
///
Expand All @@ -54,7 +56,7 @@ impl Node {
pub(crate) fn listener() -> (Self, Arc<TaskWaiting>) {
// Create a new `TaskWaiting` structure.
let task_waiting = Arc::new(TaskWaiting {
task: AtomicCell::new(None),
task: AtomicCell::new(),
entry_id: AtomicUsize::new(0),
});

Expand All @@ -75,7 +77,7 @@ impl Node {

// Send the new key to the listener and wake it if necessary.
task_waiting.entry_id.store(key.get(), Ordering::Release);
return task_waiting.task.take();
return task_waiting.task.take().map(|t| *t);
}
Node::Notify { count, additional } => {
// Notify the listener.
Expand Down Expand Up @@ -108,7 +110,7 @@ impl TaskWaiting {
/// Register a listener.
pub(crate) fn register(&self, task: Task) {
// Set the task.
if let Some(task) = self.task.swap(Some(task)) {
if let Some(task) = self.task.replace(Some(Box::new(task))) {
task.wake();
}

Expand All @@ -119,3 +121,39 @@ impl TaskWaiting {
}
}
}

/// A shared pointer to a value.
///
/// The inner value is a `Box<T>`.
#[derive(Debug)]
struct AtomicCell<T>(AtomicPtr<T>);

impl<T> AtomicCell<T> {
/// Create a new `AtomicCell`.
fn new() -> Self {
Self(AtomicPtr::new(ptr::null_mut()))
}

/// Swap the value out.
fn replace(&self, value: Option<Box<T>>) -> Option<Box<T>> {
let value = value.map_or(ptr::null_mut(), |value| Box::into_raw(value));
let old_value = self.0.swap(value, Ordering::SeqCst);

if old_value.is_null() {
None
} else {
Some(unsafe { Box::from_raw(old_value) })
}
}

/// Take the value out.
fn take(&self) -> Option<Box<T>> {
self.replace(None)
}
}

impl<T> Drop for AtomicCell<T> {
fn drop(&mut self) {
self.take();
}
}
10 changes: 4 additions & 6 deletions src/list/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,16 @@
use super::node::Node;
use crate::sync::atomic::{AtomicPtr, Ordering};

use crossbeam_utils::CachePadded;

use alloc::boxed::Box;
use core::ptr;

/// A queue of nodes.
pub(crate) struct Queue {
/// The head of the queue.
head: CachePadded<AtomicPtr<QueueNode>>,
head: AtomicPtr<QueueNode>,

/// The tail of the queue.
tail: CachePadded<AtomicPtr<QueueNode>>,
tail: AtomicPtr<QueueNode>,
}

/// A single node in the `Queue`.
Expand All @@ -30,8 +28,8 @@ impl Queue {
/// Create a new queue.
pub(crate) fn new() -> Self {
Self {
head: CachePadded::new(AtomicPtr::new(ptr::null_mut())),
tail: CachePadded::new(AtomicPtr::new(ptr::null_mut())),
head: AtomicPtr::new(ptr::null_mut()),
tail: AtomicPtr::new(ptr::null_mut()),
}
}

Expand Down

0 comments on commit 5c83b86

Please sign in to comment.