(注意)このブログは本家のほうの文章部分のみの転載です.ソースコードの配布,画像などについては本家のほうを参照してください.文章中のリンク先は面倒なのですべて本家のほうに変換してしまっているのでご注意ください.
前回の話の続きなのだけど,リアルタイム性のある厳密なタイマが必要な場合には,RTCを直接利用するのが適切だ.このため厳密性のあるタイマは,システム内で固定の数しか利用できない.まあタイマサービスを固定サイズの配列化して,配列をなめてタイマをかけるような実装をすれば(軽さを犠牲にして)数を増やすことはできるだろうが,利用数に上限があることには変わりは無い.
半面,一般的なスレッドではそれほど厳密なタイマが必要とされることは少なく,場合によっては数秒の誤差があっても実害は無いことも多い.このようなタイマは,RTCをひとつ利用して,タイマキューによってソフトウエア的に実現しても問題はない.ここまでは前回の話.
で,今回はextintrのもつタイマ資源(TIMER_NUMで定義されている数.現状で4個)のうちのひとつを利用して,タイマキューによるソフトウエアタイマサービスを実装してみよう.
もともとKOZOSはタイマサービスを持っているのだけどこれはタイマキューによって実現されているのでリアルタイム性は無い.なのでOSの内部に持っているのは適切ではない.ということで,従来の kz_timer() によるKOZOSのタイマサービスをスレッド化して,タイマキューを管理するタイマサービススレッドを作成する.
ソースは以下のような感じ.
タイマサービス用スレッドは timerd という名前にした.ファイルは timerd.c だ.
で,KOZOSの kz_timer() の処理部分(タイマキューの処理)を切り出して timerd.c に移動して,スレッド化している.あと kz_timer() のシステムコールまわりの定義をごっそり消してすっきりさせた.
timerd は extintr のタイマをひとつ利用して,ソフトウエアタイマサービスを提供する.使いかたは,タイマを起動したい時間をメッセージで送るだけ.タイマが満了するとメッセージを返してくる.タイマはタイマキューで処理されるので,複数スレッドから同時に利用できる.もちろんひとつのスレッドが複数のタイマをかけることもできる(ただしその場合,どのタイマが満了したのかをメッセージから判断できないね.これはそのうち対処が必要だろう).
くどいようだけど,内部ではタイマキューの検索処理などを行っているので,タイマに厳密性はない.タイマキューの長さによって,タイマ満了が多少遅れる可能性も十分にある.外部割り込みなどで extintr スレッドが動きっぱなしになってtimerd が動けないと,タイマが全然かからない,という可能性もある.
あと,細かいバグをちょっと直してある.まあこのへんは diff.txt を参照.
で,実験用に clock.c, clock2.c, clock3.c の3つのファイルを用意した.clock.c は extintr のタイマをひとつ利用して,1秒間隔でメッセージ出力する.clock2.c, clock3.c は timerd のタイマサービスを利用して,それぞれ1.5秒,1.8秒間隔でメッセージ出力する.
実行結果は以下.問題なく動作しているようだ.
前回の話の続きなのだけど,リアルタイム性のある厳密なタイマが必要な場合には,RTCを直接利用するのが適切だ.このため厳密性のあるタイマは,システム内で固定の数しか利用できない.まあタイマサービスを固定サイズの配列化して,配列をなめてタイマをかけるような実装をすれば(軽さを犠牲にして)数を増やすことはできるだろうが,利用数に上限があることには変わりは無い.
半面,一般的なスレッドではそれほど厳密なタイマが必要とされることは少なく,場合によっては数秒の誤差があっても実害は無いことも多い.このようなタイマは,RTCをひとつ利用して,タイマキューによってソフトウエア的に実現しても問題はない.ここまでは前回の話.
で,今回はextintrのもつタイマ資源(TIMER_NUMで定義されている数.現状で4個)のうちのひとつを利用して,タイマキューによるソフトウエアタイマサービスを実装してみよう.
もともとKOZOSはタイマサービスを持っているのだけどこれはタイマキューによって実現されているのでリアルタイム性は無い.なのでOSの内部に持っているのは適切ではない.ということで,従来の kz_timer() によるKOZOSのタイマサービスをスレッド化して,タイマキューを管理するタイマサービススレッドを作成する.
ソースは以下のような感じ.
タイマサービス用スレッドは timerd という名前にした.ファイルは timerd.c だ.
で,KOZOSの kz_timer() の処理部分(タイマキューの処理)を切り出して timerd.c に移動して,スレッド化している.あと kz_timer() のシステムコールまわりの定義をごっそり消してすっきりさせた.
timerd は extintr のタイマをひとつ利用して,ソフトウエアタイマサービスを提供する.使いかたは,タイマを起動したい時間をメッセージで送るだけ.タイマが満了するとメッセージを返してくる.タイマはタイマキューで処理されるので,複数スレッドから同時に利用できる.もちろんひとつのスレッドが複数のタイマをかけることもできる(ただしその場合,どのタイマが満了したのかをメッセージから判断できないね.これはそのうち対処が必要だろう).
くどいようだけど,内部ではタイマキューの検索処理などを行っているので,タイマに厳密性はない.タイマキューの長さによって,タイマ満了が多少遅れる可能性も十分にある.外部割り込みなどで extintr スレッドが動きっぱなしになってtimerd が動けないと,タイマが全然かからない,という可能性もある.
あと,細かいバグをちょっと直してある.まあこのへんは diff.txt を参照.
で,実験用に clock.c, clock2.c, clock3.c の3つのファイルを用意した.clock.c は extintr のタイマをひとつ利用して,1秒間隔でメッセージ出力する.clock2.c, clock3.c は timerd のタイマサービスを利用して,それぞれ1.5秒,1.8秒間隔でメッセージ出力する.
実行結果は以下.問題なく動作しているようだ.
hiroaki@teapot:~/kozos35>% ./koz
clock1 Mon Jan 19 21:51:36 2009
clock2 Mon Jan 19 21:51:36 2009
clock3 Mon Jan 19 21:51:36 2009
clock1 Mon Jan 19 21:51:37 2009
clock1 Mon Jan 19 21:51:38 2009
clock2 Mon Jan 19 21:51:38 2009
clock3 Mon Jan 19 21:51:38 2009
clock1 Mon Jan 19 21:51:39 2009
clock2 Mon Jan 19 21:51:39 2009
clock1 Mon Jan 19 21:51:40 2009
clock3 Mon Jan 19 21:51:40 2009
clock1 Mon Jan 19 21:51:41 2009
clock2 Mon Jan 19 21:51:41 2009
clock1 Mon Jan 19 21:51:42 2009
clock3 Mon Jan 19 21:51:42 2009
clock2 Mon Jan 19 21:51:42 2009
clock1 Mon Jan 19 21:51:43 2009
clock1 Mon Jan 19 21:51:44 2009
clock3 Mon Jan 19 21:51:44 2009
clock2 Mon Jan 19 21:51:44 2009
...