1 //! 当前slab分配器暂时不使用,等待后续完善后合并主线 2 #![allow(dead_code)] 3 4 use core::{alloc::Layout, ptr::NonNull, sync::atomic::AtomicBool}; 5 6 use alloc::boxed::Box; 7 use slabmalloc::*; 8 9 // 全局slab分配器 10 pub(crate) static mut SLABALLOCATOR: Option<SlabAllocator> = None; 11 12 // slab初始化状态 13 pub(crate) static mut SLABINITSTATE: AtomicBool = AtomicBool::new(false); 14 15 /// slab分配器,实际为一堆小的allocator,可以在里面装4K的page 16 /// 利用这些allocator可以为对象分配不同大小的空间 17 pub(crate) struct SlabAllocator { 18 zone: ZoneAllocator<'static>, 19 } 20 21 impl SlabAllocator { 22 /// 创建slab分配器 23 pub fn new() -> SlabAllocator { 24 kdebug!("trying to new a slab_allocator"); 25 SlabAllocator { 26 zone: ZoneAllocator::new(), 27 } 28 } 29 30 /// 为对象(2K以内)分配内存空间 31 pub(crate) unsafe fn allocate(&mut self, layout: Layout) -> *mut u8 { 32 match self.zone.allocate(layout) { 33 Ok(nptr) => nptr.as_ptr(), 34 Err(AllocationError::OutOfMemory) => { 35 let boxed_page = ObjectPage::new(); 36 let leaked_page = Box::leak(boxed_page); 37 self.zone 38 .refill(layout, leaked_page) 39 .expect("Could not refill?"); 40 self.zone 41 .allocate(layout) 42 .expect("Should succeed after refill") 43 .as_ptr() 44 } 45 Err(AllocationError::InvalidLayout) => panic!("Can't allocate this size"), 46 } 47 } 48 49 /// 释放内存空间 50 pub(crate) unsafe fn deallocate( 51 &mut self, 52 ptr: *mut u8, 53 layout: Layout, 54 ) -> Result<(), AllocationError> { 55 if let Some(nptr) = NonNull::new(ptr) { 56 self.zone 57 .deallocate(nptr, layout) 58 .expect("Couldn't deallocate"); 59 return Ok(()); 60 } else { 61 return Ok(()); 62 } 63 } 64 } 65 66 /// 初始化slab分配器 67 pub unsafe fn slab_init() { 68 kdebug!("trying to init a slab_allocator"); 69 SLABALLOCATOR = Some(SlabAllocator::new()); 70 SLABINITSTATE = true.into(); 71 } 72 73 // 查看slab初始化状态 74 pub fn slab_init_state() -> bool { 75 unsafe { *SLABINITSTATE.get_mut() } 76 } 77