個人用雑記

勉強したことを書いていければなーと

30日でできる!OS自作入門(Day 12)

タイマ

ついにきましたね、タイマ。

タイマって?

timer、時計ですね。一定時間ごとに割り込みを発生させてくれるというとても重要で便利なものです。
このタイマのおかげで非常にたくさんのメリットが生まれます。例えばHLT命令で停止している時でもタイマは割込みを発生してくれるので、どれだけの時間が経過したかをCPUを休ませながら把握できます。また、今後くるであろうマルチタスクにおけるコンテキストスイッチを発生させるタイミングもタイマによって実現できます。

PIT(Programmable Interval Timer)を使ってみる

このPITは設定した周期毎に割り込みを発生させてくれます。例えば、11932を設定すると100Hzの動作、つまり10msごとに割り込みを発生させてくれるようになります。あとはこの割込みに対応するための割り込みハンドラを作成し、IDTに割り込みハンドラを登録すればこのタイマを扱えるようになります。このあたりの流れはキーボードの割り込み処理何かとほとんど同じです。
割り込みハンドラでとりあえずカウンタを増やせばこのカウンタは1秒間に100回増えることになります。

タイムアウト機能

タイマをCPUに依らず実時間で扱えるということは、「○○秒経ったら教えてくれ」というような扱い方ができるということです。使い方は簡単で、割り込みのタイミングで設定した秒数を減らしていき、0になったら通知すればよいだけです。
といいたいところでしたが、これにはいくつか問題があります。
まず、複数のタイムアウトに対応できていない点です。まぁ、これは配列か何かを用意してそのすべてを割り込みごとに減らすようにすれば実現はできます。
もう一つは、時間がかかるという点です。いつしか、割り込みはできるだけ短くするべきという話がありました。しかし、現状のコードは複数のタイムアウトに対応させてもさせなくても、遅いです。

割込みは素早く

前の記事を見ても毎回何かしらを高速化してますね。(それこそが自作における本質な気がしますし、たくさんの知識を身に着けられるので好きです。)
さて、ここでもいくつかの高速化の方法が提案されるわけですが、例のごとく一気に最後の段階を見ます。
見たかったのですが、翌日の内容にさらなる高速化があって何とも言えない気持ちになってしまいました・・・とりあえず、現状の高速化を考えてみます。
・毎回複数のタイムアウトすべてをインクリメントするのではなく、一つカウンタ変数を用意して、インクリメントするのはその変数だけにする。
・下敷きと同じように順番を管理する構造体と中身を持った構造体の二つを用意し、 期限が短いものからタイムアウトしているかを確認していき、一度でもタイムアウトしていなかったら確認をやめる。
という高速化を取っています。 とはいえ、この方法にも欠点はあって、挿入する際に割り込みが発生しては困るので一時的に割り込みを禁止する部分が出てしまいます。こればっかりは事前の登録に時間をかけるか、処理中に時間をかけるかのトレードオフですね。

Day13へ

明日も引き続きタイマです。さらなる高速化、楽しみですね。(まぁ、もう読んでいるのですが。)ベンチマークテストのようなものもやってみるようです。