プログラムが仮想記憶内のどの領域をGETMAINしているかをマッピングすることができます。一般のプログラムでは殆ど必要とされませんが、サーバー・プログラムなどで自分が使用しているリソース量の詳細を得る機能などを実装する場合などに利用できます。
VSMLISTマクロでストレージ・マップを作る
リージョン(PVT域)内のGETMAIN済み領域をリストする
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- GETVSMAP DS 0H VSMLIST SP=PVT,SPACE=FREE, BUILD ALLOC AND FREE SPACE MAP + WKAREA=(VSMLIST,4096) CH RF,=H'4' SUCCESSFUL ? BH VSMERROR NO, : : 返されたマップ情報から割当て済み領域のアドレスと長さを得る。 : CLI VSMLIST+3,4 PARTIAL DONE ? BE GETVSMAP YES, READ AGAIN : : : DS 0D VSMLIST DC 4096X'00' VSMLIST MAP AREA |
SP=PVT指定のVSMLISTで、プログラムがリージョン内にどれだけのGETMAINを出しているかを知ることができます。返される領域情報は、GETMAINして割当て中の仮想ページのアドレスと大きさ(4KB単位)です。SPACE=FREEパラメーターを追加することで、割当て中ページ内の空きスペース長も得ることができます。割当て中ページの大きさから空きスペース長を引けば、そのページ内でのGETMAIN済み領域長となります。なお連続するページ内で複数回に渡ってGETMAINしても、割当て済み領域が連続すれば1つの割当て済み領域として返されますから、どの長さで何回GETMAINしたかはトレースできません。例えば、1504バイトの長さで2回連続したGETMAINをしても、VSMLISTでは3008バイトの領域が割当て中と返されます。
共通域(CSA)内の割当て済みページをリストする
1 2 3 4 5 6 |
----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- GETVSMAP DS 0H VSMLIST SP=CSA,SPACE=ALLOC, BUILD CSA ALLOCATED MAP + WKAREA=(VSMLIST,4096) : : |
CSAの割当て済み領域のリストを作成するには、SPパラメーターにCSAを指定します。他にもLSQA、SQAが指定できます。PVTの場合は、領域を割り振ったタスクを判別するTCBアドレスがリスト内に設定されますが、CSAの場合は0がセットされて具体的にどのタスクあるいはジョブでCSAを割り振ったかはわかりません。ただし、割り振られている領域の記憶保護キーが返されるので、キーの値によってどのコンポーネントで使っている領域かは大まかな見当を付けることはできます。例えば、キーが6であればVTAMやTCPIP関連の領域、キーが5であればDFSMS関連の領域、キーが1であればJES関連の領域という具合です。キーが8であれば主にアプリケーション(ベンダー・ソフトウェア含む)が割り振った領域となりますが、z/OSのV1R9からはユーザー・キーでのCSA割り振りを認めないのがシステム・デフォルトになってしまったため、PARMLIBのDIAGxxパラメーターでユーザーキーCSAを認めていない限り、アプリケーションであっても7以下(おそらくは0)のキーの領域しか割り振れません。
VSMLISTによって返されるストレージ・マップリスト
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
ヘッダー域(VSMLISTのWKAREAパラメーターで指定した領域の先頭) +----------------------+ +00 I 復帰コード I +----------------------+ +04 I データ域のアドレス I +----------------------+ +08 I データ域の長さ I +----------------------+ I I 〓〓 〓〓 I I +----------------------+ データ域(SP=PVT,SPACE=FREE指定の形式) +----------------------------+ +00 I TCBの数 I +----------------------------+ +04 I TCBアドレス I --> VSMLIST発行タスク +----------------------------+ +08 I サブプール数 = 3 I <-- SP=CSAの場合はここから始まる +----------------------------+ +12 I サブプール記述子 I +----------------------------+ +16 I オーナータスクTCB I --> GETMAINしたタスクのTCB +----------------------------+ +20 I 割当て済みブロック数 = 2 I +----------------------------+ +24 I 割当て済み領域のアドレス I +----------------------------+ +28 I 割当て済み領域の長さ I --> バイト単位だが4KBの倍数 +----------------------------+ +32 I ページ内空き領域の数 = 2 I +----------------------------+ +36 I 空き領域のアドレス I +----------------------------+ +40 I 空き領域の長さ I +----------------------------+ +44 I 空き領域のアドレス I +----------------------------+ +48 I 空き領域の長さ I +----------------------------+ +52 I 割当て済み領域のアドレス I +----------------------------+ +56 I 割当て済み領域の長さ I +----------------------------+ +60 I ページ内空き領域の数 = 0 I +----------------------------+ +64 I サブプール記述子 I +----------------------------+ +68 I オーナータスクTCB I --> GETMAINしたタスクのTCB +----------------------------+ +72 I 割当て済みブロック数 = 1 I +----------------------------+ +80 I 割当て済み領域のアドレス I +----------------------------+ +84 I 割当て済み領域の長さ I +----------------------------+ +88 I ページ内空き領域の数 = 0 I +----------------------------+ : : : サブプール記述子(4バイト) +----+----+----+------------+ SPはサブプール番号 +00 I 00 I 08 I SP I KEY + XX00 I KEYは記憶保護キー(4ビット) +----+----+----+------------+ XXはフラグビット 4bit+4bit |
VSMLISTで戻される割当て済み領域及び空き領域リストは、上記のような構造の可変長エントリーのテーブルです。1つ1つのエントリーをたどってGETMAIN済み領域のアドレスと長さを求めることができます。MVSではGETMAINによって領域を割り振る時、必要なページを切り出した後、ページの後方から領域を割り振ります。例えば、切り出したページ・アドレスがx10000番地の時、GETMAINで1000バイト(x3E8)の長さを要求すると、x10C18番地からx10FFF番地までの1000バイトが割り振られます。そのページのx10000番地からx10C17番地までは、空き領域になり次のGETMAIN等で使用されます。GETMAINで5000バイト要求した場合は、2ページが切り出されて後方ページの後方アドレスから割り振られます。
VSMLISTは、例えシステム系プログラムであっても滅多に必要とするAPIではありませんが、仮想記憶の中がどのように使われているかを調べたいような場合に利用できます。存在ぐらいを覚えておけばいいでしょう。マクロの使い方と返答領域の構造などの詳細は、マニュアル「MVS許可アセンブラーサービスの手引き(Authorized Assembler Services Guide)」「MVS許可アセンブラーサービス解説書(Authorized Assembler Services Reference)」に記載されています。マニュアルは許可アセンブラーサービスとなっていますが、非APFプログラムでも使用できます。
その他の仮想記憶管理関連マクロ
VSMLOCマクロでストレージの妥当性をテストする
1 2 3 4 5 6 7 8 9 |
----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- L R2,AWORK LOAD STORAGE ADDRESS L R3,LWORK LOAD STORAGE LENGTH VSMLOC PVT, VALIDATE STORAGE ADDRESS + AREA=((2),(3)) LTR RF,RF VALID STORAGE ? BNZ STOERROR NO, INVALID STORAGE ADDR/LNG : : |
VSMLOCマクロを使えば、メモリーアドレスの正当性をチェックすることができます。例えば、サブルーチンでパラメーター領域として正しいアドレスが渡されたかどうかをチェックしたいといった場合に利用できます。従来このようなチェックをするには、プログラムを監視プログラム・モードにしてLRA命令やTPROT命令を使うのが一般的でした。監視プログラム・モードのプログラムなら機械命令でチェックした方がパフォーマンス面でも有利ですが、非APFプログラムなど監視プログラム・モードで走行することができないプログラムでも仮想記憶アドレスの正当性が確認できます。これによって、誤ったアドレスをハンドリングしたことによるS0C4ABENDを抑止するようなガードを掛けることもできます。
1 2 3 4 5 6 7 8 9 |
スーパーバーザー・モードのプログラムなら機械命令でチェックできる TPROT 0(R2),0 VALIDATE STORAGE ADDRESS BC 3,STOERROR IF INVALID ADDRESS, INFORM IT LA R1,0(R3,R2) LOAD ENDING ADDRESS BCTR R1,0 CORRECT IT TPROT 0(R1),0 VALIDATE STORAGE ADDRESS BC 3,STOERROR IF INVALID ADDRESS, INFORM IT : : |
VSMREGNマクロでリージョンの開始アドレスと大きさを求める
1 2 3 4 5 |
----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- VSMREGN WKAREA=RGNLIST EXTRACT OUR MAXIMUM REGION SIZE : : RGNLIST DC 4F'0' |
VSMREGNマクロを使えば、利用可能な私用域の最大サイズを求めることができます。簡単ですが、返ってくるのはそのシステムでの構成上の最大値で、JCLのREGIONパラメーター値は考慮されていません。利用可能な残りのストレージ量を実用的に求めるならLDAというOSの制御表を参照する方が確実です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- SAM31 CHANGE US TO AMODE=31 L R2,PSAAOLD-PSA(0,0) LOAD OUR ASCB ADDRESS L R2,ASCBLDA-ASCB(,R2) LOAD LDA(ALLOCATED PVT REGION) L R3,LDAREGRQ-LDA(,R2) REGION SIZE REQUESTED L R4,LDALIMIT-LDA(,R2) BELOW 16M V=V REGION LIMIT VALU L R5,LDAVVRG-LDA(,R2) BELOW 16M V=V REGION HIGH VALUE L R6,LDAELIM-LDA(,R2) ABOVE 16M V=V REGION LIMIT VALU L R7,LDAEVVRG-LDA(,R2) ABOVE 16M V=V REGION HIGH VALUE : : IHAPSA , PSA IHAASCB , ASCB IHALDA , LDA |