Handle昔話 [昔話]
Carbonな人には問題ないだろうけどMac OSのHandleには初め驚き、そのあと苦労した。
OS9以前のMacではメモリブロックを要求する場合、ほとんど必ずHandleというポインタへのポインタを使う(何故かWindowの構造体はHandleではなくPtrなのが依怙贔屓)。
OSXではCoreServises/MacMemory.hのなかに
typedef char * Ptr; typedef Ptr * Handle;
と定義されている(ヘッダからのコピー)。
メモリを要求するときは
Handle aHandle = NewHandle(handleSize);
等とするのであるが、なんでこんなことをするかと言うと、驚くなかれ昔のMacは仮想メモリが無かった。
ロードされたアプリケーションのすべてが一つのメモリ空間を行儀良く使わなければいけなかった。あるアプリケーションがメモリブロックを要求するとシステムにたった一つのヒープからOS(memoryManager)が割り当てる。割当/解放を繰り返すとヒープが穴だらけになる。ほっておくとメモリは余っているのにメモリブロックの割当が失敗するようになる。これを避けるためにメモリブロックへのポインタを渡すのではなく、メモリブロックのポインタはOSが管理し、そこへのポインタ(Handle)をアプリケーションに渡す。ポインタそのものはOSが管理しているのでコンパクションが必要になったらOSが勝手に行うことができる。
だからアプリケーションはいつメモリブロックの場所が変わっても良いようにプログラムしなければならない。ブロック本体をアクセスするときは当然ポインタが必要なのでHandleを手繰ることになるが、手繰った値をずっと持っていたらいつの間にかブロックの位置が変わっていた、等と言うことになる。
古いMac OSは今で言うプリエンプティブではなかったのでWaitNextEvent()を呼ばないかぎりOSに制御は渡らないのだけど数値計算の場合、深いループの中に入ってしまうとマシン全体がハングしてしまったように見えるので、それなりの頻度でWaitNextEvent()をループの中でも呼ばなければならない。呼んだ後ちゃんとHandleの先を更新しないとひどい目に遭う。たいていの場合クラッシュした(あたりまえか)。これがunixから来た、メモリはやりたい放題でもじぇんじぇん気にせずにすんであるだけ使って放ったらかしでもプロセスが終わってしまえば何事も無くシステムは稼働し続けるのに慣れた当時の若者にはとんでもなく苦痛だった。
そもそもなんでMacに来たかと言うと、時間を遡ること二十数年前...
「なんで1台何百万もするワークステーションなんてものを使わなければいけないんだ?」
「だって僕の仕事は自分でプログラムしないといけないんですう」
「98があるだろ、NECの98が。みんなあれをプログラムして使ってるじゃないか」
「だってあれはプログラミングが大変なんですう。512kBの2次元FFTを64kBごとにメモリ領域を切り替えながらプログラムするなんて人間業じゃないですう」
「じゃあこれはどうだ。なんのことはないCPUはお前の「わーくすてーしょん」と同じじゃないか。そのくせ値段は5分の1だろが。これを使えこれを」
で、手に入れたのがMacIIだった。確かにCPUはHPのワークステーション(ビットマップディスプレイ(これも死語やな)を持ってX-windowが動くデスクトップのunixマシンを当時こう呼んだ)と同じモトローラの68020。まあ、これでもいいかと思ったのが運の尽き。
Handleを書くたびにあの課長の顔が今でも思い浮かぶ。彼ももう定年やなあ....
コメント 0