use bitmap_allocator::BitAlloc;
use crate::{AllocError, AllocResult, BaseAllocator, PageAllocator};
type BitAllocUsed = bitmap_allocator::BitAlloc1M;
pub struct BitmapPageAllocator<const PAGE_SIZE: usize> {
base: usize,
total_pages: usize,
used_pages: usize,
inner: BitAllocUsed,
}
impl<const PAGE_SIZE: usize> BitmapPageAllocator<PAGE_SIZE> {
pub const fn new() -> Self {
Self {
base: 0,
total_pages: 0,
used_pages: 0,
inner: BitAllocUsed::DEFAULT,
}
}
}
impl<const PAGE_SIZE: usize> BaseAllocator for BitmapPageAllocator<PAGE_SIZE> {
fn init(&mut self, start: usize, size: usize) {
assert!(PAGE_SIZE.is_power_of_two());
let end = super::align_down(start + size, PAGE_SIZE);
let start = super::align_up(start, PAGE_SIZE);
self.base = start;
self.total_pages = (end - start) / PAGE_SIZE;
self.inner.insert(0..self.total_pages);
}
fn add_memory(&mut self, _start: usize, _size: usize) -> AllocResult {
Err(AllocError::NoMemory) }
}
impl<const PAGE_SIZE: usize> PageAllocator for BitmapPageAllocator<PAGE_SIZE> {
const PAGE_SIZE: usize = PAGE_SIZE;
fn alloc_pages(&mut self, num_pages: usize, align_pow2: usize) -> AllocResult<usize> {
if align_pow2 % PAGE_SIZE != 0 {
return Err(AllocError::InvalidParam);
}
let align_pow2 = align_pow2 / PAGE_SIZE;
if !align_pow2.is_power_of_two() {
return Err(AllocError::InvalidParam);
}
let align_log2 = align_pow2.trailing_zeros() as usize;
match num_pages.cmp(&1) {
core::cmp::Ordering::Equal => self.inner.alloc().map(|idx| idx * PAGE_SIZE + self.base),
core::cmp::Ordering::Greater => self
.inner
.alloc_contiguous(num_pages, align_log2)
.map(|idx| idx * PAGE_SIZE + self.base),
_ => return Err(AllocError::InvalidParam),
}
.ok_or(AllocError::NoMemory)
.inspect(|_| self.used_pages += num_pages)
}
fn dealloc_pages(&mut self, pos: usize, num_pages: usize) {
self.used_pages -= num_pages;
self.inner.dealloc((pos - self.base) / PAGE_SIZE)
}
fn total_pages(&self) -> usize {
self.total_pages
}
fn used_pages(&self) -> usize {
self.used_pages
}
fn available_pages(&self) -> usize {
self.total_pages - self.used_pages
}
}