mirror of
https://github.com/rtic-rs/rtic.git
synced 2025-12-18 13:55:23 +01:00
rtic-sync: we have exclusive access to the free slot pointer when in drop
This commit is contained in:
parent
ea56cc0ce8
commit
1dd279e86e
1 changed files with 21 additions and 12 deletions
|
|
@ -246,7 +246,19 @@ impl SlotPtr {
|
||||||
new_value: Option<u8>,
|
new_value: Option<u8>,
|
||||||
_cs: critical_section::CriticalSection,
|
_cs: critical_section::CriticalSection,
|
||||||
) -> Option<u8> {
|
) -> Option<u8> {
|
||||||
// SAFETY: we are in a critical section.
|
// SAFETY: the critical section guarantees exclusive access, and the
|
||||||
|
// caller guarantees that the pointer is valid.
|
||||||
|
self.replace_exclusive(new_value)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Replace the value of this slot with `new_value`, and return
|
||||||
|
/// the old value.
|
||||||
|
///
|
||||||
|
/// SAFETY: the pointer in this `SlotPtr` must be valid for writes, and the caller must guarantee exclusive
|
||||||
|
/// access to the underlying value..
|
||||||
|
unsafe fn replace_exclusive(&mut self, new_value: Option<u8>) -> Option<u8> {
|
||||||
|
// SAFETY: the caller has ensured that we have exclusive access & that
|
||||||
|
// the pointer is valid.
|
||||||
unsafe { core::ptr::replace(self.0, new_value) }
|
unsafe { core::ptr::replace(self.0, new_value) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -338,17 +350,14 @@ impl<T, const N: usize> Sender<'_, T, N> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return our potentially-unused free slot.
|
// Return our potentially-unused free slot.
|
||||||
// Potentially unnecessary c-s because our link was already popped, so there
|
// Since we are certain that our link has been removed from the list (either
|
||||||
// is no way for anything else to access the free slot ptr. Gotta think
|
// pop-ed or removed just above), we have exclusive access to the free slot pointer.
|
||||||
// about this a bit more...
|
if let Some(freed_slot) = unsafe { free_slot_ptr2.replace_exclusive(None) } {
|
||||||
critical_section::with(|cs| {
|
// SAFETY: freed slot is passed to us from `return_free_slot`, which either
|
||||||
if let Some(freed_slot) = unsafe { free_slot_ptr2.replace(None, cs) } {
|
// directly (through `try_recv`), or indirectly (through another `return_free_slot`)
|
||||||
// SAFETY: freed slot is passed to us from `return_free_slot`, which either
|
// comes from `readyq`.
|
||||||
// directly (through `try_recv`), or indirectly (through another `return_free_slot`)
|
unsafe { self.0.return_free_slot(freed_slot) };
|
||||||
// comes from `readyq`.
|
}
|
||||||
unsafe { self.0.return_free_slot(freed_slot) };
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let idx = poll_fn(|cx| {
|
let idx = poll_fn(|cx| {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue