Skip to content

Commit d80fadf

Browse files
committed
docs: 更新重构设计
Signed-off-by: YdrMaster <ydrml@hotmail.com>
1 parent 276efef commit d80fadf

File tree

1 file changed

+42
-0
lines changed

1 file changed

+42
-0
lines changed

README.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88

99
> **感谢:2022 系统能力赛,哈工大(深圳),[FTL-OS](https://gitlab.eduxiji.net/DarkAngelEX/oskernel2022-ftlos) 提供灵感**
1010
11+
| 注意 | 这个项目有重大 bug,设计上也需要调整,正在重构中,参见[重构设计](#重构设计)
12+
|-|-
13+
1114
## 目录
1215

1316
- [概念](#概念)
@@ -22,6 +25,7 @@
2225
- [使用说明](#使用说明)
2326
- [功能测试](#功能测试)
2427
- [性能测试](#性能测试)
28+
- [重构设计](#重构设计)
2529

2630
## 概念
2731

@@ -446,3 +450,41 @@ cargo qemu --kernel bench --smp 1
446450
| main | 107700360 | 107756601 | 123088023 | 48.5%
447451
| vectored | 212014619 | 212212320 | 273411079 | 100.0%
448452
| slow | 210191584 | 210286668 | 456087262 | 125.6%
453+
454+
## 重构设计
455+
456+
将陷入分为 2 类:
457+
458+
- 陷入到新栈:陷入之后将栈指针指向一个新的栈,意味着启动了新的线程;
459+
- 陷入到当前栈:发生陷入时栈指针不动,直接继续使用,因此陷入时栈指针必须有效;
460+
461+
必须将陷入处理和“线程”的概念耦合。在这个库的框架下,产生新线程的唯一方式就是陷入到新栈。
462+
463+
陷入到新栈时一定会创建一个新线程,但是这个线程的生命周期可能很短。任务的切换只能发生在陷入线程的末尾,这类似于 CORTEX 架构的 PendSV 可挂起中断的设计。
464+
465+
一般来说,跨权限等级的陷入必须陷入到新栈,因为低权限代码可能没有正确使用栈指针,甚至就是因为栈溢出才发生陷入。但同权限的陷入,尤其是在同一个软件内部发生的陷入(比如内核开中断),通常来说栈指针是保证有效的,此时就可以使用同栈陷入的方式。
466+
467+
陷入之后,上下文可以直接压在栈上。下表显示了一个典型的线程栈结构:
468+
469+
| 栈底(高地址)
470+
| -
471+
| 低权限上下文
472+
| 0 级陷入栈
473+
| 1 级嵌套上下文
474+
| 1 级陷入栈
475+
| ……
476+
| n 级嵌套上下文
477+
478+
这个线程栈由一次低优先级发生的陷入创建,在栈上压入控制流上下文后开始处理,此时使用的栈空间称为 0 级陷入栈。若处理过程中再次发生陷入,栈指针不动,当前上下文直接压到栈上后开始处理,此时使用的栈空间称为 1 级陷入栈。以此类推,若发生 n 次嵌套陷入后,无法处理,需要挂起等待,则 n 级嵌套处理必须退出,栈顶存放用于恢复 n-1 级陷入处理的 n 级上下文,然后一步恢复另一个线程的最后一个上下文。此时,刚刚创建的那个线程上,共有 n 个内核陷入和一个低权限陷入不能处理,处于挂起状态。只有原来的 n 级陷入处理完成才能依次恢复。
479+
480+
这种逐级压到同一个栈的方式可以节省栈空间的开销,也会减少同权限陷入不得不换栈导致的缓存失效问题。但也会压住之前到来的陷入无法处理,必须跟着挂起。尤其是新到来的同权限陷入通常和被压住的陷入没什么关系,很可能带来死锁。所以,如果第 n 级上下文无法立即处理,可以选择创建一个挂起状态的新线程,然后恢复处理 n-1 级陷入。只需分配一个新的栈空间,拷贝 n 级陷入栈的数据到新栈上,然后构造一个可恢复这个陷入栈的上下文即可。
481+
482+
这种从挂起创建的线程栈具有这样的结构:
483+
484+
| 栈底(高地址)
485+
| -
486+
| 无效上下文
487+
| n 级陷入栈
488+
| n+1 级嵌套上下文
489+
490+
从这个线程恢复时,恢复 n+1 级嵌套上下文将继续执行 n 级陷入栈的处理流程,完成后识别到下一个要恢复的是一个无效的上下文,可以执行一个调度流程,这个栈空间则可回收。

0 commit comments

Comments
 (0)