From d7c6947f4eabd1e4bbfaf6f966e9e12e16297137 Mon Sep 17 00:00:00 2001 From: datdenkikniet Date: Sun, 23 Mar 2025 12:34:59 +0100 Subject: rtic-sync: re-wrap UnsafeCell instead --- rtic-sync/src/channel.rs | 7 ++-- rtic-sync/src/unsafecell.rs | 81 ++++++++++++++++++++++++++++++--------------- 2 files changed, 57 insertions(+), 31 deletions(-) (limited to 'rtic-sync') diff --git a/rtic-sync/src/channel.rs b/rtic-sync/src/channel.rs index 043d058..f2f8aa1 100644 --- a/rtic-sync/src/channel.rs +++ b/rtic-sync/src/channel.rs @@ -104,9 +104,7 @@ impl Channel { /// Split the queue into a `Sender`/`Receiver` pair. pub fn split(&mut self) -> (Sender<'_, T, N>, Receiver<'_, T, N>) { - // SAFETY: we have exclusive access to `self`. - let freeq = self.freeq.get_mut(); - let freeq = unsafe { freeq.deref() }; + let freeq = self.freeq.as_mut(); // Fill free queue for idx in 0..N as u8 { @@ -123,8 +121,7 @@ impl Channel { debug_assert!(freeq.is_full()); // There is now 1 sender - // SAFETY: we have exclusive access to `self`. - unsafe { *self.num_senders.get_mut().deref() = 1 }; + *self.num_senders.as_mut() = 1; (Sender(self), Receiver(self)) } diff --git a/rtic-sync/src/unsafecell.rs b/rtic-sync/src/unsafecell.rs index e3730d4..707f413 100644 --- a/rtic-sync/src/unsafecell.rs +++ b/rtic-sync/src/unsafecell.rs @@ -1,39 +1,68 @@ //! Compat layer for [`core::cell::UnsafeCell`] and `loom::cell::UnsafeCell`. #[cfg(loom)] -pub use loom::cell::UnsafeCell; +use loom::cell::UnsafeCell as InnerUnsafeCell; -#[cfg(not(loom))] -pub use core::UnsafeCell; +#[cfg(loom)] +pub use loom::cell::MutPtr; #[cfg(not(loom))] -mod core { - /// An [`core::cell::UnsafeCell`] wrapper that provides compatibility with - /// loom's UnsafeCell. - #[derive(Debug)] - pub struct UnsafeCell(core::cell::UnsafeCell); - - impl UnsafeCell { - /// Create a new `UnsafeCell`. - pub const fn new(data: T) -> UnsafeCell { - UnsafeCell(core::cell::UnsafeCell::new(data)) - } +use core::cell::UnsafeCell as InnerUnsafeCell; - /// Access the contents of the `UnsafeCell` through a mut pointer. - pub fn get_mut(&self) -> MutPtr { - MutPtr(self.0.get()) - } +/// An [`core::cell::UnsafeCell`] wrapper that provides compatibility with +/// loom's UnsafeCell. +#[derive(Debug)] +pub struct UnsafeCell(InnerUnsafeCell); + +impl UnsafeCell { + /// Create a new `UnsafeCell`. + #[cfg(not(loom))] + pub const fn new(data: T) -> UnsafeCell { + UnsafeCell(InnerUnsafeCell::new(data)) } - pub struct MutPtr(*mut T); + #[cfg(loom)] + pub fn new(data: T) -> UnsafeCell { + UnsafeCell(InnerUnsafeCell::new(data)) + } + + /// Access the contents of the `UnsafeCell` through a tracked mut pointer. + pub fn get_mut(&self) -> MutPtr { + #[cfg(loom)] + return self.0.get_mut(); + + #[cfg(not(loom))] + return MutPtr(self.0.get()); + } - impl MutPtr { - #[allow(clippy::mut_from_ref)] - /// SAFETY: the caller must guarantee that the contained `*mut T` is not - /// null, and must uphold the same safety requirements as for - /// [`core::primitive::pointer::as_mut`] for the contained `*mut T`. - pub unsafe fn deref(&self) -> &mut T { - &mut *self.0 + /// Access the contents of the `UnsafeCell` mutably. + pub fn as_mut(&mut self) -> &mut T { + #[cfg(not(loom))] + return self.0.get_mut(); + + #[cfg(loom)] + { + // SAFETY: we have exclusive access to `self`. + let ptr = self.get_mut(); + let ptr = unsafe { ptr.deref() }; + + // SAFETY: we have exclusive access to `self` for the duration of + // the borrow. + unsafe { core::mem::transmute(ptr) } } } } + +#[cfg(not(loom))] +pub struct MutPtr(*mut T); + +#[cfg(not(loom))] +impl MutPtr { + #[allow(clippy::mut_from_ref)] + /// SAFETY: the caller must guarantee that the contained `*mut T` is not + /// null, and must uphold the same safety requirements as for + /// [`core::primitive::pointer::as_mut`] for the contained `*mut T`. + pub unsafe fn deref(&self) -> &mut T { + &mut *self.0 + } +} -- cgit v1.2.3