aboutsummaryrefslogtreecommitdiff
path: root/rtic-channel/src/wait_queue.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rtic-channel/src/wait_queue.rs')
-rw-r--r--rtic-channel/src/wait_queue.rs16
1 files changed, 10 insertions, 6 deletions
diff --git a/rtic-channel/src/wait_queue.rs b/rtic-channel/src/wait_queue.rs
index 5b59983..ba05e6b 100644
--- a/rtic-channel/src/wait_queue.rs
+++ b/rtic-channel/src/wait_queue.rs
@@ -1,6 +1,7 @@
//! ...
use core::marker::PhantomPinned;
+use core::pin::Pin;
use core::ptr::null_mut;
use core::sync::atomic::{AtomicPtr, Ordering};
use core::task::Waker;
@@ -65,13 +66,16 @@ impl<T: Clone> LinkedList<T> {
}
/// Put an element at the back of the queue.
- pub fn push(&self, link: &mut Link<T>) {
+ pub fn push(&self, link: Pin<&mut Link<T>>) {
cs::with(|_| {
// Make sure all previous writes are visible
core::sync::atomic::fence(Ordering::SeqCst);
let tail = self.tail.load(Self::R);
+ // SAFETY: This datastructure does not move the underlying value.
+ let link = unsafe { link.get_unchecked_mut() };
+
if let Some(tail_ref) = unsafe { tail.as_ref() } {
// Queue is not empty
link.prev.store(tail, Self::R);
@@ -221,11 +225,11 @@ mod tests {
let mut i4 = Link::new(13);
let mut i5 = Link::new(14);
- wq.push(&mut i1);
- wq.push(&mut i2);
- wq.push(&mut i3);
- wq.push(&mut i4);
- wq.push(&mut i5);
+ wq.push(unsafe { Pin::new_unchecked(&mut i1) });
+ wq.push(unsafe { Pin::new_unchecked(&mut i2) });
+ wq.push(unsafe { Pin::new_unchecked(&mut i3) });
+ wq.push(unsafe { Pin::new_unchecked(&mut i4) });
+ wq.push(unsafe { Pin::new_unchecked(&mut i5) });
wq.print();