Skip to content

Commit

Permalink
fix approach 2: use unsafecell
Browse files Browse the repository at this point in the history
  • Loading branch information
JoJoDeveloping committed Aug 29, 2024
1 parent f637e50 commit 3f60789
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 29 deletions.
28 changes: 8 additions & 20 deletions core/arena/unique_arena.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ impl<T: 'static> ArenaBox<T> {
/// This function returns a raw pointer without managing the memory, potentially leading to
/// memory leaks if the pointer is not properly handled or deallocated.
#[inline(always)]
pub fn into_raw(mut alloc: ArenaBox<T>) -> NonNull<T> {
let ptr = NonNull::from(alloc.data_mut());
pub fn into_raw(alloc: ArenaBox<T>) -> NonNull<T> {
let ptr: NonNull<ArenaBoxData<T>> = alloc.ptr;
std::mem::forget(alloc);
unsafe { Self::ptr_from_data(ptr) }
}
Expand Down Expand Up @@ -91,8 +91,10 @@ impl<T> ArenaBox<T> {
}

#[inline(always)]
fn data_mut(&mut self) -> &mut ArenaBoxData<T> {
unsafe { self.ptr.as_mut() }
pub(crate) fn deref_data(&self) -> NonNull<T> {
unsafe {
NonNull::new_unchecked(std::ptr::addr_of_mut!((*self.ptr.as_ptr()).data))
}
}
}

Expand Down Expand Up @@ -120,20 +122,6 @@ impl<T> std::convert::AsRef<T> for ArenaBox<T> {
}
}

impl<T> std::ops::DerefMut for ArenaBox<T> {
#[inline(always)]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.data_mut().data
}
}

impl<T> std::convert::AsMut<T> for ArenaBox<T> {
#[inline(always)]
fn as_mut(&mut self) -> &mut T {
&mut self.data_mut().data
}
}

impl<F, R> std::future::Future for ArenaBox<F>
where
F: Future<Output = R>,
Expand All @@ -142,10 +130,10 @@ where

#[inline(always)]
fn poll(
mut self: Pin<&mut Self>,
self: Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
) -> std::task::Poll<Self::Output> {
unsafe { F::poll(Pin::new_unchecked(&mut self.data_mut().data), cx) }
unsafe { F::poll(Pin::new_unchecked(self.deref_data().as_mut()), cx) }
}
}

Expand Down
9 changes: 6 additions & 3 deletions core/runtime/op_driver/erased_future.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,11 @@ impl<const MAX_SIZE: usize> TypeErased<MAX_SIZE> {
}

#[inline(always)]
pub fn raw_ptr<R>(&mut self) -> NonNull<R> {
unsafe { NonNull::new_unchecked(self.memory.as_mut_ptr() as *mut _) }
/// Safety: This uses a place projection to `this.memory`, which must be in-bounds.
pub unsafe fn raw_ptr<R>(this: *mut Self) -> NonNull<R> {
unsafe {
NonNull::new_unchecked(std::ptr::addr_of_mut!((*this).memory) as *mut _)
}
}

#[inline(always)]
Expand Down Expand Up @@ -70,7 +73,7 @@ impl<const MAX_SIZE: usize> TypeErased<MAX_SIZE> {

impl<const MAX_SIZE: usize> Drop for TypeErased<MAX_SIZE> {
fn drop(&mut self) {
(self.drop)(self.raw_ptr::<()>())
(self.drop)(unsafe { Self::raw_ptr(self) })
}
}

Expand Down
14 changes: 8 additions & 6 deletions core/runtime/op_driver/future_arena.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use super::erased_future::TypeErased;
use crate::arena::ArenaBox;
use crate::arena::ArenaUnique;
use pin_project::pin_project;
use std::cell::UnsafeCell;
use std::future::Future;
use std::marker::PhantomData;
use std::mem::MaybeUninit;
Expand All @@ -25,7 +26,7 @@ pub trait FutureContextMapper<T, C, R> {

struct DynFutureInfoErased<T, C> {
ptr: MaybeUninit<NonNull<dyn ContextFuture<T, C>>>,
data: TypeErased<MAX_ARENA_FUTURE_SIZE>,
data: UnsafeCell<TypeErased<MAX_ARENA_FUTURE_SIZE>>,
}

pub trait ContextFuture<T, C>: Future<Output = T> {
Expand Down Expand Up @@ -190,19 +191,20 @@ impl<T, C: Clone> FutureArena<T, C> {
{
unsafe {
if let Some(reservation) = self.arena.reserve_space() {
let mut alloc = self.arena.complete_reservation(
let alloc = self.arena.complete_reservation(
reservation,
DynFutureInfoErased {
ptr: MaybeUninit::uninit(),
data: TypeErased::new(DynFutureInfo {
data: UnsafeCell::new(TypeErased::new(DynFutureInfo {
context,
future,
_phantom: PhantomData,
}),
})),
},
);
let ptr = alloc.data.raw_ptr::<DynFutureInfo<T, C, M, F>>();
alloc.ptr.write(ptr);
let ptr =
TypeErased::raw_ptr::<DynFutureInfo<T, C, M, F>>(alloc.data.get());
(*alloc.deref_data().as_ptr()).ptr.write(ptr);
return TypedFutureAllocation {
inner: FutureAllocation::Arena(alloc),
ptr,
Expand Down

0 comments on commit 3f60789

Please sign in to comment.