use crate::{system_table, MemoryType};
use core::alloc::{GlobalAlloc, Layout};
use core::mem::size_of;
use core::ptr::{null_mut, read_unaligned, write_unaligned};
pub struct PoolAllocator;
unsafe impl GlobalAlloc for PoolAllocator {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
let mut size = if layout.align() <= 8 {
layout.size()
} else {
layout.size() + (layout.align() - 8)
};
size += size_of::<usize>();
let mem = system_table()
.boot_services()
.allocate_pool(MemoryType::LoaderData, size)
.unwrap_or(null_mut());
if mem.is_null() {
return null_mut();
}
let misaligned = (mem as usize) % layout.align();
let adjust = if misaligned == 0 {
0
} else {
layout.align() - misaligned
};
let mem = mem.add(adjust);
write_unaligned(mem.add(layout.size()) as *mut usize, adjust);
mem
}
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
let adjusted = read_unaligned(ptr.add(layout.size()) as *const usize);
let ptr = ptr.sub(adjusted);
system_table().boot_services().free_pool(ptr).unwrap();
}
}