関数のコメントには以下のように書かれている。
つまり、優先度を再計算して、現在実行中のプロセスより優先度が高くなっていたら再スケジューリングのためにrunrunを++する、と書かれている。ところが実際のコードは2150 /* 2151 * Set user priority. 2152 * The rescheduling flag (runrun) 2153 * is set if the priority is higher 2154 * than the currently running process. 2155 */
2156 setpri(up)
2157 {
2158 register *pp, p;
2159
2160 pp = up;
2161 p = (pp->p_cpu & 0377)/16;
2162 p =+ PUSER + pp->p_nice;
2163 if(p > 127)
2164 p = 127;
2165 if(p > curpri)
2166 runrun++;
2167 pp->p_pri = p;
2168 } であり、再計算した優先度が、実行中のプロセスの優先度より低ければ(if (p > curpri))再スケジューリング(runrun++)となっている。で、Lions本によれば「自力でバグでない事を確認せよ(ヒント:呼び出し時の引数)」との事。さっそくgrepした感じではsetpriはプリエンプションの時に呼ばれているように見える。つまり、走行中のプロセスが持ち時間を使い切ってタイマーによって割り込まれた際に、CPU使用時間を計上してからsetpriを呼んでいる。優先度を下げる方向で再計算させているのであり、curpriは走行中のプロセスが選択された時の優先度。 下げてるんだからここでは常に「p > curpri」が成立するのは自明であり、再スケジューリングが走るのはしかるべきである。つまりコメント側が間違っている、という理解。バグではないという事で納得した・・・と思ったんですが。。。
例の2238 Clubにはバグという記述がありました。確かにベル研の資料には以下のように書かれている模様。
むぅ・・・公式にバグと言ってるわけだから、やっぱりバグなのだろうか。。。30) Bug fix in "setpri()": p>curpri should be p<curpri.
真実を知っている人がいたら、ぜひ答えを教えて下さい。
1 件のコメント:
自己レス。
(4)に書いた通り、clockをきちんと読むと、実行中プロセスの優先度は下げ、それ以外のプロセスの優先度は上げてsetpriを呼んでいる。よってやはりコード側のバグと考えるのが正解か。実際、どっちでも大差ないけど。直した方が無駄なswtchが減る?
コメントを投稿