(莱昂氏unix源代码分析导读-21)时钟中断处理

时钟中断是系统中最重要的中断,每个时钟滴答都会产生时钟中断,它的中断矢量为(0100)(0103)

 

0533: . = 100^.

0534:       kwlp; br6

0535:       kwlp; br6

 

0569: .globl  _clock

0570: kwlp:  jsr r0,call; _clock

 

显然,时钟中断会通过call例程调用_clock函数,对clock函数,11.1小节有详细的介绍。

 

我在这里只谈几个问题:

1.参数

clock(dev, sp, r1, nps, r0, pc, ps)7个参数,想要逐一了解他们,请回头看看上面的栈图;

 

2.时钟中断是典型的“多用途”中断,它需要进行多个层次的处理。实际上,clock函数对时间进行

    3个维度的处理:

  1)时钟滴答

       修改p_cpu值,对于大多数进程来说,p_cpu就是占用的cpu滴答数,但如果进程执行时间较长的话,

      p_cpu的值会有一个回归——其作用是防止进程的优先级变的太低而导致饿死。

       检查定时器,看是否需要执行操作。

 

  2)秒

       修改u.stimeu.utimetime[ ]等以秒为单位的计时器。

       甚至还有以4s为单位的系统进程唤醒。

 

3)时间片

       此版本的unix正好使用1秒作为一个时间片,故与秒的处理发生了重叠。

 

3Clock函数的各项工作的“Priority

   显然,在clock函数的多项工作中,优先级是不同的,而且各项工作对于时延的容忍程度是不同的。

   对秒级、时间片级的工作——即使是推迟几个时钟滴答再处理对整体的影响也不大。

 

于是,clock函数内对低优先级、高耗时的工作进行了控制——会进行这样的检查:

if((ps&0340) != 0) return;  /by pass following codes

 

即只有在“前ps”的cpu优先级为0时,才会从事下面那些工作。而一般情况下,

(1)         usercpu优先级为0

(2)         kernel态时,程序调用spl0将自己设置为优先级0

 

受到控制的工作有:

(1)         时间片——重设进程优先级的工作;

(2)         计时器处理

(3)         Etc

 

4.时间片处理

按我所学习的操作系统理论,时间片应该是很重要的进程切换的时机。但很遗憾,clock()函数中仅仅调用setpri()

重新设置了进程的priority,并没有直接调用swtch()切换进程。

 

但是,且慢……

(1)         clock()函数返回到call例程后,会有机会切换进程的,关键在runrun是否设置;

(2)         setpri()函数是可以增加runrun计数的——还记得吗,那个诡异的判断?

2165:    if(p > curpri)

2166:       runrun++;

 

让我们仔细考察一下clock()setpri()

对大多数的进程,clock()会以更高的p_cpu调用setpri()函数,这样会降低进程的优先级,显然,对active

进程也是如此。而这正好会使2165那个判断成真——即增加runrun计数,也就引起了后面的进程切换。

 

【注】:对于2165谜题,希望读者能给出更好的答案。

 

5time数组

      time[0]time[1]组成,记录自1970年以来所经过的秒数。它使用216bit整数模拟132位整数,

     time[0]为高16bittime[1]为低16bit。因此才有以下的算法:

3801: if(++time[1] == 0)

3802: ++time[0];

 

6.定时器

   callout数组记录了要执行的定时任务。

   任务按照执行先后顺序排列,其c_time意义如下:

(1)         callout[0].c_time ——“绝对时钟滴答数”,再过这么多滴答,即执行函数;

(2)         callout[n] .c_time (n>0)——相对于callout[n-1]的相对时钟滴答数

 

7tout的叫醒服务

   显然,tout[ ]内记录的是下一个要被wakeup的时间,当与当前时间(time[])相同时,

  会调用wakeup(tout)唤醒进程——显然,睡眠的进程使用tout[ ]数组首地址作为睡眠id

莱昂针对tout的实现提出了自己的看法,但这部分涉及到system call,我们会在下面的章节进行讨论。

 

注意,我们将swap的部分留在后面讨论。

 

博客地址:http://blog.csdn.net/cszhao1980

博客专栏地址:http://blog.csdn.net/column/details/lions-unix.html

你可能感兴趣的:((莱昂氏unix源代码分析导读-21)时钟中断处理)