mirror of
https://github.com/rtic-rs/rtic.git
synced 2024-11-25 21:19:35 +01:00
rtic-time: Make Send happy
This commit is contained in:
parent
bef6c359a0
commit
2bd70baeb9
3 changed files with 26 additions and 6 deletions
|
@ -532,7 +532,7 @@ mod tests {
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn stress_channel() {
|
async fn stress_channel() {
|
||||||
const NUM_RUNS: usize = 1_000000;
|
const NUM_RUNS: usize = 1_000;
|
||||||
const QUEUE_SIZE: usize = 10;
|
const QUEUE_SIZE: usize = 10;
|
||||||
|
|
||||||
let (s, mut r) = make_channel!(u32, QUEUE_SIZE);
|
let (s, mut r) = make_channel!(u32, QUEUE_SIZE);
|
||||||
|
|
|
@ -105,8 +105,6 @@ pub struct Link<T> {
|
||||||
_up: PhantomPinned,
|
_up: PhantomPinned,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<T> Send for Link<T> {}
|
|
||||||
|
|
||||||
impl<T: Clone> Link<T> {
|
impl<T: Clone> Link<T> {
|
||||||
const R: Ordering = Ordering::Relaxed;
|
const R: Ordering = Ordering::Relaxed;
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,26 @@ pub struct TimerQueue<Mono: Monotonic> {
|
||||||
/// This indicates that there was a timeout.
|
/// This indicates that there was a timeout.
|
||||||
pub struct TimeoutError;
|
pub struct TimeoutError;
|
||||||
|
|
||||||
|
/// This is needed to make the async closure in `delay_until` accept that we "share"
|
||||||
|
/// the link possible between threads.
|
||||||
|
struct LinkPtr<Mono: Monotonic>(*mut Option<linked_list::Link<WaitingWaker<Mono>>>);
|
||||||
|
|
||||||
|
impl<Mono: Monotonic> Clone for LinkPtr<Mono> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
LinkPtr(self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Mono: Monotonic> LinkPtr<Mono> {
|
||||||
|
/// This will dereference the pointer stored within and give out an `&mut`.
|
||||||
|
unsafe fn get(&mut self) -> &mut Option<linked_list::Link<WaitingWaker<Mono>>> {
|
||||||
|
&mut *self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl<Mono: Monotonic> Send for LinkPtr<Mono> {}
|
||||||
|
unsafe impl<Mono: Monotonic> Sync for LinkPtr<Mono> {}
|
||||||
|
|
||||||
impl<Mono: Monotonic> TimerQueue<Mono> {
|
impl<Mono: Monotonic> TimerQueue<Mono> {
|
||||||
/// Make a new queue.
|
/// Make a new queue.
|
||||||
pub const fn new() -> Self {
|
pub const fn new() -> Self {
|
||||||
|
@ -189,7 +209,9 @@ impl<Mono: Monotonic> TimerQueue<Mono> {
|
||||||
let mut link_ptr: Option<linked_list::Link<WaitingWaker<Mono>>> = None;
|
let mut link_ptr: Option<linked_list::Link<WaitingWaker<Mono>>> = None;
|
||||||
|
|
||||||
// Make this future `Drop`-safe, also shadow the original definition so we can't abuse it.
|
// Make this future `Drop`-safe, also shadow the original definition so we can't abuse it.
|
||||||
let link_ptr = &mut link_ptr as *mut Option<linked_list::Link<WaitingWaker<Mono>>>;
|
let mut link_ptr =
|
||||||
|
LinkPtr(&mut link_ptr as *mut Option<linked_list::Link<WaitingWaker<Mono>>>);
|
||||||
|
let mut link_ptr2 = link_ptr.clone();
|
||||||
|
|
||||||
let queue = &self.queue;
|
let queue = &self.queue;
|
||||||
let marker = &AtomicUsize::new(0);
|
let marker = &AtomicUsize::new(0);
|
||||||
|
@ -205,7 +227,7 @@ impl<Mono: Monotonic> TimerQueue<Mono> {
|
||||||
|
|
||||||
// SAFETY: This pointer is only dereferenced here and on drop of the future
|
// SAFETY: This pointer is only dereferenced here and on drop of the future
|
||||||
// which happens outside this `poll_fn`'s stack frame.
|
// which happens outside this `poll_fn`'s stack frame.
|
||||||
let link = unsafe { &mut *link_ptr };
|
let link = unsafe { link_ptr2.get() };
|
||||||
if link.is_none() {
|
if link.is_none() {
|
||||||
let mut link_ref = link.insert(Link::new(WaitingWaker {
|
let mut link_ref = link.insert(Link::new(WaitingWaker {
|
||||||
waker: cx.waker().clone(),
|
waker: cx.waker().clone(),
|
||||||
|
@ -231,7 +253,7 @@ impl<Mono: Monotonic> TimerQueue<Mono> {
|
||||||
// SAFETY: We only run this and dereference the pointer if we have
|
// SAFETY: We only run this and dereference the pointer if we have
|
||||||
// exited the `poll_fn` below in the `drop(dropper)` call. The other dereference
|
// exited the `poll_fn` below in the `drop(dropper)` call. The other dereference
|
||||||
// of this pointer is in the `poll_fn`.
|
// of this pointer is in the `poll_fn`.
|
||||||
if let Some(link) = unsafe { &mut *link_ptr } {
|
if let Some(link) = unsafe { link_ptr.get() } {
|
||||||
if link.val.was_poped.load(Ordering::Relaxed) {
|
if link.val.was_poped.load(Ordering::Relaxed) {
|
||||||
// If it was poped from the queue there is no need to run delete
|
// If it was poped from the queue there is no need to run delete
|
||||||
dropper.defuse();
|
dropper.defuse();
|
||||||
|
|
Loading…
Reference in a new issue