師走の挨拶どうもこんにちは、突撃隊です。64bit自作OS「minOS」をちまちま作っとるのですが、11月でついにマルチタスクを実装できたので解説します。github.com設計スレッドかプロセスかOSのタスク単位としてとりあえずスレッドを実装することにしました。プロセスはメモリ空間を分離しなくてはいけないので、その分コーディングが大変だからです。スレッドならスタックを用意してあげるだけなので簡単簡単。構造体スレッドごとの構造体はこんな感じにしてみました。上から順にスレッドのスタック領域の開始アドレススレッドごとのスタックポインタスレッドで実行する関数の情報スレッドの状態スレッドキューに登録した際のインデックスです。順番に解説していきます。関数を用いてスタック領域を確保します。関数のソースコードはこちら。しますが、スタックポインタは構造体に持たせるほうがやりやすそうです。関数ポインタとその引数を受け取ります。3種類を用意しておきました。スレッドキューに登録した際のインデックスminOSではスレッドのキューはただの配列です。スレッドの削除時に配列に登録したときのインデックスが必要になるのでパラメータとして持たせてあります。どのタイミングでスレッド切り替えをするかタイマ割り込みのタイミングでスレッド切り替えをすることにしました。タイマ割り込みの何回かに一回にスケジューラを呼び出してタスクを切り替えます。coinsLT#110で話したときの資料が詳しいです。今回のキモはスレッドのスタックの初期化処理とスレッドを切り替える瞬間の処理です。関数でスレッドの生成を行います。構造体に各種情報を登録していきます。スレッドのスタックの初期化を行います。この時スタックポインタの値も調整されます。関数の実装はレジスタをいじるのでアセンブラで書きます。保存し、今のスタックに戻ってこれるようにします。関数の第1引数で受け取ったスレッドのスタックポインタをロードして、スレッドのスタックの初期化作業を始めます。している数値が初期化のデフォルト値に対応しています。渡す引数を設定しています。