xref: /DragonOS/kernel/src/mm/allocator/slab.rs (revision 418ad41fd84c15ed7e132e56970150ac38fc24a9)
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