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

Source

  • 按照指定的优先权使进程进入睡眠状态,并且调用swtch进行进程切换调度
  • 传入2个参数 , chan ,pri

2054

2055 /*

2056  * Give up the processor till a wakeup occurs

2057  * on chan, at which time the process

2059  * The most important effect of pri is that when

2060  * pri<0 a signal cannot disturb the sleep;

2061  * if the pri>=0 signals will be processed.

2062  * Callers of this routine must be prepared for

2063  * premature return, and check that the reason for

2064  * sleeping has gone away.

2065  */

2066 sleep(chan, pri)

2067 {

2068     register *rp, s;

2069

2070     s = PS->integ;

2071     rp = u.u_procp;

2072     if(pri >= 0) {

2073           if(issig())

2074                    goto psig;

  • 当进程睡眠优先权大于等于0时,在睡眠前先判断有无 信号,若有,则进入 信号处理
2075           spl6();
  • 关中断
  • 此处关中断的原因:
    • 为了防止在2076与2077之间由于中断而插入wakeup(chan),将p_wchan置回为0
    • 接着2007行继续会进入睡眠状态,于是造成进程的睡眠原因为0,从而永远都无法被唤醒
2076           rp->p_wchan = chan;

2077           rp->p_stat = SWAIT;

2078           rp->p_pri = pri;

  • 睡眠原因置为 chan
  • 状态置为低优先权睡眠状态,参看进程优先级
  • 进程优先权置为 pri
2079           spl0();
2080           if(runin != 0) {

2081                    runin = 0;

2082                    wakeup(&runin);

  • 如果runin被置,清runin标志,唤醒在runin上睡眠的0#进程,执行进程图象调入调出的工作
  • 关于为何唤醒的是0#进程,参看进程调度之0#进程
2083           }

2084           swtch();

2085           if(issig())

2086                    goto psig;

  • 在结束时再判断一下是否有 信号
  • 若有,则进入 信号处理
2087     } else {

2088           spl6();

  • 关中断
  • 此处关中断的原因同2075行
2089           rp->p_wchan = chan;

2090           rp->p_stat = SSLEEP;

2091           rp->p_pri = pri;

  • 若进程睡眠优先权小于0
  • 则将睡眠原因置为chan
  • 将进程状态置为高优先级睡眠状态,参见进程优先级
  • 将进程优先权置为pri
2092           spl0();
2093           swtch();
2094     }

2095     PS->integ = s;

  • 睡眠结束并且被选中上台时恢复睡眠前的处理机状态字
2096     return;

2097

2098     /*

2099     * If priority was low (>=0) and

2100     * there has been a signal,

2101     * execute non-local goto to

2102     * the qsav location.

2103     * (see trap1/trap.c)

2104     */

2105 psig:

2106     aretu(u.u_qsav);

2107 }

2108 /*-------------------------- */

Ref

Caller

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