Replace the original XArray with RCU-based XArray

This commit is contained in:
Chen Chengjun 2025-04-28 10:29:39 +08:00 committed by Tate, Hongliang Tian
parent ac1de89d31
commit 1da723c0de
7 changed files with 32 additions and 43 deletions

11
Cargo.lock generated
View File

@ -229,7 +229,7 @@ dependencies = [
"time", "time",
"typeflags", "typeflags",
"typeflags-util", "typeflags-util",
"xarray 0.1.0", "xarray",
"xmas-elf 0.8.0", "xmas-elf 0.8.0",
] ]
@ -1324,7 +1324,6 @@ dependencies = [
"volatile 0.6.1", "volatile 0.6.1",
"x86", "x86",
"x86_64", "x86_64",
"xarray 0.1.0 (git+https://github.com/asterinas/xarray)",
] ]
[[package]] [[package]]
@ -1984,14 +1983,6 @@ dependencies = [
"ostd", "ostd",
] ]
[[package]]
name = "xarray"
version = "0.1.0"
source = "git+https://github.com/asterinas/xarray#1dad5d9b74aac30193bd242a97077b4c54933830"
dependencies = [
"smallvec",
]
[[package]] [[package]]
name = "xmas-elf" name = "xmas-elf"
version = "0.8.0" version = "0.8.0"

View File

@ -37,7 +37,6 @@ spin = "0.9.4"
smallvec = "1.13.2" smallvec = "1.13.2"
unwinding = { version = "=0.2.5", default-features = false, features = ["fde-gnu-eh-frame-hdr", "hide-trace", "panic", "personality", "unwinder"] } unwinding = { version = "=0.2.5", default-features = false, features = ["fde-gnu-eh-frame-hdr", "hide-trace", "panic", "personality", "unwinder"] }
volatile = "0.6.1" volatile = "0.6.1"
xarray = { git = "https://github.com/asterinas/xarray", version = "0.1.0" }
[target.x86_64-unknown-none.dependencies] [target.x86_64-unknown-none.dependencies]
x86_64 = "0.14.13" x86_64 = "0.14.13"

View File

@ -1,6 +0,0 @@
// SPDX-License-Identifier: MPL-2.0
//! This module provides some advanced collections.
// TODO: Remove the old xarray module.
pub mod xarray;

View File

@ -1,6 +0,0 @@
// SPDX-License-Identifier: MPL-2.0
//! This module introduces the xarray crate and provides relevant support and interfaces for `XArray`.
extern crate xarray as xarray_crate;
pub use xarray_crate::{Cursor, CursorMut, XArray, XMark};

View File

@ -33,7 +33,6 @@ pub mod arch;
pub mod arch; pub mod arch;
pub mod boot; pub mod boot;
pub mod bus; pub mod bus;
pub mod collections;
pub mod console; pub mod console;
pub mod cpu; pub mod cpu;
mod error; mod error;

View File

@ -486,8 +486,8 @@ mod untyped {
} }
#[ktest] #[ktest]
fn xarray_item_entry() { fn frame_impls_non_null_ptr() {
use xarray::ItemEntry; use crate::sync::non_null::NonNullPtr;
let init_val = 42; let init_val = 42;
let frame = FrameAllocOptions::new() let frame = FrameAllocOptions::new()
@ -497,13 +497,13 @@ mod untyped {
let uframe: UFrame = frame.into(); let uframe: UFrame = frame.into();
// Converts and retrieves the frame from raw pointer // Converts and retrieves the frame from raw pointer
let raw_ptr = ItemEntry::into_raw(uframe); let raw_ptr = NonNullPtr::into_raw(uframe);
let frame_from_raw: Frame<MockUFrameMeta> = unsafe { ItemEntry::from_raw(raw_ptr) }; let frame_from_raw: Frame<MockUFrameMeta> = unsafe { NonNullPtr::from_raw(raw_ptr.cast()) };
assert_eq!(frame_from_raw.start_paddr(), ptr); assert_eq!(frame_from_raw.start_paddr(), ptr);
assert_eq!(frame_from_raw.meta().value, init_val); assert_eq!(frame_from_raw.meta().value, init_val);
// References the frame from raw pointer // References the frame from raw pointer
let frame_ref: FrameRef<MockUFrameMeta> = unsafe { Frame::raw_as_ref(raw_ptr) }; let frame_ref: FrameRef<MockUFrameMeta> = unsafe { Frame::raw_as_ref(raw_ptr.cast()) };
assert_eq!(frame_ref.start_paddr(), ptr); assert_eq!(frame_ref.start_paddr(), ptr);
} }
} }

View File

@ -7,12 +7,16 @@
//! the declaration of untyped frames and segments, and the implementation of //! the declaration of untyped frames and segments, and the implementation of
//! extra functionalities (such as [`VmIo`]) for them. //! extra functionalities (such as [`VmIo`]) for them.
use super::{meta::AnyFrameMeta, Frame, Segment}; use super::{
meta::{AnyFrameMeta, MetaSlot},
Frame, Segment,
};
use crate::{ use crate::{
mm::{ mm::{
io::{FallibleVmRead, FallibleVmWrite, VmIo, VmReader, VmWriter}, io::{FallibleVmRead, FallibleVmWrite, VmIo, VmReader, VmWriter},
paddr_to_vaddr, Infallible, paddr_to_vaddr, Infallible,
}, },
sync::non_null::NonNullPtr,
Error, Result, Error, Result,
}; };
@ -132,13 +136,13 @@ macro_rules! impl_untyped_for {
impl_untyped_for!(Frame); impl_untyped_for!(Frame);
impl_untyped_for!(Segment); impl_untyped_for!(Segment);
// Here are implementations for `xarray`. // Here are implementations for `crate::sync::rcu`.
use core::{marker::PhantomData, mem::ManuallyDrop, ops::Deref}; use core::{marker::PhantomData, mem::ManuallyDrop, ops::Deref, ptr::NonNull};
/// `FrameRef` is a struct that can work as `&'a Frame<m>`. /// `FrameRef` is a struct that can work as `&'a Frame<m>`.
/// ///
/// This is solely useful for [`crate::collections::xarray`]. /// This is useful for [`crate::sync::rcu`].
pub struct FrameRef<'a, M: AnyUFrameMeta + ?Sized> { pub struct FrameRef<'a, M: AnyUFrameMeta + ?Sized> {
inner: ManuallyDrop<Frame<M>>, inner: ManuallyDrop<Frame<M>>,
_marker: PhantomData<&'a Frame<M>>, _marker: PhantomData<&'a Frame<M>>,
@ -152,34 +156,42 @@ impl<M: AnyUFrameMeta + ?Sized> Deref for FrameRef<'_, M> {
} }
} }
// SAFETY: `Frame` is essentially an `*const MetaSlot` that could be used as a `*const` pointer. // SAFETY: `Frame` is essentially an `*const MetaSlot` that could be used as a non-null
// The pointer is also aligned to 4. // `*const` pointer.
unsafe impl<M: AnyUFrameMeta + ?Sized> xarray::ItemEntry for Frame<M> { unsafe impl<M: AnyUFrameMeta + ?Sized> NonNullPtr for Frame<M> {
type Target = PhantomData<Self>;
type Ref<'a> type Ref<'a>
= FrameRef<'a, M> = FrameRef<'a, M>
where where
Self: 'a; Self: 'a;
fn into_raw(self) -> *const () { const ALIGN_BITS: u32 = core::mem::align_of::<MetaSlot>().trailing_zeros();
let ptr = self.ptr;
fn into_raw(self) -> NonNull<Self::Target> {
let ptr = NonNull::new(self.ptr.cast_mut()).unwrap();
let _ = ManuallyDrop::new(self); let _ = ManuallyDrop::new(self);
ptr as *const () ptr.cast()
} }
unsafe fn from_raw(raw: *const ()) -> Self { unsafe fn from_raw(raw: NonNull<Self::Target>) -> Self {
Self { Self {
ptr: raw as *const _, ptr: raw.as_ptr().cast_const().cast(),
_marker: PhantomData, _marker: PhantomData,
} }
} }
unsafe fn raw_as_ref<'a>(raw: *const ()) -> Self::Ref<'a> { unsafe fn raw_as_ref<'a>(raw: NonNull<Self::Target>) -> Self::Ref<'a> {
Self::Ref { Self::Ref {
inner: ManuallyDrop::new(Frame { inner: ManuallyDrop::new(Frame {
ptr: raw as *const _, ptr: raw.as_ptr().cast_const().cast(),
_marker: PhantomData, _marker: PhantomData,
}), }),
_marker: PhantomData, _marker: PhantomData,
} }
} }
fn ref_as_raw(ptr_ref: Self::Ref<'_>) -> core::ptr::NonNull<Self::Target> {
NonNull::new(ptr_ref.inner.ptr.cast_mut()).unwrap().cast()
}
} }