Next: KL1レベルでの割り込み処理
Up: 例外処理
Previous: 例外処理
割り込み時の処理
割り込みが発生した場合、
先に述べたように、KLICでは実行中には一般的には割り込み処理を行わず、
割り込みがあったことのみを記録しておき、後にklic_interruptにて処理を行う。
割り込みがあった「その時」に実行されるコードについての
記述は、runtime/signal.c中で記述されている。
KLICでの割り込み処理は、基本的に以下のように2段がまえになっている。
- 各割り込み種別(UNIXのSIGXXX)毎に、UNIXレベルの割り込みハンドラが存在し、
また、各割り込み毎に「割り込みフラグ」(signal_flags)がある。
このハンドラは、割り込みが起きたときには、当該
「割り込みフラグ」をonにすることにより「割り込みがあった」ということを
記録し、heaplimitを0とするだけである。
このハンドラは、handle_signal()なる既定の関数で、runtime/signal.cで
定義されている。
- リダクションの切れ目にて、ヒープ検査の際に割り込みがあったことが
確認された場合には「割り込みフラグ」を検査し、割り込み種類別の
処理を実行する。各割り込み毎の処理は、割り込み処理表(signal_handlers)に
記録されている。この処理は後述する、klic_interrupt()内で行われる。
つまり、割り込みハンドラには2通りがある。以下の説明で、特に
断ることなく「割り込みハンドラ」と称した場合には、後者、つまり、
リダクションの切れ目で行われる処理を記述したハンドラを指す。
この「割り込みハンドラ」の関数仕様は以下のようになっている。
handler(allocp, signal)
- q *allocp:
- ヒープトップ。つまり、割り込みハンドラ中では、
ヒープ割付を行うことが可能で、したがって、KL1のゴールをわりつけることも
できる。
- int signal:
- 割り込み種別(SIGXXX)
SIGINT, SIGALRMについては、以下のように、特殊な割り込みハンドラを
システム側で設定している。
- SIGINTに関しては、sigint_interruptをセットするだけの処理を行うハンドラ
(default_sigint_handler)が設定される。
- SIGALRMに関しては、そもそも、
UNIXレベルのハンドラが異なっており、
timer_expiration_handler がセットされる(タイマについての処理は
runtime/timer.cにて記述される)。
タイマ割り込みは、システムで利用している一方、ユーザも利用する可能性がある
ため、仮想化の処理を行い、実効上、複数のタイマを同時に
設定できるようになっている。
これまでの説明で登場しなかった
割り込み処理に関して定義されている主な関数群の説明を以下に記述する。
- klic_signal_handler():
- 割り込みフラグを参照し、
割り込みフラグがonである場合には当該処理を割り込み処理表を参照することにより
実行する。後述されるklic_interupt内で呼びだされる。
- add_signal_handler():
- 割り込み処理を登録する。
つまり、
- 割り込み処理表に指定された関数を登録する
(add_slit_check_signal_handler())。
- 指定された割り込み種別に対してsigaction()にてUNIXレベルの割り込み処理
を設定する。
- init_general_signal_handling():
- 割り込み処理表、
割り込みフラグを初期化する。
Sekita Daigo
1998-05-18