Allow Segment<dyn FrameMeta>

This commit is contained in:
Zhang Junyang
2024-12-24 15:07:07 +08:00
committed by Tate, Hongliang Tian
parent ef6ff7ad84
commit 6e1c36965a

View File

@ -8,7 +8,7 @@ use core::{mem::ManuallyDrop, ops::Range};
use super::{inc_page_ref_count, meta::FrameMeta, Frame}; use super::{inc_page_ref_count, meta::FrameMeta, Frame};
use crate::mm::{Paddr, PAGE_SIZE}; use crate::mm::{Paddr, PAGE_SIZE};
/// A contiguous range of physical memory pages. /// A contiguous range of homogeneous physical memory pages.
/// ///
/// This is a handle to many contiguous pages. It will be more lightweight /// This is a handle to many contiguous pages. It will be more lightweight
/// than owning an array of page handles. /// than owning an array of page handles.
@ -17,13 +17,16 @@ use crate::mm::{Paddr, PAGE_SIZE};
/// When constructing a `Segment`, the page handles are created then /// When constructing a `Segment`, the page handles are created then
/// forgotten, leaving the reference count. When dropping a it, the page /// forgotten, leaving the reference count. When dropping a it, the page
/// handles are restored and dropped, decrementing the reference count. /// handles are restored and dropped, decrementing the reference count.
///
/// All the metadata of the pages are homogeneous, i.e., they are of the same
/// type.
#[derive(Debug)] #[derive(Debug)]
pub struct Segment<M: FrameMeta> { pub struct Segment<M: FrameMeta + ?Sized> {
range: Range<Paddr>, range: Range<Paddr>,
_marker: core::marker::PhantomData<M>, _marker: core::marker::PhantomData<M>,
} }
impl<M: FrameMeta> Drop for Segment<M> { impl<M: FrameMeta + ?Sized> Drop for Segment<M> {
fn drop(&mut self) { fn drop(&mut self) {
for paddr in self.range.clone().step_by(PAGE_SIZE) { for paddr in self.range.clone().step_by(PAGE_SIZE) {
// SAFETY: for each page there would be a forgotten handle // SAFETY: for each page there would be a forgotten handle
@ -33,7 +36,7 @@ impl<M: FrameMeta> Drop for Segment<M> {
} }
} }
impl<M: FrameMeta> Clone for Segment<M> { impl<M: FrameMeta + ?Sized> Clone for Segment<M> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
for paddr in self.range.clone().step_by(PAGE_SIZE) { for paddr in self.range.clone().step_by(PAGE_SIZE) {
// SAFETY: for each page there would be a forgotten handle // SAFETY: for each page there would be a forgotten handle
@ -72,7 +75,9 @@ impl<M: FrameMeta> Segment<M> {
_marker: core::marker::PhantomData, _marker: core::marker::PhantomData,
} }
} }
}
impl<M: FrameMeta + ?Sized> Segment<M> {
/// Gets the start physical address of the contiguous pages. /// Gets the start physical address of the contiguous pages.
pub fn start_paddr(&self) -> Paddr { pub fn start_paddr(&self) -> Paddr {
self.range.start self.range.start
@ -145,7 +150,7 @@ impl<M: FrameMeta> Segment<M> {
} }
} }
impl<M: FrameMeta> From<Frame<M>> for Segment<M> { impl<M: FrameMeta + ?Sized> From<Frame<M>> for Segment<M> {
fn from(page: Frame<M>) -> Self { fn from(page: Frame<M>) -> Self {
let pa = page.paddr(); let pa = page.paddr();
let _ = ManuallyDrop::new(page); let _ = ManuallyDrop::new(page);
@ -156,7 +161,7 @@ impl<M: FrameMeta> From<Frame<M>> for Segment<M> {
} }
} }
impl<M: FrameMeta> From<Segment<M>> for Vec<Frame<M>> { impl<M: FrameMeta + ?Sized> From<Segment<M>> for Vec<Frame<M>> {
fn from(pages: Segment<M>) -> Self { fn from(pages: Segment<M>) -> Self {
let vector = pages let vector = pages
.range .range
@ -172,7 +177,7 @@ impl<M: FrameMeta> From<Segment<M>> for Vec<Frame<M>> {
} }
} }
impl<M: FrameMeta> Iterator for Segment<M> { impl<M: FrameMeta + ?Sized> Iterator for Segment<M> {
type Item = Frame<M>; type Item = Frame<M>;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {