extern crate alloc;
extern crate object_alloc;
use {OBJECTS_PER_SLAB, PAGE_SIZE, stack};
use stack::{SlabHeader, Layout};
use init::InitSystem;
use self::alloc::allocator;
use self::object_alloc::UntypedObjectAlloc;
pub struct ConfigData;
impl stack::ConfigData for ConfigData {
fn ptr_to_slab(&self, slab_size: usize, ptr: *mut u8) -> *mut SlabHeader {
let slab = ptr as usize & !(slab_size - 1);
debug_assert_eq!(slab % slab_size, 0);
slab as *mut SlabHeader
}
}
pub type System<A> = stack::System<A, ConfigData>;
impl<A: UntypedObjectAlloc> System<A> {
pub fn new(layout: allocator::Layout, alloc: A) -> Option<System<A>> {
if let Some((slab_layout, _)) = Layout::for_slab_size(layout, alloc.layout().size()) {
Some(Self::from_config_data(ConfigData, slab_layout, alloc))
} else {
None
}
}
}
pub fn backing_size_for<I: InitSystem>(layout: &allocator::Layout) -> usize {
struct PowerOfTwoIterator(usize);
impl Iterator for PowerOfTwoIterator {
type Item = usize;
fn next(&mut self) -> Option<usize> {
if (self.0 << 1) == 0 {
None
} else {
self.0 *= 2;
Some(self.0)
}
}
}
let unused = |slab_size: usize| {
Layout::for_slab_size(layout.clone(), slab_size).map(|(layout, unused)| {
(layout.num_obj, unused)
})
};
::util::size::choose_size(PowerOfTwoIterator(*PAGE_SIZE), unused, OBJECTS_PER_SLAB)
}