2009年11月5日木曜日

Lions' Commentary (4) -プリエンプション-

setpri()の疑問はclock周りまで読み進めれば理解できるかな、と思ってたんだけど。。。どうもclock.cで実装されているはずのプリエンプションが理解できない。というか、やってないように見える。

タスクスイッチするにはrunrunが非0にならなければいけないわけだけど、runrunを非0に設定するのはslp.cのsetpri()とsetrun()、あとはclock.cの中だけ。だけど、clock.cの中の処理といえば、タイマーの再設定、コールバック関数の呼び出し、CPU時間の累積くらい。それ以外は1秒に1回プロセス全体の優先度補正をしてるのと、4秒に1回、神の雷?で全プロセスを起こしてるだけ。優先度補正ではsetpri()を呼び出すし、神の雷でもrunrun++してるんだけど、これだと1秒に1回しかプリエンプションが起きない。そんなはずないよなぁ・・・(7版と見比べたけど神の雷が毎秒にかわってるくらいで本質的には差はなかった)。

実際以下のbusy loopのコードを走らせてみたけど 、普通に別端末でshellが滞りなく動いてるし。ひょっとしてI/Oで割り込みがかかるから? busy loopのコードどうしなら1秒単位でタスクスイッチする? う〜ん・・・まさか。
.globl _main
.text
_main:
jbr _main
.globl
.data
という事で、Lions' Commentaryでは11章まできましたが、まだまだプロセス制御でわからない事は多いです。風邪が治ってきたのでまた進捗は芳しくなくなるかもだし(笑。

あと、clock.cでタイマ割り込みハンドラを処理するあたり、callout配列の操作が末尾に暗黙の空エントリを期待してる。timeout()を見ると配列の大きさは気にせずに追加しちゃってるし。この辺りはまったく安全性を考慮されていないアドホックな実装になってますね。Lions'本によれば実際にはttrstrtからしか使われてないらしいので、まぁそういう事なんでしょうね。

0 件のコメント: