9 章: メモリ管理
9 章ではメモリマップに割り当てられていない空きメモリを OS が管理し、アプリケーションに割り当てる & アプリケーションが開放する仕組みを作ることが目的。
まずはメモリチェックから。 メモリチェックはアドレスに 0xaa55aa55 を書いて、bit 反転させてチェックするという仕組み。でも、これを律儀に全アドレスにやっても無駄なので、1K ごととかそういう感じでメモリチェックをし、 OS が空きメモリサイズを獲得するという流れ。ここで面白かったのは「アドレスに値を格納して反転させてチェックする」というこんな感じの処理:
unsigned int old, *p, pat0, pat1;
unsigned *p /* チェックするアドレス */
old = *p; /* いじる前の値を覚えておく */
*p = 0xaa55aa55; /* ためしに書いてみる */
*p ^= 0xffffffff /* そしてそれを反転してみる */
if (*p != 0x55aa55aa ) { /* 反転結果になったか? */
*p = old;
break; /* チェック失敗 */
}
がコンパイラによって最適化されて「なにもしない」になっていたこと。本の中ではこのメモリチェック処理をアセンブラで書いて最適化されることを回避していたが、実は変数 p の定義を
volatile unsigned int *p;
とすることで最適化を回避しても OK。実際この方法の方がスマートだし、動作させてみたがメモリチェックも正しく動作した。じゃあ、なんでアセンブラで関数を用意したのかというと、おそらく OS 作りとは直接関係のないコンパイルの最適化の解説の後にさらに volatile の解説をするのを避けたのではないかなというのが僕の予想。普通はアセンブラでわざわざ作るよりは volatile で…となるんだろうけど、アセンブラの関数を作る方法は 9日目までに既知のものとなっているし。
で、本題のメモリ管理のほうはテーブルを用意して「空き領域の開始アドレスとサイズ」を覚えさせておくという方法。テーブルの数は 1000 個。これが充分かどうかは分からないのだけど隣り合う領域をマージして空きテーブルを最大限増やす工夫もできているから充分なのかなぁ。
この処理はテーブルに配列を使っているのだけど、malloc 使って動的リストで管理したほうがいいんじゃないかと、おろかなことを考えてしまった。malloc を使えるようにするためのメモリ管理なのに、そこで malloc を使えるわけがない…。
9 章終わり。1 章分で増えるコードも量が大きくなってきた。理解にも時間がかかるなぁ。











コメントする