use crate::include::bindings::bindings::{gfp_t, kfree, kmalloc, PAGE_2M_SIZE}; use super::gfp::__GFP_ZERO; use core::alloc::{GlobalAlloc, Layout}; /// 类kmalloc的分配器应当实现的trait pub trait LocalAlloc { unsafe fn local_alloc(&self, layout: Layout, gfp: gfp_t) -> *mut u8; unsafe fn local_alloc_zeroed(&self, layout: Layout, gfp: gfp_t) -> *mut u8; unsafe fn local_dealloc(&self, ptr: *mut u8, layout: Layout); } pub struct KernelAllocator {} /// 为内核SLAB分配器实现LocalAlloc的trait impl LocalAlloc for KernelAllocator { unsafe fn local_alloc(&self, layout: Layout, gfp: gfp_t) -> *mut u8 { if layout.size() > (PAGE_2M_SIZE as usize / 2) { return core::ptr::null_mut(); } return kmalloc(layout.size() as u64, gfp) as *mut u8; } unsafe fn local_alloc_zeroed(&self, layout: Layout, gfp: gfp_t) -> *mut u8 { if layout.size() > (PAGE_2M_SIZE as usize / 2) { return core::ptr::null_mut(); } return kmalloc(layout.size() as u64, gfp | __GFP_ZERO) as *mut u8; } #[allow(unused_variables)] unsafe fn local_dealloc(&self, ptr: *mut u8, layout: Layout) { kfree(ptr as *mut ::core::ffi::c_void); } } /// 为内核slab分配器实现GlobalAlloc特性 unsafe impl GlobalAlloc for KernelAllocator { unsafe fn alloc(&self, layout: Layout) -> *mut u8 { self.local_alloc(layout, 0) } unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { self.local_alloc_zeroed(layout, 0) } unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { self.local_dealloc(ptr, layout); } } /// 内存分配错误处理函数 #[alloc_error_handler] pub fn global_alloc_err_handler(_layout: Layout) -> ! { panic!("global_alloc_error"); }