Skip to content

Commit

Permalink
Add slab free space calculation and add it to freeram of sysinfo
Browse files Browse the repository at this point in the history
  • Loading branch information
laokengwt committed Apr 25, 2024
1 parent 93c3797 commit a03cebf
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 8 deletions.
39 changes: 34 additions & 5 deletions kernel/crates/rust-slabmalloc/src/zone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
//! The ZoneAllocator achieves this by having many `SCAllocator`
use crate::*;
use core::sync::atomic::Ordering;

/// Creates an instance of a zone, we do this in a macro because we
/// re-use the code in const and non-const functions
Expand Down Expand Up @@ -52,14 +53,10 @@ enum Slab {
}

impl<'a> ZoneAllocator<'a> {
/// Maximum size that allocated within LargeObjectPages (2 MiB).
/// This is also the maximum object size that this allocator can handle.
pub const MAX_ALLOC_SIZE: usize = 1 << 11;

/// Maximum size which is allocated with ObjectPages (4 KiB pages).
///
/// e.g. this is 4 KiB - 80 bytes of meta-data.
pub const MAX_BASE_ALLOC_SIZE: usize = 256;
pub const MAX_BASE_ALLOC_SIZE: usize = 1 << 11;

/// How many allocators of type SCAllocator<ObjectPage> we have.
const MAX_BASE_SIZE_CLASSES: usize = 9;
Expand Down Expand Up @@ -126,6 +123,38 @@ impl<'a> ZoneAllocator<'a> {
}
}
}

/// 获取scallocator中的还未被分配的空间
pub fn usage(&mut self) -> u64 {
// 记录空闲空间
let mut free = 0;
// scallocator的数量
let mut count = 0;

// 遍历所有scallocator
while count < 9 {
// 获取scallocator
let scallocator = &mut self.small_slabs[count];
// 遍历scallocator中的部分分配的page(partial_page)
for slab_page in scallocator.slabs.iter_mut() {
// 每个page的obj_per_page,即每个page的最大object数,这里用来赋值给obj_count
// 用来统计page中还可以分配多少个object
let mut obj_count = scallocator.obj_per_page;
// 遍历page中的bitfield(用来统计内存分配情况的u64数组)
for (_base_idx, b) in slab_page.bitfield().iter().enumerate() {
let bitval = b.load(Ordering::Relaxed);
let negated = !bitval;
let allocated_count = negated.trailing_zeros() as usize;
// 减去已分配的object数
obj_count -= allocated_count;
}
// 剩余可分配object数乘上page中规定的每个object的大小,即空闲空间
free += obj_count * scallocator.size();
}
count -= 1;
}
free as u64
}
}

unsafe impl<'a> crate::Allocator<'a> for ZoneAllocator<'a> {
Expand Down
11 changes: 10 additions & 1 deletion kernel/src/mm/allocator/slab.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! 当前slab分配器暂时不使用,等待后续完善后合并主线
#![allow(dead_code)]

use core::{alloc::Layout, ptr::NonNull, sync::atomic::AtomicBool};
use core::{alloc::Layout, panic, ptr::NonNull, sync::atomic::AtomicBool};

use alloc::boxed::Box;
use slabmalloc::*;
Expand Down Expand Up @@ -63,6 +63,15 @@ impl SlabAllocator {
}
}

/// 获取slab中的空闲空间
pub unsafe fn slab_usage() -> u64 {
if let Some(ref mut slab) = SLABALLOCATOR {
slab.zone.usage()
} else {
panic!("slab hasn't been initialized")
}
}

/// 初始化slab分配器
pub unsafe fn slab_init() {
kdebug!("trying to init a slab_allocator");
Expand Down
5 changes: 3 additions & 2 deletions kernel/src/syscall/misc.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{
arch::{mm::LockedFrameAllocator, rand::rand},
libs::rand::GRandFlags,
mm::allocator::page_frame::FrameAllocator,
mm::allocator::{page_frame::FrameAllocator, slab::slab_usage},
};
use alloc::vec::Vec;
use core::cmp;
Expand Down Expand Up @@ -38,10 +38,11 @@ impl Syscall {
let mut sysinfo = SysInfo::default();

let mem = unsafe { LockedFrameAllocator.usage() };
let slab_free = unsafe { slab_usage() };
sysinfo.uptime = 0;
sysinfo.loads = [0; 3];
sysinfo.totalram = mem.total().bytes() as u64;
sysinfo.freeram = mem.free().bytes() as u64;
sysinfo.freeram = mem.free().bytes() as u64 + slab_free;
sysinfo.sharedram = 0;
sysinfo.bufferram = 0;
sysinfo.totalswap = 0;
Expand Down

0 comments on commit a03cebf

Please sign in to comment.