use alloc::vec::Vec;
use core::{mem::ManuallyDrop, ops::Range};
use super::{meta::PageMeta, Page};
use crate::mm::{Paddr, PAGE_SIZE};
#[derive(Debug)]
pub struct ContPages<M: PageMeta> {
range: Range<Paddr>,
_marker: core::marker::PhantomData<M>,
}
impl<M: PageMeta> Drop for ContPages<M> {
fn drop(&mut self) {
for i in self.range.clone().step_by(PAGE_SIZE) {
drop(unsafe { Page::<M>::from_raw(i) });
}
}
}
impl<M: PageMeta> ContPages<M> {
pub fn from_unused<F>(range: Range<Paddr>, mut metadata_fn: F) -> Self
where
F: FnMut(Paddr) -> M,
{
for i in range.clone().step_by(PAGE_SIZE) {
let _ = ManuallyDrop::new(Page::<M>::from_unused(i, metadata_fn(i)));
}
Self {
range,
_marker: core::marker::PhantomData,
}
}
pub fn start_paddr(&self) -> Paddr {
self.range.start
}
pub fn end_paddr(&self) -> Paddr {
self.range.end
}
pub fn len(&self) -> usize {
self.range.end - self.range.start
}
}
impl<M: PageMeta> From<Page<M>> for ContPages<M> {
fn from(page: Page<M>) -> Self {
let pa = page.paddr();
let _ = ManuallyDrop::new(page);
Self {
range: pa..pa + PAGE_SIZE,
_marker: core::marker::PhantomData,
}
}
}
impl<M: PageMeta> From<ContPages<M>> for Vec<Page<M>> {
fn from(pages: ContPages<M>) -> Self {
let vector = pages
.range
.clone()
.step_by(PAGE_SIZE)
.map(|i|
unsafe { Page::<M>::from_raw(i) })
.collect();
let _ = ManuallyDrop::new(pages);
vector
}
}