mirror of
https://github.com/rtic-rs/rtic.git
synced 2025-12-16 21:05:35 +01:00
rtic-sync: re-wrap UnsafeCell instead
This commit is contained in:
parent
bef2e1b9f0
commit
d7c6947f4e
2 changed files with 57 additions and 31 deletions
|
|
@ -104,9 +104,7 @@ impl<T, const N: usize> Channel<T, N> {
|
|||
|
||||
/// 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<T, const N: usize> Channel<T, N> {
|
|||
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))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(loom)]
|
||||
pub use loom::cell::MutPtr;
|
||||
|
||||
#[cfg(not(loom))]
|
||||
pub use core::UnsafeCell;
|
||||
use core::cell::UnsafeCell as InnerUnsafeCell;
|
||||
|
||||
#[cfg(not(loom))]
|
||||
mod core {
|
||||
/// An [`core::cell::UnsafeCell`] wrapper that provides compatibility with
|
||||
/// loom's UnsafeCell.
|
||||
#[derive(Debug)]
|
||||
pub struct UnsafeCell<T>(core::cell::UnsafeCell<T>);
|
||||
/// An [`core::cell::UnsafeCell`] wrapper that provides compatibility with
|
||||
/// loom's UnsafeCell.
|
||||
#[derive(Debug)]
|
||||
pub struct UnsafeCell<T>(InnerUnsafeCell<T>);
|
||||
|
||||
impl<T> UnsafeCell<T> {
|
||||
/// Create a new `UnsafeCell`.
|
||||
pub const fn new(data: T) -> UnsafeCell<T> {
|
||||
UnsafeCell(core::cell::UnsafeCell::new(data))
|
||||
}
|
||||
|
||||
/// Access the contents of the `UnsafeCell` through a mut pointer.
|
||||
pub fn get_mut(&self) -> MutPtr<T> {
|
||||
MutPtr(self.0.get())
|
||||
}
|
||||
impl<T> UnsafeCell<T> {
|
||||
/// Create a new `UnsafeCell`.
|
||||
#[cfg(not(loom))]
|
||||
pub const fn new(data: T) -> UnsafeCell<T> {
|
||||
UnsafeCell(InnerUnsafeCell::new(data))
|
||||
}
|
||||
|
||||
pub struct MutPtr<T>(*mut T);
|
||||
#[cfg(loom)]
|
||||
pub fn new(data: T) -> UnsafeCell<T> {
|
||||
UnsafeCell(InnerUnsafeCell::new(data))
|
||||
}
|
||||
|
||||
impl<T> MutPtr<T> {
|
||||
#[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` through a tracked mut pointer.
|
||||
pub fn get_mut(&self) -> MutPtr<T> {
|
||||
#[cfg(loom)]
|
||||
return self.0.get_mut();
|
||||
|
||||
#[cfg(not(loom))]
|
||||
return MutPtr(self.0.get());
|
||||
}
|
||||
|
||||
/// 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<T>(*mut T);
|
||||
|
||||
#[cfg(not(loom))]
|
||||
impl<T> MutPtr<T> {
|
||||
#[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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue