A: タイマー機能の有効化
ARPとTCPのモジュールは、キャッシュの有効期限管理や再送制御のためにプロトコルスタックへタイマーを登録します(timer_register())。しかし、4.2で追加したtimer.cは中身のない空のスタブで、timer_register()は登録内容を保持すらせず、タイマーを駆動する仕組みもありません。タイマーの登録から発火までを実装して、タイマー機能を動作させてください。
目標
- 一定間隔で、登録済みのタイマーハンドラが呼び出されるようにする
- ARPキャッシュが一定時間で消えること(
arp_timerの発火)を確認する
ヒント
タイマー機能は「登録の保持」「周期的に発火するきっかけ」「登録されたハンドラの実行」の3つに分けて考えると実装しやすいです。
- 登録の保持: 空スタブの
timer_register()を実装し、渡された間隔(interval)とハンドラ、および前回実行時刻を管理領域(リストなど)に保持できるようにします。この部分はmicropsのLinux版timer.c(platform/linux/timer.c)の実装がほぼそのまま流用できます。 - 周期的なきっかけ: xv6では既にタイマー割り込み(
clockintr())が周期的に発生しています。ネットワーク処理をタイマー割り込みのコンテキストで直接行うのは避け、3.5で実装したソフトウェア割り込み(intr_raise())を利用して、処理をソフトウェア割り込みのハンドラへ受け渡すのがよいでしょう。 - ハンドラの実行: 保持したタイマーのリストを走査し、各タイマーの間隔と前回実行時刻からの経過を比較して、期限が来たものを呼び出します。時刻の取得には2.3で実装した
gettimeofday()が使えます。
Note
micropsのLinux版
timer.c(platform/linux/timer.c)が実装の参考になります。Linux版はPOSIXタイマーとシグナルで周期的なきっかけを作っていますが、その部分をxv6のタイマー割り込み+ソフトウェア割り込みに置き換えるイメージです。
発展
Goldfish RTCにもアラーム機能があります。タイマー割り込みではなくRTCのアラームを使って周期的なきっかけを作ることもできます。余裕があれば挑戦してみてください。