From 9b8c1fe0112768e409a3a277c2817d617d1ff368 Mon Sep 17 00:00:00 2001 From: yufeng <321353225@qq.com> Date: Wed, 17 Apr 2024 16:19:21 +0800 Subject: [PATCH] feat: seperate sync and frame_allocator from kernel --- Cargo.lock | 2 + kernel/Cargo.toml | 4 +- modules/devfs/Cargo.toml | 2 +- modules/devices/Cargo.toml | 4 +- modules/executor/Cargo.toml | 4 +- modules/frame_allocator/Cargo.toml | 12 -- modules/frame_allocator/src/lib.rs | 281 ----------------------------- modules/fs/Cargo.toml | 4 +- modules/hal/Cargo.toml | 4 +- modules/logging/Cargo.toml | 2 +- modules/procfs/Cargo.toml | 2 +- modules/ramfs/Cargo.toml | 4 +- modules/sync/Cargo.toml | 9 - modules/sync/src/lib.rs | 117 ------------ 14 files changed, 17 insertions(+), 434 deletions(-) delete mode 100644 modules/frame_allocator/Cargo.toml delete mode 100644 modules/frame_allocator/src/lib.rs delete mode 100644 modules/sync/Cargo.toml delete mode 100644 modules/sync/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index f2126aa1..bc53474f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -314,6 +314,7 @@ checksum = "784a4df722dc6267a04af36895398f59d21d07dce47232adf31ec0ff2fa45e67" [[package]] name = "frame_allocator" version = "0.1.0" +source = "git+https://github.com/Byte-OS/bit_frame_allocator.git#7866e6f8ea3eb8677e089bb7c9c357caf3723873" dependencies = [ "arch", "bit_field", @@ -1076,6 +1077,7 @@ dependencies = [ [[package]] name = "sync" version = "0.1.0" +source = "git+https://github.com/Byte-OS/sync.git#8c5f094d85cd7f4574bb6035c87d94dc5dee3998" dependencies = [ "spin 0.9.8", ] diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index 98630d83..2ee1b73f 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -15,7 +15,7 @@ serde_derive = "1.0.136" [dependencies] allocator = { path = "../crates/allocator" } crate_interface = { git = "https://github.com/Byte-OS/crate_interface.git" } -frame_allocator = { path = "../modules/frame_allocator" } +frame_allocator = { git = "https://github.com/Byte-OS/bit_frame_allocator.git" } logging = { path = "../modules/logging" } log = "0.4" devices = { path = "../modules/devices" } @@ -25,7 +25,7 @@ fs = { path = "../modules/fs" } fdt = "0.1.5" executor = { path = "../modules/executor" } xmas-elf = "0.9.0" -sync = { path = "../modules/sync" } +sync = { git = "https://github.com/Byte-OS/sync.git" } bitflags = "2.0.2" signal = { git = "https://github.com/Byte-OS/signal.git" } bit_field = "0.10.1" diff --git a/modules/devfs/Cargo.toml b/modules/devfs/Cargo.toml index 529061a7..27ec397c 100644 --- a/modules/devfs/Cargo.toml +++ b/modules/devfs/Cargo.toml @@ -10,7 +10,7 @@ vfscore = { git = "https://github.com/Byte-OS/vfscore.git" } logging = { path = "../logging" } devices = { path = "../devices" } log = "0.4" -sync = { path = "../sync" } +sync = { git = "https://github.com/Byte-OS/sync.git" } bitflags = "2.0.2" num-traits = { version = "0.2", default-features = false} num-derive = "0.4" diff --git a/modules/devices/Cargo.toml b/modules/devices/Cargo.toml index 1a6314fd..74fc6ea6 100644 --- a/modules/devices/Cargo.toml +++ b/modules/devices/Cargo.toml @@ -12,7 +12,7 @@ arch = { git = "https://github.com/Byte-OS/arch.git" } fdt = "0.1.5" linkme = { version = "0.3.22", features = ["used_linker"] } log = "0.4" -sync = { path = "../sync" } +sync = { git = "https://github.com/Byte-OS/sync.git" } virtio-drivers = { git = "https://github.com/rcore-os/virtio-drivers", rev = "f1d1cbb"} -frame_allocator = { path = "../frame_allocator" } +frame_allocator = { git = "https://github.com/Byte-OS/bit_frame_allocator.git" } timestamp = { git = "https://github.com/Byte-OS/timestamp.git" } diff --git a/modules/executor/Cargo.toml b/modules/executor/Cargo.toml index 837d6ea0..a4525038 100644 --- a/modules/executor/Cargo.toml +++ b/modules/executor/Cargo.toml @@ -9,8 +9,8 @@ edition = "2021" crossbeam-queue = { version = "0.3.8", default-features = false, features = ["alloc"] } logging = { path = "../logging" } arch = { git = "https://github.com/Byte-OS/arch.git" } -sync = { path = "../sync" } -frame_allocator = { path = "../frame_allocator" } +sync = { git = "https://github.com/Byte-OS/sync.git" } +frame_allocator = { git = "https://github.com/Byte-OS/bit_frame_allocator.git" } log = "0.4" fs = { path = "../fs" } devfs = { path = "../devfs" } diff --git a/modules/frame_allocator/Cargo.toml b/modules/frame_allocator/Cargo.toml deleted file mode 100644 index 51f69e61..00000000 --- a/modules/frame_allocator/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "frame_allocator" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -bit_field = "0.10.1" -log = "0.4" -arch = { git = "https://github.com/Byte-OS/arch.git" } -sync = { path = "../sync" } \ No newline at end of file diff --git a/modules/frame_allocator/src/lib.rs b/modules/frame_allocator/src/lib.rs deleted file mode 100644 index 86c9e861..00000000 --- a/modules/frame_allocator/src/lib.rs +++ /dev/null @@ -1,281 +0,0 @@ -#![no_std] - -#[macro_use] -extern crate alloc; - -use core::mem::size_of; - -use alloc::vec::Vec; -use arch::addr::PhysPage; -use arch::{PAGE_SIZE, VIRT_ADDR_START}; -use bit_field::{BitArray, BitField}; -use log::info; -use sync::Mutex; - -pub const fn floor(a: usize, b: usize) -> usize { - (a + b - 1) / b -} - -pub const fn ceil_div(a: usize, b: usize) -> usize { - (a + b - 1) / b -} - -#[derive(Debug)] -/// 页帧 -/// -/// 用这个代表一个已经被分配的页表,并且利用 Drop 机制保证页表能够顺利被回收 -pub struct FrameTracker(pub PhysPage); - -impl FrameTracker { - pub fn new(ppn: PhysPage) -> Self { - Self(ppn) - } -} - -impl Drop for FrameTracker { - fn drop(&mut self) { - self.0.drop_clear(); - FRAME_ALLOCATOR.lock().dealloc(self.0); - } -} - -/// 页帧分布图 -/// -/// 利用页帧分布图保存页帧分配器中的空闲内存,并且利用 bitArray 记录页帧使用情况 -pub struct FrameRegionMap { - bits: Vec, - ppn: PhysPage, - ppn_end: PhysPage, -} - -impl FrameRegionMap { - /// 创建页帧分布图 - /// - /// start_addr: usize 空闲页帧起始地址 - /// end_addr: usize 空闲页帧结束地址 - #[inline] - pub fn new(start_addr: usize, end_addr: usize) -> Self { - let mut bits = vec![0usize; ceil_div((end_addr - start_addr) / PAGE_SIZE, 64)]; - - // set non-exists memory bit as 1 - for i in (end_addr - start_addr) / PAGE_SIZE..bits.len() * 64 { - bits.set_bit(i, true); - } - - Self { - bits, - ppn: PhysPage::from_addr(start_addr), - ppn_end: PhysPage::from_addr(end_addr), - } - } - - /// 获取页帧分布图中没有使用的页帧数量 - #[inline] - pub fn get_free_page_count(&self) -> usize { - self.bits.iter().fold(0, |mut sum, x| { - if *x == 0 { - sum + 64 - } else { - for i in 0..64 { - sum += match (*x).get_bit(i) { - true => 0, - false => 1, - }; - } - sum - } - }) - } - - /// 在 `bitArray` 指定位置获取一个空闲的页 - /// - /// index: usize 指定的位置 self.bits[index] - #[inline] - fn alloc_in_pos(&mut self, index: usize) -> Option { - for bit_index in 0..64 { - if !self.bits[index].get_bit(bit_index) { - self.bits[index].set_bit(bit_index, true); - return Some(self.ppn + index * 64 + bit_index); - } - } - None - } - - /// 申请一个空闲页 - #[inline] - pub fn alloc(&mut self) -> Option { - for i in 0..self.bits.len() { - if self.bits[i] != usize::MAX { - return self.alloc_in_pos(i); - } - } - None - } - - /// 申请多个空闲页, 空闲页是连续的 - /// - /// pages: usize 要申请的页表数量 - #[allow(unused_assignments)] - pub fn alloc_much(&mut self, pages: usize) -> Option> { - // TODO: alloc more than 64?; - // 优化本函数 - for mut i in 0..(usize::from(self.ppn_end) - usize::from(self.ppn) - pages + 1) { - let mut j = i; - loop { - if j - i >= pages { - let mut ans = Vec::new(); - (i..j).into_iter().for_each(|x| { - self.bits.set_bit(x, true); - ans.push(FrameTracker::new(self.ppn + x)); - }); - return Some(ans); - } - - if self.bits.get_bit(j) == true { - i = j + 1; - break; - } - - j += 1; - } - } - None - } - - /// 释放一个已经使用的页 - /// - /// ppn: PhysPage 要释放的页的地址 - #[inline] - pub fn dealloc(&mut self, ppn: PhysPage) { - self.bits - .set_bit(usize::from(ppn) - usize::from(self.ppn), false); - } -} - -/// 一个总的页帧分配器 -pub struct FrameAllocator(Vec); - -impl FrameAllocator { - /// 创建一个空闲的页帧分配器 - #[inline] - pub const fn new() -> Self { - Self(Vec::new()) - } - - /// 将一块内存放在页帧分配器上 - /// - /// start: usize 内存的起始地址 - /// end: usize 内存的结束地址 - #[inline] - pub fn add_memory_region(&mut self, start: usize, end: usize) { - self.0.push(FrameRegionMap::new(start, end)); - } - - /// 获取页帧分配器中空闲页表的数量 - /// - /// 也就是对所有的页帧分布图中的内存进行和运算 - #[inline] - pub fn get_free_page_count(&self) -> usize { - self.0 - .iter() - .fold(0, |sum, x| sum + x.get_free_page_count()) - } - - /// 申请一个空闲页 - #[inline] - pub fn alloc(&mut self) -> Option { - for frm in &mut self.0 { - let frame = frm.alloc(); - if frame.is_some() { - return frame; - } - } - None - } - - /// 申请多个空闲页, 空闲页是连续的 - /// - /// pages: usize 要申请的页表数量 - /// 在多个页表分布图里查找 - #[inline] - pub fn alloc_much(&mut self, pages: usize) -> Option> { - for frm in &mut self.0 { - let frame = frm.alloc_much(pages); - if frame.is_some() { - return frame; - } - } - None - } - - /// 释放一个页 - #[inline] - pub fn dealloc(&mut self, ppn: PhysPage) { - for frm in &mut self.0 { - if ppn >= frm.ppn && ppn < frm.ppn_end { - frm.dealloc(ppn); - break; - } - } - } -} - -/// 一个总的页帧分配器 -pub static FRAME_ALLOCATOR: Mutex = Mutex::new(FrameAllocator::new()); - -pub fn add_frame_map(mm_start: usize, mm_end: usize) { - extern "C" { - fn end(); - } - let phys_end = floor(end as usize, PAGE_SIZE) * PAGE_SIZE; - // let phys_end = floor(end as usize - VIRT_ADDR_START, PAGE_SIZE) * PAGE_SIZE; - if phys_end > mm_start && phys_end < mm_end { - info!("add frame memory region {:#x} - {:#x}", phys_end, mm_end); - unsafe { - core::slice::from_raw_parts_mut( - phys_end as *mut usize, - (mm_end - phys_end) / size_of::(), - ) - .fill(0); - }; - FRAME_ALLOCATOR - .lock() - .add_memory_region(phys_end - VIRT_ADDR_START, mm_end - VIRT_ADDR_START); - } -} - -/// 页帧分配器初始化 -pub fn init() { - info!("initialize frame allocator"); - - // 确保帧分配器一定能工作 - assert!( - FRAME_ALLOCATOR.lock().0.len() > 0, - "can't find frame to alloc" - ); -} - -/// 申请一个持久化存在的页表,需要手动释放 -pub unsafe fn frame_alloc_persist() -> Option { - FRAME_ALLOCATOR.lock().alloc() -} - -/// 手动释放一个页表 -pub unsafe fn frame_unalloc(ppn: PhysPage) { - FRAME_ALLOCATOR.lock().dealloc(ppn) -} - -/// 申请一个空闲页表 -pub fn frame_alloc() -> Option { - FRAME_ALLOCATOR.lock().alloc().map(FrameTracker) -} - -/// 申请多个空闲连续页表 -pub fn frame_alloc_much(pages: usize) -> Option> { - FRAME_ALLOCATOR.lock().alloc_much(pages) -} - -/// 获取空闲页表数量 -pub fn get_free_pages() -> usize { - FRAME_ALLOCATOR.lock().get_free_page_count() -} diff --git a/modules/fs/Cargo.toml b/modules/fs/Cargo.toml index 340b49ef..35dc9618 100644 --- a/modules/fs/Cargo.toml +++ b/modules/fs/Cargo.toml @@ -8,13 +8,13 @@ edition = "2021" [dependencies] log = "0.4" vfscore = { git = "https://github.com/Byte-OS/vfscore.git" } -sync = { path = "../sync" } +sync = { git = "https://github.com/Byte-OS/sync.git" } devices = { path = "../devices" } logging = { path = "../logging" } devfs = { path = "../devfs" } ramfs = { path = "../ramfs" } procfs = { path = "../procfs" } -frame_allocator = { path = "../frame_allocator" } +frame_allocator = { git = "https://github.com/Byte-OS/bit_frame_allocator.git" } arch = { git = "https://github.com/Byte-OS/arch.git" } [dependencies.fatfs] diff --git a/modules/hal/Cargo.toml b/modules/hal/Cargo.toml index 07730ff4..9b38f18e 100644 --- a/modules/hal/Cargo.toml +++ b/modules/hal/Cargo.toml @@ -8,6 +8,6 @@ edition = "2021" [dependencies] arch = { git = "https://github.com/Byte-OS/arch.git" } log = "0.4" -frame_allocator = { path = "../frame_allocator" } +frame_allocator = { git = "https://github.com/Byte-OS/bit_frame_allocator.git" } devices = { path = "../devices" } -sync = { path = "../sync" } \ No newline at end of file +sync = { git = "https://github.com/Byte-OS/sync.git" } diff --git a/modules/logging/Cargo.toml b/modules/logging/Cargo.toml index 1e6edbd1..25e4a01b 100644 --- a/modules/logging/Cargo.toml +++ b/modules/logging/Cargo.toml @@ -9,4 +9,4 @@ edition = "2021" log = "0.4" arch = { git = "https://github.com/Byte-OS/arch.git" } devices = { path = "../devices" } -sync = { path = "../sync" } +sync = { git = "https://github.com/Byte-OS/sync.git" } \ No newline at end of file diff --git a/modules/procfs/Cargo.toml b/modules/procfs/Cargo.toml index e3f0a224..08b6786a 100644 --- a/modules/procfs/Cargo.toml +++ b/modules/procfs/Cargo.toml @@ -7,6 +7,6 @@ edition = "2021" [dependencies] vfscore = { git = "https://github.com/Byte-OS/vfscore.git" } -sync = { path = "../sync" } +sync = { git = "https://github.com/Byte-OS/sync.git" } arch = { git = "https://github.com/Byte-OS/arch.git" } log = "0.4" \ No newline at end of file diff --git a/modules/ramfs/Cargo.toml b/modules/ramfs/Cargo.toml index 498ef05a..c3825be8 100644 --- a/modules/ramfs/Cargo.toml +++ b/modules/ramfs/Cargo.toml @@ -8,6 +8,6 @@ edition = "2021" [dependencies] vfscore = { git = "https://github.com/Byte-OS/vfscore.git" } log = "0.4" -sync = { path = "../sync" } -frame_allocator = { path = "../frame_allocator" } +sync = { git = "https://github.com/Byte-OS/sync.git" } +frame_allocator = { git = "https://github.com/Byte-OS/bit_frame_allocator.git" } arch = { git = "https://github.com/Byte-OS/arch.git" } diff --git a/modules/sync/Cargo.toml b/modules/sync/Cargo.toml deleted file mode 100644 index 15379fc6..00000000 --- a/modules/sync/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "sync" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -spin = { version = "0.9.8", features = ["mutex"] } diff --git a/modules/sync/src/lib.rs b/modules/sync/src/lib.rs deleted file mode 100644 index d3f48c96..00000000 --- a/modules/sync/src/lib.rs +++ /dev/null @@ -1,117 +0,0 @@ -#![no_std] - -pub use spin::{ - lazy::Lazy, Mutex, MutexGuard, RwLock, RwLockReadGuard, RwLockUpgradableGuard, RwLockWriteGuard, -}; - -use core::cell::UnsafeCell; -use core::fmt; -use core::mem::MaybeUninit; -use core::ops::{Deref, DerefMut}; -use core::sync::atomic::{AtomicBool, Ordering}; - -pub struct LazyInit { - inited: AtomicBool, - data: UnsafeCell>, -} - -unsafe impl Sync for LazyInit {} -unsafe impl Send for LazyInit {} - -impl LazyInit { - pub const fn new() -> Self { - Self { - inited: AtomicBool::new(false), - data: UnsafeCell::new(MaybeUninit::uninit()), - } - } - - pub fn init_by(&self, data: T) { - assert!(!self.is_init()); - unsafe { (*self.data.get()).as_mut_ptr().write(data) }; - self.inited.store(true, Ordering::Release); - } - - pub fn is_init(&self) -> bool { - self.inited.load(Ordering::Acquire) - } - - pub fn try_get(&self) -> Option<&T> { - if self.is_init() { - unsafe { Some(&*(*self.data.get()).as_ptr()) } - } else { - None - } - } - - fn check_init(&self) { - if !self.is_init() { - panic!( - "Use uninitialized value: {:?}", - core::any::type_name::() - ) - } - } - - #[inline] - fn get(&self) -> &T { - self.check_init(); - unsafe { self.get_unchecked() } - } - - #[inline] - fn get_mut(&mut self) -> &mut T { - self.check_init(); - unsafe { self.get_mut_unchecked() } - } - - /// # Safety - /// - /// Must be called after initialization. - #[inline] - pub unsafe fn get_unchecked(&self) -> &T { - &*(*self.data.get()).as_ptr() - } - - /// # Safety - /// - /// Must be called after initialization. - #[inline] - pub unsafe fn get_mut_unchecked(&mut self) -> &mut T { - &mut *(*self.data.get()).as_mut_ptr() - } -} - -impl fmt::Debug for LazyInit { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self.try_get() { - Some(s) => write!(f, "LazyInit {{ data: ") - .and_then(|()| s.fmt(f)) - .and_then(|()| write!(f, "}}")), - None => write!(f, "LazyInit {{ }}"), - } - } -} - -impl Deref for LazyInit { - type Target = T; - #[inline] - fn deref(&self) -> &T { - self.get() - } -} - -impl DerefMut for LazyInit { - #[inline] - fn deref_mut(&mut self) -> &mut T { - self.get_mut() - } -} - -impl Drop for LazyInit { - fn drop(&mut self) { - if self.is_init() { - unsafe { core::ptr::drop_in_place((*self.data.get()).as_mut_ptr()) }; - } - } -}