リエントラント(再入可能)なコード

text領域はメモリに常駐したまま複数のプロセスから使えるようにするコードには、いくつか方法論があります。

  • OSの側でローダがMMUに細工をしてtextは共有だけどdata,stackの領域は別物理メモリで持つ

一番シンプルな方法論です。WindowsのDLLやUnixのso,sa、WindowsCEのプロセスなどはこれです。

  • 論理アドレスは同じままstackは新たに確保する。その代わりdata領域は作らずにプログラムが自前でメモリブロックを取得する

MMUが無くても動くμITRONBREWはこれです。大域変数やstatic局所変数はプログラム内にアドレスが直接書き込まれてしまうので使えません。

  • C++の「純粋仮想関数」を実装するようにして、クラス自体をシステムに登録する。アプリケーションを立ち上げるときにはそのクラスをnewする。

Symbianなんかで使っている「ポリモーフィックDLL」がこれですね。BeOSもそうじゃなかったかな? static局所変数や大域変数が使えない制限は同じですが、通常の変数はthis経由で自然にアクセスできます。


一番いいのは最初の方法なのですが、MMUが必須でtextとdataの間に隙間が空いてしまうのが欠点といえば欠点です。
二つ目の方法論はOSやCPUがこなれるまではよく使われていました。BREWなんかは未だに引きずってますね。なれればどうということもないのですが、「必ず第1引数にthisインスタンスをポインタ渡しすること」というルールを全関数に敷衍しなくちゃいけないので、移植性のひどく悪いソースになります。thisContext擬似変数が欲しいところです。
最後の方法論は、初めて聞いたときは「頭いい!」と感心しました。また、SymbianはModelとViewを別々に登録することができたので、一つのModelに複数のViewがぶら下がったり、UIとロジックの分離を無意識のうちに行うことができました。
再入可能なプログラム自体はメモリ効率もよく、組み込み向けにはよく使いましたが、Cの標準関数がPOSIXほどは使えないという欠点はありました。printfやstrtokなんかが引っかかるんですよね。ま、それぐらい何とかなりますが。
ただ、今時メモリマップとにらめっこしながら作るのは、なんか負けのような気がします。21世紀に入ってもう10年もたつのになぁ。