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