From 5e75df56c56f1ed1c1d5427ffec3f33973f4b444 Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Thu, 26 Oct 2023 13:28:08 +0200 Subject: [PATCH] More BumpAllocator APIs. --- src/allocator/frame/bump.rs | 42 ++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/src/allocator/frame/bump.rs b/src/allocator/frame/bump.rs index d3a2b4eac1..85334b4af6 100644 --- a/src/allocator/frame/bump.rs +++ b/src/allocator/frame/bump.rs @@ -12,21 +12,44 @@ use crate::{ pub struct BumpAllocator { areas: &'static [MemoryArea], offset: usize, - phantom: PhantomData, + abs_offset: PhysicalAddress, + _marker: PhantomData A>, } impl BumpAllocator { pub fn new(areas: &'static [MemoryArea], offset: usize) -> Self { Self { areas, - offset, - phantom: PhantomData, + offset: 0, + abs_offset: areas[0].base, + _marker: PhantomData, } } - pub fn areas(&self) -> &'static [MemoryArea] { self.areas } + /// Returns one semifree and the fully free areas. The offset is the number of bytes after + /// which the first area is free. + pub fn free_areas(&self) -> (&'static [MemoryArea], usize) { + let mut areas = self.areas; + let mut offset = self.offset; + + loop { + let Some(area) = areas.first() else { + return (&[], 0); + }; + + if offset > area.size { + areas = &areas[1..]; + offset -= area.size; + } else { + return (areas, offset); + } + } + } + pub fn abs_offset(&self) -> PhysicalAddress { + self.abs_offset + } pub fn offset(&self) -> usize { self.offset @@ -38,7 +61,14 @@ impl FrameAllocator for BumpAllocator { let mut offset = self.offset; for area in self.areas.iter() { if offset < area.size { - if area.size - offset < count.data() { + if area.size - offset < count.data() * A::PAGE_SIZE { + /* + // The area may be too small for this alloc request. In that case, skip to the + // next area. + self.offset += area.size - offset; + offset = 0; + continue; + */ return None; } @@ -46,6 +76,8 @@ impl FrameAllocator for BumpAllocator { let page_virt = A::phys_to_virt(page_phys); A::write_bytes(page_virt, 0, count.data() * A::PAGE_SIZE); self.offset += count.data() * A::PAGE_SIZE; + + self.abs_offset = page_phys; return Some(page_phys); } offset -= area.size;