マルチタスク-1
1) タスクスイッチに挑戦
- 一つのCPUにでも複数のタスクを実行させるために、少しずつ切り替えながら行っているもの
- TSS (タスクステータスセグメント)
- JMP は 内部ではEIPを書き変えられてるもの
struct TSS32 {
int backlink, esp0, ss0, esp1, ss1, esp2, ss2, cr3;
int eip, eflags, eax, ecx, edx, ebx, esp, ebp, esi, edi;
int es, cs, ss, ds, fs, gs;
int ldtr, iomap;
};
- 一行目はタスクスイッチしても書き換えられない(backlinkは変わる場合がある)
- ldtr, iomap も同じだが、なんでもいいわけではない。ldtr は 0, iomap は0x40000000 に一旦しておく
- タスクスイッチは JMP 命令を使います
- Near (EIP) と Far モードがある (EIP+CS)
- JMP DWORD 2*8:0x0000001b はファーモード
-
2つのタスクある場合、TSS 2つ作ります。
- gdt にそれぞれ登録して
- 第1ステップとしてTRレジスタを切り替え
- gdt のインデックス番号 * 8 で LTR 命令を使います。
- JMPで別のセグメントに移動 JMP 4*8:0
- TSSレジスタの初期値を指定して上げる必要がある
- タスクBのスタックを設定
10秒後にタスクスイッチさせて反応なくなることを確認
2) もっとタスクスイッチ
- 5秒後にもとのタスク戻す
3) 簡単なマルチタスクをやってみる
- 各タスクごとに関数作るではなく、FARJMP の関数を作ってスイッチする方法
- 2ミリ秒ごとにタスクスイッチ
4) 簡単なマルチタスクをやってみる2
- タスクBに何かを表示させたい
- シートの情報はタスクAしか知らないので、共通のところに置く
5) スピードアップ
- 画面の再描画を1ミリ秒ごとに変更
- カウンタは速いが、画面の描画が遅くなった
- return してはいけない
6) スピード測定
- 一定期間にカウントの差分を出す
7) もっとマルチタスク
- 今はプログラム側からタスクスイッチさせているので本物ではないかもしれない
- プログラム関係なくタスクスイッチするのが本当のマルチタスク
- タスクの中でではなく、inthandler20 でFIFOキューから取り出してタスクスイッチする方法
- タスクBの無限ループのカウンタがある割には反応がいいかも