rCore-Tutorial-Book-v3
rCore-Tutorial-Book-v3 copied to clipboard
rcore-tutorial-book-v3/chapter5/2core-data-structures
进程机制核心数据结构 — rCore-Tutorial-Book-v3 0.1 文档
http://wyfcyx.gitee.io/rcore-tutorial-book-v3/chapter5/2core-data-structures.html
为什么需要额外的一个idle_task_cx,不能够直接使用之前task_cx吗,为何在前一个task和后一个task之间还要夹一个idle_task_cx
@SocialistDalao 这样做的主要目的是使得换入/换出进程和调度执行流在内核层各自执行在不同的内核栈上,分别是进程自身的内核栈和内核初始化时使用的启动栈。这样的话,调度相关的数据不会出现在进程内核栈上,也使得调度机制对于换出进程的Trap执行流是不可见的,它在决定换出的时候只需调用schedule而无需操心调度的事情。从而各执行流的分工更加明确了,虽然带来了更大的开销。
实际上当然可以在Trap处理中直接进行调度找到切换到哪个进程并切换过去。有兴趣的话可以试试。
请问idle_task_cx_ptr为什么初始化成0
@yongchicy 初始化为多少其实都没关系,每个核在内核初始化完毕后都会调用Processor::run,在第一次被调度器分配到一个任务执行的时候,就会通过__switch真正初始化它的值指向一个合法的任务上下文。
Processor::run 应该改为 Processor::run_tasks。 我看最新的 3 个分支 ch5, ch5-lab, ch5-dev 都是 run_tasks。
@lindyang Fixed.另外,这个issue开头的文档链接是有问题的,它指向一个长时间没有同步的旧仓库。
idle控制流是不是可以替换成一个idle任务
Weak 在语义上本来就是可空的,用 ::new()/::default() 可以构造,不用再包一个 Option 了。
idle控制流是不是可以替换成一个idle任务
@wei-huan 不行吧,idle 找下一个就绪的任务需要留在内核空间
base_size 不理解。应用数据仅有可能出现在应用地址空间低于 base_size 字节的区域中。
意思是限制应用虚拟空间的总大小吗?
idle 控制流我个人的理解:
idle_task_cx_ptr 实际上只是一个占位符。它存在的意义就是作为 __switch 的第一个参数。
run_tasks 是在 os 的入口函数中调用的,也即运行在内核系统栈。这个函数是系统的自带调度流,而非被进程所推动的调度流。
而调度操作,我们可以举例追溯 sys_yield 的实现,发现它调用 suspend_current_and_run_next,后者调用 schedule。即:进程的内核栈主动请求了将自己换出,换成新的进程。
因此,使用一个空上下文作为占位,内核的自己的调度流就不需要关心现在是谁在运行,只要换成下一个就绪任务就行,完成了解耦。
@YdrMaster Weak<T>的可空语义好像和这里无关吧
内核将跳转到 Processor::run 中 __switch 返回之后的位置,也即开启了下一轮的调度循环。
Processor::run 现已为 Processor::run_tasks
idle 控制流的设计和 xv6 的很像,rCore 让 run_tasks 始终保持运行, 可以把这个函数想象成一个游戏机,它的作用就是不断挑选可运行的游戏卡(进程),然后放到 CPU 这个卡槽中。一定时间后这个 CPU 卡槽要给别的游戏卡(进程)用了就把这个当前的卡弹出来(这里就用了 schedule 函数弹出),然后游戏机又开始选下一张能用的游戏卡(进程)了。
游戏卡(进程)只知道自己被插上要运行,以及到某个点自己要弹出来,它不知道游戏机的存在,这样就做到了任务调度的透明。
希望没理解错 :sob:
@HangX-Ma 这个比喻挺有意思:)
处理器管理结构 Processor 负责从任务管理器 TaskManager 中分出去的维护 CPU 状态的职责:
这句话好像不太通畅。