More BumpAllocator APIs.
This commit is contained in:
@@ -12,21 +12,44 @@ use crate::{
|
||||
pub struct BumpAllocator<A> {
|
||||
areas: &'static [MemoryArea],
|
||||
offset: usize,
|
||||
phantom: PhantomData<A>,
|
||||
abs_offset: PhysicalAddress,
|
||||
_marker: PhantomData<fn() -> A>,
|
||||
}
|
||||
|
||||
impl<A: Arch> BumpAllocator<A> {
|
||||
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<A: Arch> FrameAllocator for BumpAllocator<A> {
|
||||
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<A: Arch> FrameAllocator for BumpAllocator<A> {
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user