add some comment and update readme

This commit is contained in:
SKTT1Ryze 2021-05-26 22:30:33 +08:00
parent 3491062cbe
commit b21c752d76
14 changed files with 24 additions and 33 deletions

View File

@ -4,7 +4,7 @@
## 基于共享调度器的异步内核设计
操作系统内核经历了几个主要的发展阶段,从裸机应用,批处理系统到多道任务系统,演变为至今主流的线程操作系统。这种系统基于线程的切换来调度任务;为了进一步提升性能,一些现代编程语言在应用层复用线程资源,提出了“协程的”的概念,节省任务调度的开销。
在本项目中我们提出一种新的内核开发思想:由不同资源共享调度器,在操作系统层面提供协程。我们希望这种全新设计的内核在满足传统内核的易用性的同时,拥有着专有内核的高性能特点,“像风一样快”,因此取名**飓风内核**——**tornado-os**。
设计文档请参考[这里](https://qf.rs/2021/04/23/%E5%BC%82%E6%AD%A5%E5%86%85%E6%A0%B8%E7%9A%84%E8%AE%BE%E8%AE%A1%E4%B8%8E%E5%AE%9E%E7%8E%B0.html)
## 如何运行
依赖工具:
+ Rust 环境(nightly-2021-03-01或以上)
@ -36,3 +36,5 @@ just qemu user_task
+ [异步virtio块设备驱动](https://github.com/HUST-OS/async-virtio-driver)
其中,`洛佳的异步内核实验室`中实现了一个**内核中的生成器语法**,非常有研究价值,欢迎访问博客[执行器与生成语义](https://qf.rs/2021/05/01/%E6%89%A7%E8%A1%8C%E5%99%A8%E4%B8%8E%E7%94%9F%E6%88%90%E8%AF%AD%E4%B9%89.html)
另外,我们还初步实现了一款基于 Rust 语言异步语法的 virtio 块设备驱动库,并可以结合本项目以异步的方式运行块设备读写任务,详细内容请访问博客[异步版VIRTIO之块设备驱动实现](https://qf.rs/2021/05/26/%E5%BC%82%E6%AD%A5%E7%89%88virtio%E5%9D%97%E8%AE%BE%E5%A4%87%E9%A9%B1%E5%8A%A8%E5%AE%9E%E7%8E%B0.html)

View File

@ -4,14 +4,14 @@ mod ring_fifo;
pub use ring_fifo::RingFifoScheduler;
/// 调度器实例需要实现的 Trait
///
pub trait Scheduler<T: Clone + PartialEq> {
/// 优先级的类型
type Priority;
/// 向调度器中添加一个任务,成功返回 None不成功返回 Some(T)
fn add_task(&mut self, task: T) -> Option<T>;
/// 获取下一个任务的引用,但不弹出任务
/// 获取下一个任务的不可变引用,但不弹出任务
fn peek_next_task(&self) -> Option<&T>;
/// 获取下一个任务的可变引用,但不弹出任务
fn peek_next_task_mut(&mut self) -> Option<&mut T>;
/// 弹出下一个时间段应当执行的任务
fn next_task(&mut self) -> Option<T>;

View File

@ -23,6 +23,7 @@ impl<T, const N: usize> RingFifoScheduler<T, N> {
impl<T: Clone + PartialEq, const N: usize> Scheduler<T> for RingFifoScheduler<T, N> {
type Priority = ();
/// 添加任务
fn add_task(&mut self, task: T) -> Option<T> {
// 加入环形队列
let ans = self.ring.push_back(task);
@ -32,28 +33,34 @@ impl<T: Clone + PartialEq, const N: usize> Scheduler<T> for RingFifoScheduler<T,
}
None
}
/// 取出下一个任务,成功返回 Some(T)
fn next_task(&mut self) -> Option<T> {
// 从头部取出
let ans = self.ring.pop_front();
self.current = ans.clone();
ans
}
/// 拿出下一个任务的不可变引用,不弹出
fn peek_next_task(&self) -> Option<&T> {
// 拿出头部的引用
self.ring.front()
}
/// 拿出下一个任务的可变引用,不弹出
fn peek_next_task_mut(&mut self) -> Option<&mut T> {
self.ring.front_mut()
}
/// 获取当前任务
fn current_task(&self) -> Option<T> {
self.current.clone()
}
/// 移除一个特定的任务
fn remove_task(&mut self, task: &T) {
// 移除相应的线程并且确认恰移除一个线程
drop(task);
todo!("还没做")
}
/// 设置任务优先级
fn set_priority(&mut self, _task: T, _prio: ()) {}
/// 当前调度器的任务数,如果是队列实现则返回 Some(T)
fn queue_len(&self) -> Option<usize> {
Some(self.ring.len())
}

View File

@ -45,7 +45,6 @@ pub fn panic_handler(panic_info: &core::panic::PanicInfo) -> ! {
}
// todo: 未来尽量使用有Allocator的new_in函数这样能处理内存不足的问题
#[cfg_attr(not(test), alloc_error_handler)]
pub fn handle_alloc_error(layout: core::alloc::Layout) -> ! {
println!("[shared scheduler] alloc error, layout = {:?}", layout);

View File

@ -2,6 +2,7 @@ use super::Allocator;
use alloc::{vec, vec::Vec};
use core::ops::Range;
/// 栈分配器
pub struct StackedAllocator {
list: Vec<Range<usize>>,
}

View File

@ -94,7 +94,7 @@ pub extern "C" fn rust_main(hart_id: usize) -> ! {
println!("Current hart: {}", hart::KernelHartInfo::hart_id());
// todo: 这里要有个地方往tp里写东西目前会出错
// todo: 这里要有个地方往tp里写东西否则目前会出错
let kernel_memory = memory::MemorySet::new_kernel().expect("create kernel memory set");
kernel_memory.activate();

View File

@ -4,7 +4,6 @@ use riscv::register::{sepc, stval};
use crate::{memory::{self, Satp}, trap::SwapContext};
use crate::trap;
use super::{SyscallResult, syscall};
use alloc::vec::Vec;
/// 测试用的中断处理函数,用户态发生中断会陷入到这里
pub extern "C" fn user_trap_handler() {

View File

@ -8,6 +8,7 @@ use core::{mem, task::{Poll, Context}};
*/
/// 内核态的执行器,不断轮询共享调度器中的任务
pub fn run_until_idle(
peek_task: impl Fn() -> TaskResult,
delete_task: impl Fn(usize) -> bool,
@ -17,9 +18,10 @@ pub fn run_until_idle(
let task = peek_task();
println!(">>> kernel executor: next task = {:x?}", task);
match task {
TaskResult::Task(task_repr) => { // 在相同的(内核)地址空间里面
TaskResult::Task(task_repr) => { // 轮询到的任务在相同的(内核)地址空间里面
set_task_state(task_repr, TaskState::Sleeping);
let task: Arc<KernelTaskRepr> = unsafe { Arc::from_raw(task_repr as *mut _) };
// 注册 waker
let waker = waker_ref(&task);
let mut context = Context::from_waker(&*waker);
let ret = task.task().future.lock().as_mut().poll(&mut context);
@ -33,8 +35,10 @@ pub fn run_until_idle(
todo!("切换到 next_asid (= {}) 对应的地址空间", next_asid)
},
TaskResult::NoWakeTask => {
// 当前共享调度器里面没有醒着的任务
todo!()
},
// 没有任务了,退出
TaskResult::Finished => break
}
}

View File

@ -10,7 +10,6 @@ use core::fmt;
use core::sync::atomic::{AtomicUsize, Ordering};
/// 任务的信息
// TODO: 只是内核任务,用户任务由用户自己定义表现方式
// 如果要运行用户的进程,首先切换到用户的地址空间,其中包含一个初始化好的栈和剩余空间,然后在里面增加用户的任务
pub struct KernelTask {
/// 任务的编号
@ -69,20 +68,6 @@ impl KernelTask {
}
}
impl PartialEq for KernelTask {
fn eq(&self, other: &KernelTask) -> bool {
self.id == other.id
}
}
impl Eq for KernelTask {}
impl core::hash::Hash for KernelTask {
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
self.id.hash(state);
}
}
impl fmt::Debug for KernelTask {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let inner = self.inner.lock();

View File

@ -1,6 +1,6 @@
use spin::{Mutex, MutexGuard};
/// 关闭中断的互斥锁
/// 这个锁目前用不上,但先留着
#[derive(Default)]
pub struct Lock<T>(pub(self) Mutex<T>);

View File

@ -33,7 +33,7 @@ use alloc::sync::Arc;
use core::future::Future;
use core::ptr::NonNull;
// 创建一个新的内核任务,打包它的环境
/// 创建一个新的内核任务,打包它的环境
pub fn new_kernel(
future: impl Future<Output = ()> + 'static + Send + Sync,
process: Arc<Process>,

View File

@ -58,10 +58,7 @@ impl Process {
};
Some(process)
}
// /// 得到进程编号
// pub fn process_id(&self) -> ProcessId {
// self.id
// }
/// 得到进程*所在*的地址空间编号。进程不*对应*地址空间编号
pub fn address_space_id(&self) -> AddressSpaceId {
self.inner.lock().memory_set.address_space_id

View File

@ -1,6 +1,5 @@
use riscv::register::{stvec, sstatus::{self, SPP, Sstatus}, sepc, scause::{self, Trap, Exception}, stval};
use core::fmt;
use crate::{hart::KernelHartInfo, println};
use crate::syscall::{SyscallResult, syscall as do_syscall};
use super::timer;

View File

@ -1,7 +1,5 @@
use riscv::register::scause::{self, Trap, Interrupt};
use riscv::register::{sepc, stval};
use crate::memory::{self, PAGE_SIZE};
use crate::memory;
use crate::trap;
use crate::task;