diff --git a/docs/FinalReport.md b/docs/FinalReport.md index 40e45ed..75b0fc1 100644 --- a/docs/FinalReport.md +++ b/docs/FinalReport.md @@ -4,7 +4,7 @@ 计53 王润基 2015011279 -2018.05.25 +2018.05.25 + 06.15 ## 摘要 @@ -49,6 +49,8 @@ * 同步互斥:没写 * 文件系统:SFS和VFS作为单独模块实现完毕,还没对接到进程中 +到第16周,完成了同步互斥部分,并对内存管理进行了整合优化。 + 具体完成过程和内容参见下文,各部分完成情况清单参见[status.md](../status.md)。 ### 前期调研情况 @@ -228,6 +230,37 @@ CLion配合gdb调试的方法:详见日志2018.05.18的记录 Log模块是软件开发中一种常用的库,它可以支持在程序各处记录不同等级的日志,汇总到一起统一输出。我在RustOS中引入了这个库,并实现了根据不同日志等级以不同的颜色进行输出,还支持在运行前对指定等级的日志进行过滤,方便debug。 +### 6. 同步互斥 + +在内核线程调度的基础上,实现了用于内核态的同步互斥工具。这部分参考了spin模块和Rust标准库中的sync模块,并提供和std::sync完全相同的接口。作为测试,仿照uCore,用这些工具在OS内实现了哲学家就餐问题。 + +各模块依赖关系如下: + +```mermaid +graph TB + subgraph dependence + interrupt + thread + end + subgraph sync + SpinLock --> interrupt + Condvar --> SpinLock + Condvar --> thread + Mutex --> Condvar + Monitor --> Condvar + Semaphore --> Condvar + Semaphore --> SpinLock + mpsc --> SpinLock + mpsc --> Condvar + end +subgraph test + Dining_Philosophers --> Mutex + Dining_Philosophers --> Monitor + end +``` + +Rust中提供同步互斥的最底层支撑是核心库中的原子变量`AtomicBool`,用它即可实现最简单的自旋锁`spin::Mutex`。自旋锁已经可以满足OS内核中的大部分需求,但如果在中断和非中断态都访问同一个锁,就可能造成死锁问题,这就需要在上锁期间关闭中断。此外,还要实现支持线程调度的锁,在无法获得锁时,将当前线程加入等待队列并放弃CPU,在用锁完毕时唤醒一个等待的线程。我通过将`spin::Mutex`修改为一个可替换底层支持的锁框架,实现了上述两个需求。在此基础上,又实现了信号量、条件变量、信息传递通道,形成了比较完善的同步互斥工具组。这部分共计约400行代码。 + ## 实验总结 在整个移植过程中,我并不会直接照搬C语言的实现,而是去参考其他RustOS的设计,尽量使用Rust的风格和视角去重新审视OS。 diff --git a/docs/Log.md b/docs/Log.md index 8a1ebe5..3cfb8af 100644 --- a/docs/Log.md +++ b/docs/Log.md @@ -2,6 +2,41 @@ 这里以天为单位,以周为周期,按时间倒序维护了开发日志。 +### 第15周 + +#### 2018.06.06:FS-Process + +- 学习xv6/uCore中文件系统上层接口 +- 尝试在Rust中实现RootFS和FileManager + +#### 2018.06.04:完成同步互斥 + +- 完成了信号量、条件变量,哲学家就餐问题 +- 简易实现了std::sync::mpsc中的FIFO消息传递通道 + +#### 2018.06.03:新的物理帧分配器 + +- 实现了新的物理帧分配器,支持回收。其本质是一个0-2^k的整数分配器,内部用bitset维护,并形成树状级联结构,每16bit对应上层1bit,用x86专有指令bsr(相当于整数log2)实现快速分配。目前使用容量为64Kb的分配器,可维护256MB内存空间,实际占用内存9KB以内。 +- 由于Rust语言的限制,该类无法实现const fn构造函数,只能使用lazy_static等tradeoff进行运行时初始化。这时必须开启至少O1优化(使用RVO返回值优化,防止在栈上构造再复制到全局变量),否则会栈溢出。 + +#### 2018.06.02:重构内存管理模块 + +- 大幅调整了内存管理模块,对外统一使用MemorySet管理一个线程的内存,简化了使用方式。 + +#### 2018.06.01:同步互斥进阶 + +- 完成了OS内用锁实现的哲学家就餐问题,和OS外用条件变量的实现。 +- 关于Rust并发模型:Rust的所有权机制使得它可以轻松支持【锁数据】而不是【锁代码】。这使得在实现上述哲学家就餐问题时,用锁非常自然,而用条件变量(管程)则不太直观。 + +### 第14周 + +#### 2018.05.31:同步互斥初步 + +* 将spin::Mutex代码fork了一份到内核中,在其中实现了一个接口框架,可以自由替换底层支持。在此框架下,已经实现了自旋锁(spin_lock)、禁止中断的自旋锁(spin_lock_irqsave),接下来就可以实现自动调度的锁了。 +* 实现了禁止中断自旋锁后,即可打开syscall的中断了。 +* 为了方便内核态的线程操作,将原有的process模块又封装了一层thread接口,长得和标准库一模一样(std::thread)。这样具体的同步互斥问题(如哲学家就餐)可以先在外部环境中依赖std库实现并测试,然后方便地移植到OS环境中。 +* 在此过程中又学习了关于内核抢占、同步互斥锁等相关资料,感觉又是个大坑。并且发现我实现的RustOS一直是内核可抢占的,主要依赖时钟中断进行线程切换,不知要不要改掉。 + ### 第13周 本周完成的主要工作: diff --git a/status.md b/status.md index 4670f24..afa7d7f 100644 --- a/status.md +++ b/status.md @@ -42,10 +42,10 @@ #### lab7: Synchronization -- [x] Mutex:Rust core lib built-in -- [ ] Semaphore -- [ ] Monitor -- [ ] Dinning Philosophers Problem +- [x] Mutex +- [x] Semaphore +- [x] Monitor +- [x] Dinning Philosophers Problem #### lab8: File system