mirror of
https://github.com/rtic-rs/rtic.git
synced 2025-12-16 21:05:35 +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
|
|
@ -208,7 +208,8 @@ impl<Mono: Monotonic> TimerQueue<Mono> {
|
|||
|
||||
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
|
||||
// SAFETY(link_ptr): Shadow the original definition of `link_ptr` so we can't abuse it.
|
||||
let mut link_ptr =
|
||||
LinkPtr(&mut link_ptr as *mut Option<linked_list::Link<WaitingWaker<Mono>>>);
|
||||
let mut link_ptr2 = link_ptr.clone();
|
||||
|
|
@ -226,18 +227,24 @@ impl<Mono: Monotonic> TimerQueue<Mono> {
|
|||
}
|
||||
|
||||
// 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, so this mutable access cannot
|
||||
// happen at the same time as `dropper` runs.
|
||||
let link = unsafe { link_ptr2.get() };
|
||||
if link.is_none() {
|
||||
let mut link_ref = link.insert(Link::new(WaitingWaker {
|
||||
let link_ref = link.insert(Link::new(WaitingWaker {
|
||||
waker: cx.waker().clone(),
|
||||
release_at: instant,
|
||||
was_poped: AtomicBool::new(false),
|
||||
}));
|
||||
|
||||
// SAFETY: The address to the link is stable as it is defined outside this stack
|
||||
// frame.
|
||||
let (was_empty, addr) = queue.insert(unsafe { Pin::new_unchecked(&mut link_ref) });
|
||||
// SAFETY(new_unchecked): The address to the link is stable as it is defined
|
||||
//outside this stack frame.
|
||||
// SAFETY(insert): `link_ref` lifetime comes from `link_ptr` that is shadowed, and
|
||||
// we make sure in `dropper` that the link is removed from the queue before
|
||||
// dropping `link_ptr` AND `dropper` makes sure that the shadowed `link_ptr` lives
|
||||
// until the end of the stack frame.
|
||||
let (was_empty, addr) = unsafe { queue.insert(Pin::new_unchecked(&link_ref)) };
|
||||
|
||||
marker.store(addr, Ordering::Relaxed);
|
||||
|
||||
if was_empty {
|
||||
|
|
|
|||
|
|
@ -93,10 +93,12 @@ impl<T: PartialOrd + Clone> LinkedList<T> {
|
|||
|
||||
/// Insert a new link into the linked list.
|
||||
/// The return is (was_empty, address), where the address of the link is for use with `delete`.
|
||||
pub fn insert(&self, val: Pin<&mut Link<T>>) -> (bool, usize) {
|
||||
///
|
||||
/// SAFETY: The pinned link must live until it is removed from this list.
|
||||
pub unsafe fn insert(&self, val: Pin<&Link<T>>) -> (bool, usize) {
|
||||
cs::with(|_| {
|
||||
// SAFETY: This datastructure does not move the underlying value.
|
||||
let val = unsafe { val.get_unchecked_mut() };
|
||||
let val = val.get_ref();
|
||||
let addr = val as *const _ as usize;
|
||||
|
||||
// Make sure all previous writes are visible
|
||||
|
|
@ -111,7 +113,8 @@ impl<T: PartialOrd + Clone> LinkedList<T> {
|
|||
let head_ref = if let Some(head_ref) = unsafe { head.as_ref() } {
|
||||
head_ref
|
||||
} else {
|
||||
self.head.store(val, Ordering::Relaxed);
|
||||
self.head
|
||||
.store(val as *const _ as *mut _, Ordering::Relaxed);
|
||||
return (true, addr);
|
||||
};
|
||||
|
||||
|
|
@ -121,7 +124,8 @@ impl<T: PartialOrd + Clone> LinkedList<T> {
|
|||
val.next.store(head, Ordering::Relaxed);
|
||||
|
||||
// `val` is now first in the queue
|
||||
self.head.store(val, Ordering::Relaxed);
|
||||
self.head
|
||||
.store(val as *const _ as *mut _, Ordering::Relaxed);
|
||||
|
||||
return (false, addr);
|
||||
}
|
||||
|
|
@ -139,7 +143,8 @@ impl<T: PartialOrd + Clone> LinkedList<T> {
|
|||
val.next.store(next, Ordering::Relaxed);
|
||||
|
||||
// Insert `val`
|
||||
curr.next.store(val, Ordering::Relaxed);
|
||||
curr.next
|
||||
.store(val as *const _ as *mut _, Ordering::Relaxed);
|
||||
|
||||
return (false, addr);
|
||||
}
|
||||
|
|
@ -150,7 +155,8 @@ impl<T: PartialOrd + Clone> LinkedList<T> {
|
|||
}
|
||||
|
||||
// No next, write link to last position in list
|
||||
curr.next.store(val, Ordering::Relaxed);
|
||||
curr.next
|
||||
.store(val as *const _ as *mut _, Ordering::Relaxed);
|
||||
|
||||
(false, addr)
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue