Skip to content

Commit

Permalink
WakerVecInner
Browse files Browse the repository at this point in the history
  • Loading branch information
matheus-consoli committed Mar 20, 2024
1 parent 42c5856 commit 194bdf2
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/utils/wakers/array/waker_array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::sync::{Mutex, MutexGuard};

use crate::utils::wakers::shared_arc::{waker_from_redirec_position, SharedArcContent};

use super::{InlineWakerArray, ReadinessArray};
use super::ReadinessArray;

/// A collection of wakers which delegate to an in-line waker.
pub(crate) struct WakerArray<const N: usize> {
Expand Down
1 change: 0 additions & 1 deletion src/utils/wakers/shared_arc.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use core::task::{RawWaker, RawWakerVTable, Waker};

use alloc::sync::Arc;
use bitvec::index;

pub(super) unsafe trait SharedArcContent {
/// Get the reference of the redirect slice
Expand Down
63 changes: 54 additions & 9 deletions src/utils/wakers/vec/waker_vec.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,32 @@
#[cfg(all(feature = "alloc", not(feature = "std")))]
use alloc::vec::Vec;

use alloc::sync::Arc;
use alloc::sync::{Arc, Weak};
use core::task::Waker;
use std::sync::{Mutex, MutexGuard};

use super::{InlineWakerVec, ReadinessVec};
use crate::utils::wakers::shared_arc::{waker_from_redirec_position, SharedArcContent};

use super::ReadinessVec;

/// A collection of wakers which delegate to an in-line waker.
pub(crate) struct WakerVec {
wakers: Vec<Waker>,
readiness: Arc<Mutex<ReadinessVec>>,
inner: Arc<WakerVecInner>,
}

struct WakerVecInner {
redirect: Mutex<Vec<WakerVecInnerPtr>>,
readiness: Mutex<ReadinessVec>,
}

#[derive(Clone, Copy)]
#[repr(transparent)]
struct WakerVecInnerPtr(*const WakerVecInner);

unsafe impl Send for WakerVecInnerPtr {}
unsafe impl Sync for WakerVecInnerPtr {}

impl Default for WakerVec {
fn default() -> Self {
Self::new(0)
Expand All @@ -22,11 +36,17 @@ impl Default for WakerVec {
impl WakerVec {
/// Create a new instance of `WakerVec`.
pub(crate) fn new(len: usize) -> Self {
let readiness = Arc::new(Mutex::new(ReadinessVec::new(len)));
let inner = Arc::new_cyclic(|weak| {
let raw = Weak::as_ptr(weak);
WakerVecInner {
redirect: Mutex::new(vec![WakerVecInnerPtr(raw); len]),
readiness: Mutex::new(ReadinessVec::new(len)),
}
});
let wakers = (0..len)
.map(|i| Arc::new(InlineWakerVec::new(i, readiness.clone())).into())
.map(|i| unsafe { waker_from_redirec_position(Arc::clone(&inner), i) })
.collect();
Self { wakers, readiness }
Self { wakers, inner }
}

pub(crate) fn get(&self, index: usize) -> Option<&Waker> {
Expand All @@ -35,7 +55,7 @@ impl WakerVec {

/// Access the `Readiness`.
pub(crate) fn readiness(&self) -> MutexGuard<'_, ReadinessVec> {
self.readiness.lock().unwrap()
self.inner.readiness.lock().unwrap()
}

/// Resize the `WakerVec` to the new size.
Expand All @@ -44,13 +64,38 @@ impl WakerVec {
// Which means the first position is the current length, and every position
// beyond that is incremented by 1.
let mut index = self.wakers.len();

let ptr = WakerVecInnerPtr(Arc::as_ptr(&self.inner));
let mut lock = self.inner.redirect.lock().unwrap();
lock.resize_with(len, || ptr);
drop(lock);

self.wakers.resize_with(len, || {
let ret = Arc::new(InlineWakerVec::new(index, self.readiness.clone())).into();
let ret = unsafe { waker_from_redirec_position(Arc::clone(&self.inner), index) };
index += 1;
ret
});

let mut readiness = self.readiness.lock().unwrap();
let mut readiness = self.inner.readiness.lock().unwrap();
readiness.resize(len);
}
}

unsafe impl SharedArcContent for WakerVecInner {
fn get_redirect_slice(&self) -> &[*const Self] {
let slice = self.redirect.lock().unwrap();
let slice = slice.as_slice();
unsafe { core::mem::transmute(slice) }
}

fn wake_index(&self, index: usize) {
let mut readiness = self.readiness.lock().unwrap();
if !readiness.set_ready(index) {
readiness
.parent_waker()
.as_ref()
.expect("msg") // todo message
.wake_by_ref()
}
}
}

0 comments on commit 194bdf2

Please sign in to comment.