mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-20 22:36:31 +00:00
feat: 释放slab中的空闲页面到buddy (#932)
* patch: 释放slab中的空闲页面到buddy * 校验释放的slab_page的起始地址与大小 & SCAllcator增加空闲块计数器
This commit is contained in:
@ -51,7 +51,7 @@ impl KernelAllocator {
|
||||
return Ok(NonNull::from(slice));
|
||||
}
|
||||
|
||||
unsafe fn free_in_buddy(&self, ptr: *mut u8, layout: Layout) {
|
||||
pub(super) unsafe fn free_in_buddy(&self, ptr: *mut u8, layout: Layout) {
|
||||
// 由于buddy分配的页数量是2的幂,因此释放的时候也需要按照2的幂向上取整。
|
||||
let count = (page_align_up(layout.size()) / MMArch::PAGE_SIZE).next_power_of_two();
|
||||
let page_frame_count = PageFrameCount::new(count);
|
||||
|
@ -4,12 +4,16 @@ use alloc::boxed::Box;
|
||||
use log::debug;
|
||||
use slabmalloc::*;
|
||||
|
||||
use crate::{arch::MMArch, mm::MemoryManagementArch, KERNEL_ALLOCATOR};
|
||||
|
||||
// 全局slab分配器
|
||||
pub(crate) static mut SLABALLOCATOR: Option<SlabAllocator> = None;
|
||||
|
||||
// slab初始化状态
|
||||
pub(crate) static mut SLABINITSTATE: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
static SLAB_CALLBACK: SlabCallback = SlabCallback;
|
||||
|
||||
/// slab分配器,实际为一堆小的allocator,可以在里面装4K的page
|
||||
/// 利用这些allocator可以为对象分配不同大小的空间
|
||||
pub(crate) struct SlabAllocator {
|
||||
@ -52,7 +56,7 @@ impl SlabAllocator {
|
||||
) -> Result<(), AllocationError> {
|
||||
if let Some(nptr) = NonNull::new(ptr) {
|
||||
self.zone
|
||||
.deallocate(nptr, layout)
|
||||
.deallocate(nptr, layout, &SLAB_CALLBACK)
|
||||
.expect("Couldn't deallocate");
|
||||
return Ok(());
|
||||
} else {
|
||||
@ -80,3 +84,13 @@ pub unsafe fn slab_usage() -> SlabUsage {
|
||||
SlabUsage::new(0, 0)
|
||||
}
|
||||
}
|
||||
|
||||
/// 归还slab_page给buddy的回调
|
||||
pub struct SlabCallback;
|
||||
impl CallBack for SlabCallback {
|
||||
unsafe fn free_slab_page(&self, base_addr: *mut u8, size: usize) {
|
||||
assert_eq!(base_addr as usize & (MMArch::PAGE_SIZE - 1), 0); // 确认地址4k对齐
|
||||
assert_eq!(size, MMArch::PAGE_SIZE); // 确认释放的slab_page大小
|
||||
KERNEL_ALLOCATOR.free_in_buddy(base_addr, Layout::from_size_align_unchecked(size, 1));
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user