schedule.c 是关于进程调度的。

schedule 函数是核心,先检查task列表中,有没有收到信号的,有的话处理之。


遍历整个任务列表,找出counter最大的任务。然后switch_to


switch_to 汇编写的指令,切换到计算出的进程。最后一个汇编指令。CLTS - 清除CR0 中的任务切换标志

void sleep_on(struct task_struct **p)
void interruptible_sleep_on(struct task_struct **p)
void wake_up(struct task_struct **p)
这是理解进程调度的关键:
current指向了当前的取得CPU时间片的进程,进程一旦执行到schedule函数,进程的控制权(时间片)就交出了,重新进行调度。所以,当schedule 返回时,证明schedule又调度到了这个进程。这个进程又获取到了时间片。这个很有意思,不是普通的函数返回。而是,从一个进程切换回到了这个进程。
进程收到一个信号:
信号是一种软中断:0x80中断。
1. 忽略该信号
2. 捕获该信号
3. 默认操作。
关键是信号如何得到处理的:
do_signal()函数是内核系统调用(0x80)中断处理程序中对信号的预处理程序。在进程每次调用系统调用或者发生时钟等中断时,若进程已收到信号,则该函数就会把信号的处理句柄(即对应的信号处理函数)插入到用户程序堆栈中。这样,在当前系统调用结束返回后就会立即执行信号句柄程序,然后再继续执行用户的程序。
这样,一个信号出现两次,只会响应一次。
在system_call.s 中



会调用do_signal 函数,进行处理信号。处理信号,就是把eip指向处理信号的函数。


Copyright © 2024 Teddy Yan
Powered by .NET 8.0 on Kubernetes