2024-05-27
最后编辑于:2024-09-15
Fusion使用无栈协程来进行任务管理和调度。利用Rust语言的异步机制,可以改进操作系统内核的模块结构,优化操作系统内核的并发性能。
任务/协程: 是Fusion中最基本的调度单位。根据任务切换的时机可以分为:
无栈体现在,协程的局部变量不保存在栈上,切换时只会切换状态机指向和部分寄存器
协程在执行时进行状态机转移。每个线程内可以有多个协程。编译器会将async标记的代码块转化为一个状态机,而状态机的大小在编译器即可以确定。
await
处切换,硬刺只需保存和恢复少量的状态信息,相比于传统的线程上下文切换,任务切换开销更低。
当async
函数嵌套使用时,调用者的状态机会包含对被调用者的状态机的引用,并在适当的时候await
这个状态机。每个状态机只负责自身的状态,不需要嵌套在其他状态机中,从而避免了深层次嵌套带来的内存开销。在进行任务切换时,执行器只需改变对应状态机的指针。
Fusion将任务分为两块,信息部分和状态部分。 任务部分对外共享,可以被其他任务访问。状态部分对任务私有,只能由该任务内部访问
为了让任务支持异步执行,定义了TaskFut
并实现了Future trait
#[pin_project]
pub struct TaskFut<F> {
virt: Pin<Arsc<Virt>>,
#[pin]
fut: F,
}
任务在创建分配资源之后,传递给执行器进行调度
let fut = TaskFut::new(ts.virt.clone(), user_loop(ts, self.tf));
executor().spawn(fut).detach();
其中任务运行在user_loop
中。在此循环中,任务按照以下流程执行
scause
(中断、异常、系统调用)在内核启动时,完成硬件初始化后便会启动run_art
异步运行时
Fusion的任务调度基于async-task的调用实现,支持多核心、软抢占和任务窃取。 调度器为每一个调度核心维护一个FIFO任务队列一个抢占槽。每个调度核心的任务获取按照以下优先级顺序