uCore-Tutorial-Guide-2023S/source/chapter8/5exercise.rst

184 lines
8.3 KiB
ReStructuredText
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

chapter8 练习
=======================================
- 本节难度:助教自评为工作量最高一次,请尽早开始
本章任务
-----------------------------------------------------
- 本次任务对应 lab5也是本学期最后一次实验祝你好运。
- 老规矩,先 `make test BASE=1` 看下啥情况。
- 理解框架的多线程机制,了解几种锁的运行原理。在此基础上,实现本章编程作业死锁检测。
- 如果时间有限,多线程机制的一些细节大可跳过,但至少应知道多线程基本原理和本章在任务调度粒度上的调整
- 与实验息息相关的是互斥锁(mutex)与信号量(semaphore),条件变量(condvar)供阅读
- 框架包含 ``LAB5`` 字样的注释中给出了一个供参考的实现位置和顺序,你可以按顺序完成(下面的标号与注释中的一种):
- 1: 定义并初始化部分 PCB 的部分变量,包括控制死锁检测启动与死锁检测算法用到的变量,
你可以先定义一部分,后面发现有需要时再做添加;
- 2: 完成系统调用 ``sys_enable_deadlock_detect``,只需要修改变量,不必考虑是否正确实现了死锁。
完成这一步后你可以顺利跑完 ``ch8_sem2_deadlock``,这个测例开启了死锁检测但并没有死锁;
- 3: 尝试写一个函数实现下面提到的死锁检测算法,注释中给了供参考的函数签名。
这是一个和OS独立的函数你可以自行设计数据单独运行它以测试
- 4-1: 维护 mutex 相关的死锁检测变量,并调用死锁检测算法,完成后你可以顺利跑完测例 ``ch8_mut1_deadlock``
- 4-2: 维护 semaphore 相关的死锁检测变量,并调用死锁检测算法,完成后你可以顺利跑完测例 ``ch8_sem1_deadlock``
- 最终,完成实验报告并 push 你的 ch8 分支到远程仓库。push 代码后会自动执行 CI代码给分以 CI 给分为准。
编程作业
--------------------------------------
.. warning::
本次实验框架变动较大,且改动较为复杂,为降低同学们的工作量,本次实验不要求合并之前的实验内容,
可以直接 checkout 到助教的 ch8 框架开始实验,最终只需通过 ch8 系列的测例和前面章节的基础测例即可。
.. note::
本次实验实现死锁检测算法本身只需要40行左右代码但加上系统调用实现、变量声明与初始化、
以及在锁的创建、锁、释放时维护死锁检测 Available、Allocation、Request 数组,
总代码量预计在100行左右。助教的参考实现约为90行。
死锁检测
+++++++++++++++++++++++++++++++
目前的 mutex 和 semaphore 相关的系统调用不会分析资源的依赖情况,用户程序可能出现死锁。
我们希望在系统中加入死锁检测机制,当发现可能发生死锁时拒绝对应的资源获取请求。
一种检测死锁的算法如下:
定义如下三个数据结构:
- 可利用资源向量 Available :含有 m 个元素的一维数组,每个元素代表可利用的某一类资源的数目,
其初值是该类资源的全部可用数目,其值随该类资源的分配和回收而动态地改变。
Available[j] = k表示第 j 类资源的可用数量为 k。
- 分配矩阵 Allocationn * m 矩阵,表示每类资源已分配给每个线程的资源数。
Allocation[i,j] = g则表示线程 i 当前己分得第 j 类资源的数量为 g。
- 需求矩阵 Requestn * m 的矩阵,表示每个线程还需要的各类资源数量。
Request[i,j] = d则表示线程 i 还需要第 j 类资源的数量为 d 。
算法运行过程如下:
1. 设置两个向量: 工作向量 Work表示操作系统可提供给线程继续运行所需的各类资源数目它含有
m 个元素。初始时Work = Available ;结束向量 Finish表示系统是否有足够的资源分配给线程
使之运行完成。初始时 Finish[0~n-1] = false表示所有线程都没结束当有足够资源分配给线程时
设置 Finish[i] = true。
2. 从线程集合中找到一个能满足下述条件的线程 i
.. code-block::
:linenos:
Finish[i] == false;
Request[i,0~n-1] ≤ Work[0~n-1];
若找到,执行步骤 3否则执行步骤 4。
3. 当线程 i 获得资源后,可顺利执行,直至完成,并释放出分配给它的资源,故应执行:
.. code-block::
:linenos:
Work[0~n-1] = Work[0~n-1] + Allocation[i, 0~n-1];
Finish[i] = true;
跳转回步骤2
4. 如果 Finish[0~n-1] 都为 true则表示系统处于安全状态否则表示系统处于不安全状态即出现死锁。
出于兼容性和灵活性考虑,我们允许进程按需开启或关闭死锁检测功能。为此我们将实现一个新的系统调用:
``sys_enable_deadlock_detect``
**enable_deadlock_detect**
- syscall ID: 469
- 功能:为当前进程启用或禁用死锁检测功能。
- 接口: ``int enable_deadlock_detect(int is_enable)``
- 参数:
- is_enable: 为 1 表示启用死锁检测, 0 表示禁用死锁检测。
- 说明:
- 开启死锁检测功能后, ``mutex_lock````semaphore_down`` 如果检测到死锁,
应拒绝相应操作并返回 -0xDEAD (十六进制值)。
- 简便起见可对 mutex 和 semaphore 分别进行检测,无需考虑二者 (以及 ``waittid`` 等)
混合使用导致的死锁。
- 返回值:如果出现了错误则返回 -1否则返回 0。
- 可能的错误
- 参数不合法
- 死锁检测开启失败
..实验结果
..+++++++++++++++++++++++++++++++++++++++++
..本实验采用了github classroom的自动评分功能完成实验提交git push后会触发自动测试实验测试结果可以在在线统计<https://ucore-rv-64.github.io/classroom-grading/>中查看。
实验要求
+++++++++++++++++++++++++++++++++++++++++
- 完成分支: ch8。
- 实验目录要求不变。
- 通过所有测例。
问答作业
--------------------------------------------
1. 在我们的多线程实现中,当主线程 (即 0 号线程) 退出时,视为整个进程退出,
此时需要结束该进程管理的所有线程并回收其资源。
- 需要回收的资源有哪些?
- 其他线程的 ``struct thread`` 可能在哪些位置被引用,分别是否需要回收,为什么?
2. 对比以下两种 ``mutex_unlock`` 中阻塞锁的实现,二者有什么区别?这些区别可能会导致什么问题?
(假设无论哪种实现,对应的 ``mutex_lock`` 均正确处理了 ``m->locked``
.. code-block:: C
:linenos:
void mutex_unlock_v1(struct mutex *m)
{
if (m->blocking) {
m->locked = 0;
struct thread *t = id_to_task(pop_queue(&m->wait_queue));
if (t != NULL) {
t->state = RUNNABLE;
add_task(t);
}
} else ...
}
void mutex_unlock_v2(struct mutex *m)
{
if (m->blocking) {
struct thread *t = id_to_task(pop_queue(&m->wait_queue));
if (t == NULL) {
m->locked = 0;
} else {
t->state = RUNNABLE;
add_task(t);
}
} else ...
}
报告要求
-------------------------------
注意目录要求,报告命名 ``lab5.md````lab5.pdf``,位于 reports 目录下。 后续实验同理。
- 简单总结你实现的功能200字以内不要贴代码及你完成本次实验所用的时间。
- 完成问答题。
- 加入 :doc:`/honorcode` 的内容。否则你的提交将视作无效本次实验的成绩将按“0”分计。
- 推荐markdown文档格式。
- (optional) 你对本次实验设计及难度/工作量的看法,以及有哪些需要改进的地方,欢迎畅所欲言。
选作题目
--------------------------------------------------------
选做题目列表
- 基于多核的OS内核线程支持内核支持抢占支持多核方式下的同步互斥
- 提升多核的OS内核性能实现内核中的并行性能优化fs中的缓冲区管理并行化, 物理内存分配的并行化)
- 更通用的内核+应用的死锁检查参考Linux
提交要求
- 实现代码(包括基本的注释)
- 设计与功能/性能测试分析文档,测试用例。
- 鼓励形成可脱离OS独立存在的库可以裸机测试或在用户态测试比如easyfs那样