サブプール
サブプール:仮想記憶内の分類された区域のこと
OSは仮想記憶領域を、その利用目的などに応じて分類・管理しています。分類された領域(区域)をサブプールと呼び、各サブプールには識別のための0?255までの番号が付けられています。どのサブプールを使うかはGETMAINやSTORAGEマクロ、あるいはCPOOLマクロでサブプール番号を指定することで決まります。一般のユーザープログラムが利用できるのは0?127、131、132です。128以上、特に200番以上はSQA、CSA、LSQAと言ったシステムが制御用に使用する領域ともなっています。デフォルトのサブプールは0番となります。
各サブプールには次に示す属性が割り当てられています。プログラムが利用する領域がどのような属性を持っていればいいのかに合わせて、適切なサブプールを選択します。
仮想記憶内の位置
利用する領域が、低位アドレスPVT、高位アドレスPVT、LSQA、CSA、SQAのどこに属する領域かを示します。
低位・高位の区別は16MB境界の上下ではありません。16MB上下それぞれのプライベート領域の低いアドレスから割り当てるのか、高いアドレスから割り当てるのかです。例えば5000番地から割り当てるのか、F00000番地から割り当てるのかと言うことです。
記憶保護キー
領域が持つ記憶保護キーです。当然ながらプログラムが持つPSWのキーと一致するか、あるいは矛盾が無いようにしなければなりません。GETMAINされる領域のキーはサブプールによって、要求元プログラムのPSWキー、要求元プログラムのジョブステップ・キー、パラメーターで選択、常に0などに分かれます。
フェッチプロテクション
領域に読み出し保護が掛かるかどうかです。CPU命令ではキーが異なっても書き込みでなければアクセスが許されますが、読み出し保護が掛かっている領域では、キーが一致しないと読み出しすらできません。
ページ固定
領域がページング可能なのかページ固定されるかです。
領域の所有者
領域の所有者は、その領域の返却責任者でもあり、仮想記憶内の位置と関連します。タスク、ジョブステップ・タスク、アドレス空間、システムに分かれます。プログラムがFREEMAINマクロを使用するなど明示的に解放しない場合、オーナーが終了する時にシステムによって解放されます。タスクが所有者ならタスク終了時に未解放の領域は自動的に返却されます。CSAやSQAなどの共通域のオーナーはシステムです。GETMAINしたジョブがFREEMAINしないで終わっても自動的に解放されません。
仮想記憶を構成するサブプールの要約表はこちらのページにあります。»»» ここ
サブプールの詳細についてはマニュアルを参照してください。
「z/OS MVS Programming: Authorized Assembler Services Guide」
「システムプログラミング手引書 タスク管理編 -OS IV/MSP-」
「システムプログラマの手引 -マクロ編-」VOS3
追加の解説
サブプールを分ける効果
一般のプログラムはサブプールを特に意識しなくてもいいのですが、サブプールを分けることで仮想記憶域の使用効率を高めることができます。処理Aで4000バイトの領域を確保した後、処理Bで50バイトを確保したとします。それぞれの領域は同じサブプール0から確保されます。それぞれの領域があるページをページ1とします。その後、処理Aで別の領域を60バイト確保すると、新たなページであるページ2が切り出され、そのから60バイトが確保されます。その状態で処理Bが終わり、使用済みの50バイト領域が解放されても、ページ1とページ2の2つのページが使われたままです。(ページ1では4000バイト、ページ2では60バイトが処理Aで使われている)
異なるサブプールが同じページに混在することはないので、処理Aと処理Bでサブプールを1と2に分けると、この例では処理Bが終わるとページ2は解放されます。処理Aではサブプール1であるページ1に4000と60バイト、処理Bではサブプール2であるページ2に50バイトが使われることになります。処理Bが終わればページ2は返却されるため、残るページは1だけとなります。したがって空間が使っているページは1個減ります。リアルメモリーも1ページ分減りますから、ワーキングセットも小さくなります。
合計で使用する仮想記憶量を減らすことにはならなくても、サブプールを上手に使い分けることで、ページの利用効率を高めて、実記憶の使用量であるワーキングセットを小さくできることに繋がります。
ロードモジュールのサブプール
ロードモジュールはサブプール251または252にローディングされます。モジュールがAPF許可ライブラリーにあって、リエントラントプログラムとしてリンケージされている場合はサブプール252です。サブプール252はキー0の領域なので、APF許可された再入可能モジュールは書き込みから保護されます。
ロジック自体は再入可能になっていても、処理の必要からモジュール内に書き込み(例えば初回コールの時だけアンカーポイントを設定するなど)を行うようなプログラムは、改版などによってAPFが必要な機能を追加した途端にS0C4でABENDするようなことが起き得ます。ISVにいた時、同様の経験がありました。
※TSOでは、コマンドプログラムとCALLコマンドで呼び出されるプログラムは、APFでなくてもRENT属性であれば、サブプール252にローディングされます。
キー0のプログラムによるサブプール0へのGETMAIN
キー0でスーパーバイザーモードのプログラムがサブプール0にGETMAINすると、実際の領域はサブプール252から獲得されます。領域の記憶保護キーは0です。そのため、ユーザーSVCルーチンなどを使用する際、SVCの呼び出し側とSVCルーチンで共用する領域を、SVCルーチン側で確保する場合は注意が必要です。
SVCルーチンに限らず、キー0スーパーで動くプログラムが、ジョブステップのキー(8)で領域を確保する場合は、サブプール250を指定します。この場合OSはサブプールを0に変換して領域を確保します。解放時も同じです。
サブプールの共用
サブプール0はタスク間で共用されます。0以外のサブプールは共用されません。しかしここで言う共用とは、誰がその領域を返却できるのか?と言うことです。同じ空間なので各タスクは他のタスクが確保した領域であってもアドレスさえ指定すれば自由に読み書きできますが、返却に関しては領域を確保したタスクに限られます。共用可能なサブプールのみが、他のタスクが確保した領域を返却できることになるのです。例えばメインタスクで確保した領域をサブタスクで解放するような場合は、共用サブプールを使わねばなりません。そのためにはサブタスクをATTACHする際に、共用するサブプール番号をパラメーターで指定することで行います。また逆に暗黙の共用サブプールである0を共用しないように指定することもできます。OSのユーティリティをプログラムから繰り返し呼び出すような場合、LINKマクロを使うより、サブプール0を共用しない指定にして、サブタスクとしてATTACHすることで、ユーティリティ側でGETMAINした領域が未返却のまま処理が終わっても、OSがサブタスク終了時に使用済みのサブプール0を解放してくれます。