xref: /DragonOS/kernel/src/mm/allocator/slab.rs (revision 2eab6dd743e94a86a685f1f3c01e599adf86610a)
1ceeb2e94Slaokengwt use core::{alloc::Layout, ptr::NonNull, sync::atomic::AtomicBool};
240fe15e0SLoGin 
3ceeb2e94Slaokengwt use alloc::boxed::Box;
4*2eab6dd7S曾俊 use log::debug;
5ceeb2e94Slaokengwt use slabmalloc::*;
6ceeb2e94Slaokengwt 
7ceeb2e94Slaokengwt // 全局slab分配器
8ceeb2e94Slaokengwt pub(crate) static mut SLABALLOCATOR: Option<SlabAllocator> = None;
9ceeb2e94Slaokengwt 
10ceeb2e94Slaokengwt // slab初始化状态
11ceeb2e94Slaokengwt pub(crate) static mut SLABINITSTATE: AtomicBool = AtomicBool::new(false);
12ceeb2e94Slaokengwt 
13ceeb2e94Slaokengwt /// slab分配器,实际为一堆小的allocator,可以在里面装4K的page
14ceeb2e94Slaokengwt /// 利用这些allocator可以为对象分配不同大小的空间
15ceeb2e94Slaokengwt pub(crate) struct SlabAllocator {
16ceeb2e94Slaokengwt     zone: ZoneAllocator<'static>,
1740fe15e0SLoGin }
1840fe15e0SLoGin 
19ceeb2e94Slaokengwt impl SlabAllocator {
20ceeb2e94Slaokengwt     /// 创建slab分配器
new() -> SlabAllocator21ceeb2e94Slaokengwt     pub fn new() -> SlabAllocator {
22*2eab6dd7S曾俊         debug!("trying to new a slab_allocator");
23ceeb2e94Slaokengwt         SlabAllocator {
24ceeb2e94Slaokengwt             zone: ZoneAllocator::new(),
2540fe15e0SLoGin         }
2640fe15e0SLoGin     }
2740fe15e0SLoGin 
28ceeb2e94Slaokengwt     /// 为对象(2K以内)分配内存空间
allocate(&mut self, layout: Layout) -> *mut u829ceeb2e94Slaokengwt     pub(crate) unsafe fn allocate(&mut self, layout: Layout) -> *mut u8 {
30ceeb2e94Slaokengwt         match self.zone.allocate(layout) {
31ceeb2e94Slaokengwt             Ok(nptr) => nptr.as_ptr(),
32ceeb2e94Slaokengwt             Err(AllocationError::OutOfMemory) => {
33ceeb2e94Slaokengwt                 let boxed_page = ObjectPage::new();
34ceeb2e94Slaokengwt                 let leaked_page = Box::leak(boxed_page);
35ceeb2e94Slaokengwt                 self.zone
36ceeb2e94Slaokengwt                     .refill(layout, leaked_page)
37ceeb2e94Slaokengwt                     .expect("Could not refill?");
38ceeb2e94Slaokengwt                 self.zone
39ceeb2e94Slaokengwt                     .allocate(layout)
40ceeb2e94Slaokengwt                     .expect("Should succeed after refill")
41ceeb2e94Slaokengwt                     .as_ptr()
42ceeb2e94Slaokengwt             }
43ceeb2e94Slaokengwt             Err(AllocationError::InvalidLayout) => panic!("Can't allocate this size"),
4440fe15e0SLoGin         }
4540fe15e0SLoGin     }
4640fe15e0SLoGin 
47ceeb2e94Slaokengwt     /// 释放内存空间
deallocate( &mut self, ptr: *mut u8, layout: Layout, ) -> Result<(), AllocationError>48ceeb2e94Slaokengwt     pub(crate) unsafe fn deallocate(
49ceeb2e94Slaokengwt         &mut self,
50ceeb2e94Slaokengwt         ptr: *mut u8,
51ceeb2e94Slaokengwt         layout: Layout,
52ceeb2e94Slaokengwt     ) -> Result<(), AllocationError> {
53ceeb2e94Slaokengwt         if let Some(nptr) = NonNull::new(ptr) {
54ceeb2e94Slaokengwt             self.zone
55ceeb2e94Slaokengwt                 .deallocate(nptr, layout)
56ceeb2e94Slaokengwt                 .expect("Couldn't deallocate");
57ceeb2e94Slaokengwt             return Ok(());
58ceeb2e94Slaokengwt         } else {
59ceeb2e94Slaokengwt             return Ok(());
60ceeb2e94Slaokengwt         }
61ceeb2e94Slaokengwt     }
6240fe15e0SLoGin }
6340fe15e0SLoGin 
64ceeb2e94Slaokengwt /// 初始化slab分配器
slab_init()65ceeb2e94Slaokengwt pub unsafe fn slab_init() {
66*2eab6dd7S曾俊     debug!("trying to init a slab_allocator");
67ceeb2e94Slaokengwt     SLABALLOCATOR = Some(SlabAllocator::new());
68ceeb2e94Slaokengwt     SLABINITSTATE = true.into();
6940fe15e0SLoGin }
70ceeb2e94Slaokengwt 
71ceeb2e94Slaokengwt // 查看slab初始化状态
slab_init_state() -> bool72ceeb2e94Slaokengwt pub fn slab_init_state() -> bool {
73ceeb2e94Slaokengwt     unsafe { *SLABINITSTATE.get_mut() }
7440fe15e0SLoGin }
757401bec5Slaokengwt 
slab_usage() -> SlabUsage767401bec5Slaokengwt pub unsafe fn slab_usage() -> SlabUsage {
777401bec5Slaokengwt     if let Some(ref mut slab) = SLABALLOCATOR {
787401bec5Slaokengwt         slab.zone.usage()
797401bec5Slaokengwt     } else {
807401bec5Slaokengwt         SlabUsage::new(0, 0)
817401bec5Slaokengwt     }
827401bec5Slaokengwt }
83