code:clock - ikarishinjieva/unixV6-code-analyze-chs GitHub Wiki

Source

3708

3709 /*

3710  * clock is called straight from

3711  * the real time clock interrupt.

3712  *

3713  * Functions:

3714  * reprime clock

3715  * copy *switches to display

3716  * implement callouts

3717  * maintain user/system times

3718  * maintain date

3719  * profile

3720  * tout wakeup (sys sleep)

3721  * lightning bolt wakeup (every 4 sec)

3722  * alarm clock signals

3723  * jab the scheduler

3724  */

3725 clock(dev, sp, r1, nps, r0, pc, ps)

总体思想
  • 将 整体处理 划分为几部分,划分标准
    • 处理机优先级是否为0 (是否有更重要的任务需要完成)
    • 先前态是否为用户态 (核心态运行时,时钟中断尽可能不占用时间)
  • 时钟中断尽可能节省时间
将统计/计数的工作留给 不重要的时候 再做 而不是严格的按照时间来做
3726 {

3727     register struct callo *p1, *p2;

3728     register struct proc *pp;

3729

3730     /*

3731      * restart clock

3732      */

3733

3734     *lks = 0115;

3735

3736     /*

3737      * display register

3738      */

3739

3740     display();

3741

  • "显示"函数在pdp11/40中无实现
3742     /*

3743      * callouts

3744      * if done, just return

3745      * else update first non-zero time

3746      */

callout总体说明
  • callout 用于 按时序 调用指定函数
  • 数据结构 参看callout
  • clock中对于callout的操作总体如下
    • callout中第一个未到期的事件 的 剩余时间-1
    • 处理callout中所有到期事件,并从callout中移除到期事件
3747

3748     if(callout[0].c_func == 0)

3749          goto out;

  • 若callout为空,则跳过callout处理过程
3750     p2 = &callout[0];

3751     while(p2->c_time<=0 && p2->c_func!=0)

3752          p2++;

3753     p2->c_time--;

3754

  • callout中第一个未到期的事件 的 剩余时间-1
3755     /*

3756      * if ps is high, just return

3757      */

3758

3759     if((ps&0340) != 0)

3760          goto out;

  • 处理机优先级 不为 0,则跳过callout处理过程
  • 意图在于 : 处理机优先级 不为0时,则有更紧要的任务需要执行,不进行callout处理以节省时间
3761

3762     /*

3763      * callout

3764      */

3765

3766     spl5();

  • 处理机优先级 置 5
  • 避免插入不必要的中断,使得整个时钟处理时间延长
3767     if(callout[0].c_time <= 0) {

3768          p1 = &callout[0];

3769          while(p1->c_func != 0 && p1->c_time <= 0) {

3770           (*p1->c_func)(p1->c_arg);

3771           p1++;

3772          }

3773          p2 = &callout[0];

3774          while(p2->c_func = p1->c_func) {

3775           p2->c_time = p1->c_time;

3776           p2->c_arg = p1->c_arg;

3777           p1++;

3778           p2++;

3779          }

3780     }

  • 处理callout中所有到期事件,并从callout中移除到期事件
3781

3782     /*

3783      * lightning bolt time-out

3784      * and time of day

3785      */

3786

3787 out:

3788     if((ps&UMODE) == UMODE) {

3789          u.u_utime++;

3790          if(u.u_prof[3])

3791           incupc(ps, u.u_prof);

3792     } else

3793          u.u_stime++;

3794     pp = u.u_procp;

3795     if(++pp->p_cpu == 0)

3796          pp->p_cpu--;

  • 当前进程 CPU使用度+1
  • 若越界,则 不进行+1
3797     if(++lbolt >= HZ) {
  • 若 时钟滴答数 积攒到 整秒,进行整秒处理
3798          if((ps&0340) != 0)

3799           return;

  • 处理机优先级 不为0,则直接返回
  • 这样跳过整秒处理,为了节省执行时间
3800          lbolt =- HZ;

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

3802           ++time[0];

  • 修正 系统时间
3803          spl1();
3804          if(time[1]==tout[1] && time[0]==tout[0])

3805           wakeup(tout);

3806          if((time[1]&03) == 0) {

3807           runrun++;

3808           wakeup(&lbolt);

3809          }

  • 每4秒
    • 置runrun,强制进行进程调度
    • 唤醒因lbolt睡眠的进程,睡眠原因 :lbolt
(需要等待较长时间才进行的事务处理,一般用于与外设同步,如在pc-11驱动函数pcopen中使用)
3810          for(pp = &proc[0]; pp < &proc[NPROC]; pp++)

3811          if (pp->p_stat) {

3812           if(pp->p_time != 127)

3813                pp->p_time++;

3814           if((pp->p_cpu & 0377) > SCHMAG)

3815                pp->p_cpu =- SCHMAG; else

3816           pp->p_cpu = 0;

3817           if(pp->p_pri > PUSER)

3818                setpri(pp);

3819          }

3820          if(runin!=0) {

3821           runin = 0;

3822           wakeup(&runin);

3823          }

  • 唤醒 等待图像调入内存的进程
  • 调度决策频率 1次/秒
3824          if((ps&UMODE) == UMODE) {

3825           u.u_ar0 = &r0;

3826           if(issig())

3827                psig();

3828           setpri(u.u_procp);

3829          }

3830     }

3831 }

3832 /* ------------------------- */

Ref

⚠️ **GitHub.com Fallback** ⚠️