1 use super::gfp::__GFP_ZERO;
2 use crate::include::bindings::bindings::{gfp_t, kfree, kmalloc, PAGE_2M_SIZE};
3 
4 use core::alloc::{GlobalAlloc, Layout};
5 
6 /// 类kmalloc的分配器应当实现的trait
7 pub trait LocalAlloc {
local_alloc(&self, layout: Layout, gfp: gfp_t) -> *mut u88     unsafe fn local_alloc(&self, layout: Layout, gfp: gfp_t) -> *mut u8;
local_alloc_zeroed(&self, layout: Layout, gfp: gfp_t) -> *mut u89     unsafe fn local_alloc_zeroed(&self, layout: Layout, gfp: gfp_t) -> *mut u8;
local_dealloc(&self, ptr: *mut u8, layout: Layout)10     unsafe fn local_dealloc(&self, ptr: *mut u8, layout: Layout);
11 }
12 
13 pub struct KernelAllocator {}
14 
15 /// 为内核SLAB分配器实现LocalAlloc的trait
16 impl LocalAlloc for KernelAllocator {
local_alloc(&self, layout: Layout, gfp: gfp_t) -> *mut u817     unsafe fn local_alloc(&self, layout: Layout, gfp: gfp_t) -> *mut u8 {
18         if layout.size() > (PAGE_2M_SIZE as usize / 2) {
19             return core::ptr::null_mut();
20         }
21         return kmalloc(layout.size() as u64, gfp) as *mut u8;
22     }
23 
local_alloc_zeroed(&self, layout: Layout, gfp: gfp_t) -> *mut u824     unsafe fn local_alloc_zeroed(&self, layout: Layout, gfp: gfp_t) -> *mut u8 {
25         if layout.size() > (PAGE_2M_SIZE as usize / 2) {
26             return core::ptr::null_mut();
27         }
28         return kmalloc(layout.size() as u64, gfp | __GFP_ZERO) as *mut u8;
29     }
30     #[allow(unused_variables)]
local_dealloc(&self, ptr: *mut u8, layout: Layout)31     unsafe fn local_dealloc(&self, ptr: *mut u8, layout: Layout) {
32         kfree(ptr as *mut ::core::ffi::c_void);
33     }
34 }
35 
36 /// 为内核slab分配器实现GlobalAlloc特性
37 unsafe impl GlobalAlloc for KernelAllocator {
alloc(&self, layout: Layout) -> *mut u838     unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
39         self.local_alloc(layout, 0)
40     }
41 
alloc_zeroed(&self, layout: Layout) -> *mut u842     unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
43         self.local_alloc_zeroed(layout, 0)
44     }
45 
dealloc(&self, ptr: *mut u8, layout: Layout)46     unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
47         self.local_dealloc(ptr, layout);
48     }
49 }
50 
51 /// 内存分配错误处理函数
52 #[alloc_error_handler]
global_alloc_err_handler(layout: Layout) -> !53 pub fn global_alloc_err_handler(layout: Layout) -> ! {
54     panic!("global_alloc_error, layout: {:?}", layout);
55 }
56