schedule浪子何时回头?

来源:互联网 发布:蚁群算法优化SVM 编辑:程序博客网 时间:2024/04/26 04:43

schedule浪子何时回头?

刺猬@http://blog.csdn.net/littlehedgehog

 




schedule.c 给人最大的疑惑就是一旦把进程调度完成后切换到其他进程时,什么时候再返回执行呢?

 

void schedule (void)
{
    
int
 i, next, c;
    
struct task_struct **
p;    
    
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;
        }


  
/* 这里是调度程序的主要部分 */

    
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);        //
 切换到任务号为next 的任务,并运行之。
}

schedule函数主要是:

1、处理信号

2、寻找合适调度程序

3、切换

我们主要关注在切换这块。看最后一句,调用switch_to函数,这个函数在shed.h中的171行:

 

#define switch_to(n) {
struct {long a,b;} __tmp; 
__asm__( 
"cmpl %%ecx,_current "
     
  
"je 1f "
             
  
"movw %%dx,%1 "
         
  
"xchgl %%ecx,_current "
     
  
"ljmp %0 "
         
// 在任务切换回来后才会继续执行下面的语句。

  "cmpl %%ecx,_last_task_used_math "     
  
"jne 1f "
         
  
"clts "
             
  
"1:"::"m" (*&__tmp.a), "m" (*&
__tmp.b),
  
"d" (_TSS (n)), "c" ((long
) task[n]));
}

程序运行到 ljmp %0 ,这里就是ljmp tss ,进行了任务切换,有人也问过为什么jmp tss 就能进行任务切换呢?

这个是cpu的设计问题了,那要去问intel公司为什么要这样设计。不过我们可以设想一下,在tss中所有进程需要的所有内容都有了,包括寄存器、页目录表、ldt的选择符,那么为什么不能设计成jmp tss 就可以切换任务呢?如果我是设计人员,我也会这样设计,方便系统编程人员啊。

jmp tss 后就完成了任务切换。当前任务暂停执行,一直到schedule又重新调度该任务。不过还要补充说明的是: 当前任务进入调度程序时,此时已经是内核态了。等我们再回来执行时,同样是接着在内核态执行。这里是接着执行 cmpl %%ecx,_last_task_used_math 这条语句,如上面所注释的一样。

原创粉丝点击