《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. 默认操作。
关键是信号如何得到处理的:
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指向处理信号的函数。


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值