已提供信号部分的用户库接口及测例,但内核没有相关实现
目前 /ch7 模块复制自 /ch6,已经有了基本的信号实现。
在 /xtask/src/user.rs 和 /user/cases.toml 中加入了第七章相关信息。
目前新增加了四个模块:
-
signal-defs模块。包含每个信号标号的具体含义enum SignalNo和信号处理函数的定义struct SignalAction。syscall模块需要它们,而信号的接口模块signal也需要它们。考虑到syscall和signal谁依赖谁都不太合适,所以单独拆了一个非常简单的signal-defs出来,专门存放用户程序和内核都需要使用的信号定义 -
signal模块。信号模块的定义,主要提供pub trait Signal -
signal-impl模块。一个信号模块的参考实现。 -
ch7模块。第七章的主线代码。
它们(和部分已有模块)的依赖关系如下:
graph TD;
ch7-->signal-impl
ch7-->signal
ch7-->syscall
user-->syscall
signal-impl-->signal
signal-->signal-defs
syscall-->signal-defs
signal-defs-->numeric-enum-macro
其中 numeric-enum-macro 是一个外部库,提供了 enum 和整数类型之间的表达和转换关系。
添加测例:sig_ctrlc sig_simple sig_simple2 sig_tests,其中 sig_ctrlc sig_simple sig_simple2 可通过。
目前仅添加了信号相关的测例,后续还会加入其他测例。
(本项目与原 rCore-Tutorial-v3对用户程序的部分接口有所不同,因此引入时会修改部分代码)
目前已在 /syscall/src/user.rs 添加用户库对应需要的 syscall:
kill发送信号sigaction设置信号处理函数sigprocmask修改信号掩码sigreturn从信号处理函数中返回
并添加 /signal-defs,包含一些用户程序和内核通用的信号标号和处理函数定义。
这里
SignalAction::mask使用usize而非i32,是为了兼容将来可能会有的标号在[32,64)之间的实时信号。这里信号标号使用
SignalNo,是为了与上面的mask区分,提示用户程序在kill()和sigaction()中应使用信号的标号,而在sigprocmask中应使用信号的掩码
由于信号模块依赖一些前面章节的 syscall,但它们还没有实现,所以这里也添加和修改了一些信号之外的 syscall 和代码:
-
添加
syscall: getpid,应属于第五章。 -
添加
/user/src/lib.rs: sleep(period_ms: usize),应属于第三章。这里为了适应用户程序,还在/syscall/lib/time.rs中添加了从毫秒数(usize)转换为TimeSpec的方法 -
添加
/ch7/src/exit_process.rs这个方法实际上是原来的sys_exit。因为“进程退出”这一事件除了由sys_exit触发,也可能由信号触发,因此现在把这个过程抽离出来,其他事情发生时也会
前面章节还有一些工作没有完成,而第七章的部分内容恰好对这些没完成的部分有依赖,因此目前功能还不够全面:
-
缺少时钟中断,所以还不支持暂停应用的信号
-
缺少 trait File,目前所有文件都来自fs,而stdin/stdout 是靠特判实现的,所以pipe还需要等一会
-
第五章实现中,进程状态简化了,现在没法保存和获取进程退出时的 exit_code,wait 的非负数返回值只能使 333。但是信号相关的部分测例
sig_tests是需要检测退出时的返回值的。 -
之前的rCore-Tutorial是有“用户程序阻塞在内核态”的机制的,比如说暂停的信号和pipe,即可能出现
loop {
if ......
suspend_current_and_run_next();
}的情况,但是现在的 kernel-context 似乎不支持这个机制了。这样上述的功能都需要重新考虑如何实现
(顺便一提,本来 stdin 的串口输入也是需要这个机制的,但现在似乎整个内核会阻塞在sbi_rt::legacy::console_getchar() 上,把问题绕过去了)