mirror of
https://github.com/rtic-rs/rtic.git
synced 2025-12-16 12:55:23 +01:00
Make some linked list operations unsafe, and document their safety at usage
This commit is contained in:
parent
002d0b0d16
commit
1cda61fbda
6 changed files with 66 additions and 40 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
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);
|
||||
|
||||
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) });
|
||||
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();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue