関数のコメントには以下のように書かれている。
つまり、優先度を再計算して、現在実行中のプロセスより優先度が高くなっていたら再スケジューリングのために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 */
であり、再計算した優先度が、実行中のプロセスの優先度より低ければ(if (p > curpri))再スケジューリング(runrun++)となっている。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 }
で、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が減る?
コメントを投稿