Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(recycling): add customizable recycling policies #33

Merged
merged 11 commits into from
Feb 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 27 additions & 21 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,36 @@
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
use core::{cmp, fmt, mem::MaybeUninit, ops, ptr};

#[macro_use]
mod macros;

mod loom;
mod recycle;
pub mod mpsc;
pub mod recycling;
mod util;
mod wait;

pub use self::recycling::Recycle;

#[cfg_attr(docsrs, doc = include_str!("../mpsc_perf_comparison.md"))]
pub mod mpsc_perf_comparison {
// Empty module, used only for documentation.
}

feature! {
#![not(all(loom, test))]
mod static_thingbuf;
pub use self::static_thingbuf::StaticThingBuf;
}

feature! {
#![feature = "alloc"]
extern crate alloc;

mod thingbuf;
pub use self::thingbuf::ThingBuf;

mod stringbuf;
pub use stringbuf::{StaticStringBuf, StringBuf};
}

pub mod mpsc;

mod static_thingbuf;
pub use self::static_thingbuf::StaticThingBuf;

use crate::{
loom::{
atomic::{AtomicUsize, Ordering::*},
Expand Down Expand Up @@ -97,7 +97,6 @@ impl Core {
closed,
idx_mask,
capacity,

has_dropped_slots: false,
}
}
Expand All @@ -116,7 +115,6 @@ impl Core {
gen_mask,
idx_mask,
capacity,

#[cfg(debug_assertions)]
has_dropped_slots: false,
}
Expand Down Expand Up @@ -155,12 +153,13 @@ impl Core {
}

#[inline(always)]
fn push_ref<'slots, T, S>(
fn push_ref<'slots, T, S, R>(
&self,
slots: &'slots S,
recycle: &R,
) -> Result<Ref<'slots, T>, mpsc::TrySendError<()>>
where
T: Default,
R: Recycle<T>,
S: ops::Index<usize, Output = Slot<T>> + ?Sized,
{
test_println!("push_ref");
Expand Down Expand Up @@ -190,13 +189,20 @@ impl Core {
// Claim exclusive ownership over the slot
let ptr = slot.value.get_mut();

if gen == 0 {
unsafe {
// Safety: we have just claimed exclusive ownership over
// this slot.
ptr.deref().write(T::default());
};
test_println!("-> initialized");
// Initialize or recycle the element.
unsafe {
// Safety: we have just claimed exclusive ownership over
// this slot.
let ptr = ptr.deref();
if gen == 0 {
ptr.write(recycle.new_element());
test_println!("-> initialized");
} else {
// Safety: if the generation is > 0, then the
// slot has already been initialized.
recycle.recycle(ptr.assume_init_mut());
test_println!("-> recycled");
}
}

return Ok(Ref {
Expand Down
10 changes: 10 additions & 0 deletions src/loom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,16 @@ mod inner {
Self::new(T::default())
}
}

impl<T: Clone> Clone for Track<T> {
fn clone(&self) -> Self {
Self::new(self.get_ref().clone())
}

fn clone_from(&mut self, source: &Self) {
self.get_mut().clone_from(source.get_ref());
}
}
}
}

Expand Down
15 changes: 8 additions & 7 deletions src/mpsc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

use crate::{
loom::{atomic::AtomicUsize, hint},
recycling::Recycle,
wait::{Notify, WaitCell, WaitQueue, WaitResult},
Core, Ref, Slot,
};
Expand Down Expand Up @@ -109,24 +110,25 @@ impl<N> ChannelCore<N>
where
N: Notify + Unpin,
{
fn try_send_ref<'a, T>(
fn try_send_ref<'a, T, R>(
&'a self,
slots: &'a [Slot<T>],
recycle: &R,
) -> Result<SendRefInner<'a, T, N>, TrySendError>
where
T: Default,
R: Recycle<T>,
{
self.core.push_ref(slots).map(|slot| SendRefInner {
self.core.push_ref(slots, recycle).map(|slot| SendRefInner {
_notify: NotifyRx(&self.rx_wait),
slot,
})
}

fn try_send<T>(&self, slots: &[Slot<T>], val: T) -> Result<(), TrySendError<T>>
fn try_send<T, R>(&self, slots: &[Slot<T>], val: T, recycle: &R) -> Result<(), TrySendError<T>>
where
T: Default,
R: Recycle<T>,
{
match self.try_send_ref(slots) {
match self.try_send_ref(slots, recycle) {
Ok(mut slot) => {
slot.with_mut(|slot| *slot = val);
Ok(())
Expand All @@ -147,7 +149,6 @@ where
) -> Poll<Option<Ref<'a, T>>>
where
S: Index<usize, Output = Slot<T>> + ?Sized,
T: Default,
{
macro_rules! try_poll_recv {
() => {
Expand Down
Loading