hermit/mm/
page_range_alloc.rs1use core::alloc::AllocError;
2use core::marker::PhantomData;
3use core::mem::ManuallyDrop;
4use core::ops::Deref;
5
6use free_list::{PageLayout, PageRange};
7
8pub trait PageRangeAllocator {
10 unsafe fn init();
11
12 fn allocate(layout: PageLayout) -> Result<PageRange, AllocError>;
14
15 fn allocate_at(range: PageRange) -> Result<(), AllocError>;
17
18 unsafe fn deallocate(range: PageRange);
24}
25
26pub struct PageRangeBox<A: PageRangeAllocator>(PageRange, PhantomData<A>);
27
28impl<A: PageRangeAllocator> PageRangeBox<A> {
29 pub fn new(layout: PageLayout) -> Result<Self, AllocError> {
30 let range = A::allocate(layout)?;
31 Ok(Self(range, PhantomData))
32 }
33
34 pub unsafe fn from_raw(range: PageRange) -> Self {
35 Self(range, PhantomData)
36 }
37
38 pub fn into_raw(b: Self) -> PageRange {
39 let b = ManuallyDrop::new(b);
40 **b
41 }
42}
43
44impl<A: PageRangeAllocator> Drop for PageRangeBox<A> {
45 fn drop(&mut self) {
46 unsafe {
47 A::deallocate(self.0);
48 }
49 }
50}
51
52impl<A: PageRangeAllocator> Deref for PageRangeBox<A> {
53 type Target = PageRange;
54
55 fn deref(&self) -> &Self::Target {
56 &self.0
57 }
58}