《Linux0.11内核完全注释》读后小结 --- 进程调度与信号

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

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

/* check alarm, wake up any interruptible tasks that have got a signal */ for(p = &LAST_TASK ; p > &FIRST_TASK ; --p) if (*p) { if ((*p)->alarm && (*p)->alarm < jiffies) { (*p)->signal |= (1<<(SIGALRM-1)); (*p)->alarm = 0; } if (((*p)->signal & ~(_BLOCKABLE & (*p)->blocked)) && (*p)->state==TASK_INTERRUPTIBLE) (*p)->state=TASK_RUNNING; }
遍历整个任务列表,找出counter最大的任务。然后switch_to

/* this is the scheduler proper: */ while (1) { c = -1; next = 0; i = NR_TASKS; p = &task[NR_TASKS]; while (--i) { if (!*--p) continue; if ((*p)->state == TASK_RUNNING && (*p)->counter > c) c = (*p)->counter, next = i; } if (c) break; for(p = &LAST_TASK ; p > &FIRST_TASK ; --p) if (*p) (*p)->counter = ((*p)->counter >> 1) + (*p)->priority; } switch_to(next);


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. 默认操作。
《Linux0.11内核完全注释》读后小结 --- 进程调度与信号_第1张图片
关键是信号如何得到处理的:
do_signal()函数是内核系统调用(0x80)中断处理程序中对信号的预处理程序。在进程每次调用系统调用或者发生时钟等中断时,若进程已收到信号,则该函数就会把信号的处理句柄(即对应的信号处理函数)插入到用户程序堆栈中。这样,在当前系统调用结束返回后就会立即执行信号句柄程序,然后再继续执行用户的程序。
这样,一个信号出现两次,只会响应一次。
在system_call.s 中
ret_from_sys_call: movl current,%eax# task[0] cannot have signals cmpl task,%eax je 3f cmpw $0x0f,CS(%esp)# was old code segment supervisor ? jne 3f cmpw $0x17,OLDSS(%esp)# was stack segment = 0x17 ? jne 3f movl signal(%eax),%ebx movl blocked(%eax),%ecx notl %ecx andl %ebx,%ecx bsfl %ecx,%ecx je 3f btrl %ecx,%ebx movl %ebx,signal(%eax) incl %ecx pushl %ecx //------------------------------------- call do_signal //------------------------------------- popl %eax 3: popl %eax popl %ebx popl %ecx popl %edx pop %fs pop %es pop %ds iret


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

《Linux0.11内核完全注释》读后小结 --- 进程调度与信号_第2张图片


你可能感兴趣的:(《Linux0.11内核完全注释》读后小结 --- 进程调度与信号)