aboutsummaryrefslogtreecommitdiff
path: root/rtic-common/src
diff options
context:
space:
mode:
authorGravatar Emil Fresk <emil.fresk@gmail.com> 2023-02-18 09:43:06 +0100
committerGravatar Henrik Tjäder <henrik@tjaders.com> 2023-03-01 00:35:20 +0100
commit1cda61fbda205920517f7b63af90c97c38ff9af6 (patch)
treece3921072005300ab089c72deaae41dc0cf3a61b /rtic-common/src
parent002d0b0d1685473f0f81cd17346d119fc671ad9c (diff)
downloadrtic-1cda61fbda205920517f7b63af90c97c38ff9af6.tar.gz
rtic-1cda61fbda205920517f7b63af90c97c38ff9af6.tar.zst
rtic-1cda61fbda205920517f7b63af90c97c38ff9af6.zip
Make some linked list operations unsafe, and document their safety at usage
Diffstat (limited to 'rtic-common/src')
-rw-r--r--rtic-common/src/lib.rs4
-rw-r--r--rtic-common/src/wait_queue.rs38
2 files changed, 24 insertions, 18 deletions
diff --git a/rtic-common/src/lib.rs b/rtic-common/src/lib.rs
index b8b5e0d9..03d03063 100644
--- a/rtic-common/src/lib.rs
+++ b/rtic-common/src/lib.rs
@@ -4,6 +4,10 @@
#![deny(missing_docs)]
//deny_warnings_placeholder_for_ci
+#[cfg(test)]
+#[macro_use]
+extern crate std;
+
pub mod dropper;
pub mod wait_queue;
pub mod waker_registration;
diff --git a/rtic-common/src/wait_queue.rs b/rtic-common/src/wait_queue.rs
index 4ced6ab9..7387a984 100644
--- a/rtic-common/src/wait_queue.rs
+++ b/rtic-common/src/wait_queue.rs
@@ -68,7 +68,9 @@ impl<T: Clone> LinkedList<T> {
}
/// Put an element at the back of the queue.
- pub fn push(&self, link: Pin<&mut Link<T>>) {
+ ///
+ /// SAFETY: The link must live until it is removed from the queue.
+ pub unsafe fn push(&self, link: Pin<&Link<T>>) {
cs::with(|_| {
// Make sure all previous writes are visible
core::sync::atomic::fence(Ordering::SeqCst);
@@ -76,17 +78,17 @@ impl<T: Clone> LinkedList<T> {
let tail = self.tail.load(Self::R);
// SAFETY: This datastructure does not move the underlying value.
- let link = unsafe { link.get_unchecked_mut() };
+ let link = link.get_ref();
if let Some(tail_ref) = unsafe { tail.as_ref() } {
// Queue is not empty
link.prev.store(tail, Self::R);
- self.tail.store(link, Self::R);
- tail_ref.next.store(link, Self::R);
+ self.tail.store(link as *const _ as *mut _, Self::R);
+ tail_ref.next.store(link as *const _ as *mut _, Self::R);
} else {
// Queue is empty
- self.tail.store(link, Self::R);
- self.head.store(link, Self::R);
+ self.tail.store(link as *const _ as *mut _, Self::R);
+ self.head.store(link as *const _ as *mut _, Self::R);
}
});
}
@@ -126,7 +128,7 @@ impl<T: Clone> Link<T> {
}
/// Remove this link from a linked list.
- pub fn remove_from_list(&mut self, list: &LinkedList<T>) {
+ pub fn remove_from_list(&self, list: &LinkedList<T>) {
cs::with(|_| {
// Make sure all previous writes are visible
core::sync::atomic::fence(Ordering::SeqCst);
@@ -230,17 +232,17 @@ mod tests {
fn linked_list() {
let wq = LinkedList::<u32>::new();
- let mut i1 = Link::new(10);
- let mut i2 = Link::new(11);
- let mut i3 = Link::new(12);
- let mut i4 = Link::new(13);
- let mut i5 = Link::new(14);
-
- 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) });
+ let i1 = Link::new(10);
+ let i2 = Link::new(11);
+ let i3 = Link::new(12);
+ let i4 = Link::new(13);
+ let i5 = Link::new(14);
+
+ unsafe { wq.push(Pin::new_unchecked(&i1)) };
+ unsafe { wq.push(Pin::new_unchecked(&i2)) };
+ unsafe { wq.push(Pin::new_unchecked(&i3)) };
+ unsafe { wq.push(Pin::new_unchecked(&i4)) };
+ unsafe { wq.push(Pin::new_unchecked(&i5)) };
wq.print();