割込み(2)

割 込 み(2)
オペレーティングシステム
第6回
今回の内容


前回の復習
割込み処理の具体例
 印刷処理
復 習 (1)


割込みとは
 事象が発生
 現在,実行中のプログラムを中断
 事象の処理
 中断したプログラムを再開
プログラムの実行中に,発生したことを先に処理
 プログラムは,そのことを考えずに作ることが
できる
割込みは,いつ何が起きるか分からない(除く 割出し)
そのことを予想して,プログラムを作ることは困難
(実はできる → 次回 今回)
復 習 (2)

プログラムと割込み処理プログラムの関係
元のプログラムは,
“割込み”を考慮せず
に作ることができる
復 習 (3)


割込みで可能になること
割込みのレベルと割込み禁止
 多重レベル割込み(優先度)
 割込みが禁止される場合
復 習 (4)

割込み(事象)の分類
 外部割込み
 内部割込み
TSSの実現
簡単に
TSSの実現(1)


プログラム1(pro-1)とプログラム2(pro-2)をTSS
で実行する
既に実行が始まっているものとする

pro-1とpro-2が交互に実行
TSSの実現(2)




タイマーにある時間を設定
pro-1を実行
設定した時間経過するとタイマー割込みが発生
pro-1を中断して,タイマー割込み処理プログラ
ムを実行
TSSの実現(3)

割込み処理プログラム
 中断したpro-1の状態(コンテクスト)を保存
 中断中のpro-2の状態(コンテクスト)を設定
 タイマーにある時間を設定
 pro-2を再開
TSSの実現(4)



設定した時間が経過
タイマー割込み発生
割込み処理プログラム開始
TSSの実現(5)


割込み処理プログラム
 中断したpro-2の状態を保存
 中断中のpro-1の状態を設定
 タイマーにある時間を設定
 pro-1を再開
というように,pro-1とpro-2を交互に実行
障 害 対 応(1)



例えば,除数が0の割算
何らかの誤りがあるわけで,その先を実行するこ
とはムダ
除数が0の場合,“演算例外”の割込みが発生
障 害 対 応(2)

演算例外の割込み処理プログラム
 対象プログラムの実行を打ち切る処理

場合により,除数を変更し,除算をやり直す,
ということもありうる
例題記述の準備
プログラムの記述(1)

制御プログラムを記述する言語
 Cの一部
プログラムの記述(2)

a=b;
 b(一般に式)の値を計算して,
変数aに格納する
プログラムの記述(3)

if (条件) { … }

条件が成立する(真)場合のみ,
{ … }の部分を実行する


条件 a = = b
aとbが等しいか?
条件 c
cが真か?(cが正しいか?)
プログラムの記述(3)


while (条件) { … }
①条件を調べる
②成立する場合は,{ … }を実行してから①に戻
る
③成立しない場合は,この先に進む
条件が成立する間(正しい間),
{ … }を繰り返し実行する
割込み処理の例
ちょっと難しいかも知れないが,
雰囲気は分かって欲しい
印刷処理
プリンタの制御
 想定するプリンタ
CPUがプリンタの速度に合わせると効率が悪くなる
 1文字ずつ印字
 現在あるかどうかは不明
割込みで,どのようにこのギャップを埋めるのか!?
 過去にはあった(使ったことがある)


プリンタの印字速度は遅いが,CPUの計算速度
は速い
プリンタの使い方



プログラムから,印字する1文字分のデータ(文
字コード)をプリンタに送る
プリンタに,(先に送ったデータの)印字開始を指
示する
 印字終了までに時間がかかる!
注意
プリンタが印字動作中に印字データを送ることは
できない(送っても無視される)
プ リ ン タ の 制 御 命 令(1)

send(data)

プリンタにdata(データ,印字する文字の文
字コード)を送る手続き
プ リ ン タ の 制 御 命 令(2)

start( )

プリンタに既に送ってあるデータの印字を開
始させる手続き

印字には時間がかかるが,その終了を
待たずに手続きの呼び出し元に戻る
startの次を実行しているときは,
まだ印字中である
プ リ ン タ の 制 御 命 令(3)

busy( )

プリンタが動作中,つまり印字中ならYES,
そうでないならNO
を返す,プリンタの状態を調べるための関数

プリンタは動作中にsendでデータを送られて
も受け取ることができないので,この関数で
状態をチェックする
割込みを用いないプログラム
印字データを用意
send(data);
start( );
while( busy( )==YES ) { ; }
印字データをプ
リンタに送る
このような部分が,
プログラム中に
たくさんある!
次の印字データ用意
プリンタがbusyの間(印字中
以下同様 の間),何もしないことを繰り
返す(印字の終了を待つ)
印字終了後,先に進む
start終了直後は,
プリンタは印字動作
中
プログラムとプリンタの動作
while( busy( )==YES ) { ; }

プリンタの動作中は,プログラムの実行が実質上止まる
割 込 み の 利 用(1)

印字終了で,プリンタが割込みをかけられる
 外部割込み
 “プリンタの印字終了”という事象により,割込
み発生
 利用者プログラムを中断
 割込み処理プログラムの実行
 その終了後,中断していた利用者プログラム
を再開
bufferが“空”かどうか
割 込 み の 利 用(2)
YESなら“空”又は“プリンタに送付済みのデータ”,
NOなら“プリンタに未送付のデータ”



2つのプログラムから読み書きできる変数
empty:YESまたはNO(初期値はYES)
buffer:印字データを一時的に格納
emptyがNOであったら,
何もしないことを繰り返し続ける。
割 込 み の 利 用(3)
そのうちにemptyがYESになり,先
に進む
利用者プログラム
印字データを用意
while(empty = = NO) { ; }
buffer = data; empty = NO;
if(busy( )==NO) {
send(buffer);
start( );
empty = YES;
}

プリンタが印字中でな
ければ …
プリンタは動作中であるが,
プログラムは先に進む
割 込 み の 利 用(4)

プログラム中に,
青枠部分がたくさんあ
る
1文字目
2文字目
3文字目
割 込 み の 利 用(5)

割込み処理プログラム(利用者プログラムとは全
く別のところにある – OSの一部)
if(empty = = NO) {
send(buffer);
start( );
empty = YES;
}
割 込 み の 利 用(6)

以降,1文字目,2文字目と順に印字することを
追いかける
割 込 み の 利 用(7)
利用者プログラム
while(empty = = NO) { ; }
buffer = data; empty = NO;
if(busy( )==NO) {
send(buffer);
start( );
empty = YES;
}
1文字目が用意できた
empty は YES
印字データをbufferに
emptyをNOに
プリンタは動作中でないから,
busyではない
bufferのデータを送り,
プリンタをスタート
emptyをYESに
2文字目の用意を始める
(プリンタは印字中)
割 込 み の 利 用(8)
プリンタが1文字目を印字中に,
2文字目の用意ができたとする
割 込 み の 利 用(9)
利用者プログラム
while(empty = = NO) { ; }
buffer = data; empty = NO;
if(busy( )==NO) {
send(buffer);
start( );
empty = YES;
}
2文字目が用意できた
empty は YES
印字データをbufferに
emptyをNOに
プリンタは動作中なので,
実行しない
2文字目はbufferに入れたまま,
3文字目の用意
(プリンタは1文字目を印字中)
割 込 み の 利 用(10)
1文字目の印字
終了の割込み
割 込 み の 利 用(11)
if(empty = = NO) {
send(buffer);
start( );
empty = YES;
}
割込み処理プログラム
emptyはNO
buffer中のデータ(2文字目)を
プリンタに送る
プリンタをスタート
emptyをYESに
3文字目を用意している
割り込まれたプログラムを再開
割 込 み の 利 用(12)
割込みなし
割込みあり
CPU(プログラム)とプリンタが同時に動作
効率がよくなる
一言でまとめると



CPU→プリンタ→CPU→プリンタ→…
と交互に動作するのではなく,
プリンタの動作中も,CPUは動作することにより,
CPUを無駄なく使う
 CPUと入出力装置の同時実行
実際には,この例のようにならないこともある(多
い)
プログラムとプリンタの動作 再
while( busy( )==YES ) { ; }
プリンタの印字終了と言う事象を待つ
事象の発生を監視するという割込み処理みたいなこと
割込みという機能がないと,同様なことを
利用者のプログラムで行うことになる

プリンタの動作中は,プログラムの実行が実質上止まる
補 足
とりあえず,今までのことを理解して欲しい
補 足(1)

何文字目かの印字データが用意できたとき
emptyがNOであったらどうなるか?
 buffer中に,直前の文字
 さらにその前の文字をプリンタが印字中
 つまり,印字される文字がたまってしまってい
る
そのうちに,印字終了の
 実際には,このような状態になることがほと
割込みが発生する!
んどである
補 足(2)
emptyがNOなので,ここで待つ!
while(empty = = NO) { ; }
buffer = data; empty =
NO;
if(busy( )==NO) {
send(buffer);
start( );
empty = YES;
}
そのうちに,印字終了割込
みが発生する
if(empty = = NO) {
send(buffer);
start( );
empty = YES;
}
emptyがYESになる
補 足(3)



bufferを配列

参照 補足(1)
利用者プログラム中の印字関係の部分を手続
きにする
割込み禁止部分が必要
補 足(4)

割込みを用いないプログラムの変更
印字データdata用意
while( busy( )==YES ) { ; }
send(data);
start( );
まとめ

割込みのメリットのひとつ
 CPUと周辺機器の動作速度に差
 CPUが周辺機器につきあっていると効率が悪
い
 CPUは周辺機器に命令を出し,周辺機器の動
作終了を待たず先に進む
 周辺機器は動作終了を割込みによりCPUに
通知
次回



割込み発生のタイミングにより,正しく処理できな
くなる場合がある
クリティカルレース
際どい部分(クリティカルセクション)