割り込みハンドラ
![]() |
割り込みハンドラ(わりこみハンドラ、英: Interrupt handler)または割り込みサービスルーチン(わりこみサービスルーチン、英: Interrupt Service Routine, ISR)は、割り込み受け付けによって起動されるオペレーティングシステムやデバイスドライバのコールバックルーチンである。割り込みハンドラは割り込み原因によってそれぞれ存在し、割り込みハンドラがそのタスクを完了するまでにかかる時間も様々である。
割り込みハンドラはイベントハンドラに対応してハードウェアに近いところで動作する。これらのハンドラは、ハードウェアの割り込みかソフトウェアの割り込み命令で起動され、ハードウェア機器のための処理をしたり、システムコールなどのCPUモードの移行を行ったりする。
概要
[編集]最近のオペレーティングシステムでは、割り込みハンドラは2つの部分に分かれている。第1レベル割り込みハンドラ(First-Level Interrupt Handler、FLIH)と第2レベル割り込みハンドラ(Second-Level Interrupt Handler、SLIH)である。FLIHは、ハード割り込みハンドラ、高速割り込みハンドラなどとも呼ばれ、SLIHは割り込みスレッド、低速割り込みハンドラなどとも呼ばれる。
FLIHは、プラットフォーム固有の最小限の割り込み処理を実装している。割り込みが発生すると、まずコンテキストスイッチがあり、FLIHが実行される。FLIHでは、割り込みのコンテキストでしなければならない処理として、割り込みの刈り取りやその時点でしか入手できない重要な情報の記録などを行い、時間のかかる割り込み処理のためにSLIHの実行をスケジューリングする。
FLIHはプロセス実行におけるジッターを生じる。また、FLIH実行中は割り込みもマスクされる。リアルタイムオペレーティングシステムでは、あるコードが予定された時間内に実行完了することを保証しなければならないため、ジッターの低減は非常に重要である。ジッターを低減し、割り込みをマスク(禁止)することで情報が失われる可能性を低減するため、FLIHの実行時間は極力短くしなければならず、可能な限り処理をSLIHに委譲する必要がある。最近のコンピュータでは、FLIHは機器やプラットフォーム依存の処理を全て行い、SLIHで時間のかかるプラットフォームに依存しない処理を行っている。
ハードウェアの割り込みを処理するFLIHは一般に、実行されている間は対応する割り込みをマスクしている。そうしないで割り込みを受け付けるようにしていると、同じ割り込みベクトルによって多重にプリエンプションが発生し、スタックオーバーフローの原因となる。割り込みに優先順位がある場合、FLIHは対応する割り込みと同じか下の優先度の全ての割り込みをマスクする。
SLIHはプロセスのような時間のかかる割り込み処理を行う。SLIHはハンドラ毎に専用のカーネルスレッドを持つ場合と、カーネル内の汎用スレッド群を使う場合がある。これらのスレッドはOSのランキュー上に置かれて、ユーザースレッドと同様にスケジューリングされる。
割り込みスレッド
[編集]Solaris、macOS、FreeBSDなどのOSでは、割り込みスレッド(英: Interrupt thread)と呼ばれる方式が採用されている。割り込みハンドラは高優先度のスレッドであり、割り込みによって起動され、排他制御でブロックされるという重要な特徴がある。これによってカーネル内のロック機構が大幅に単純化される。また割り込みスレッドは、より優先度の高い割り込みスレッドでプリエンプションされる。
割り込みスレッドを用いることにより、割り込みハンドラの大部分を制限の多いリエントラント実装や割り込みそのもののマスクではなく、制限がより緩く、かつ並列度が高いスレッドセーフのみの条件下で実装することができる。割り込みスレッドを使用しない場合、割り込まれた処理は割り込みハンドラの処理が終了するまでは全く実行できないため、割り込みハンドラがリエントラントでないと予期せぬ挙動となる。割り込みスレッドを導入すると割り込みハンドラの処理がスケジューリングの対象となるため、割り込みスレッド全体に対するリエントラント性は(スレッドとして決して実装できない、割り込みスレッドの起動処理を除いて)必要なくなる。
割り込みスレッドが本来の割り込み処理に近い挙動をとるためには単純にスレッドとしての実装だけでなく、特にカーネル内にて[1]割り込み向けではないスレッドを割り込みスレッドがプリエンプトすることが必要となる。SVR4では実際にカーネル内に限定的なプリエンプション・ポイントを実装したが実用に耐える性能は実現できず、Solarisにてより粒度が細かいロックをカーネルに導入する動機となった。
脚注
[編集]- ^ ユーザモードのスレッドをカーネルモードのスレッドがプリエンプトすることは一般に可能なので問題にならない。