日本-日本語

製品  >  ソフトウェア  >  OpenVMS  >  マニュアル

OpenVMS マニュアル


≫ 

OpenVMS V8.3
ライブラリ

タイトルページ
目次
まえがき
第 1 章:移行プロセスの概要
第 2 章:移行方法の選択
第 3 章:アプリケーションの移行
第 4 章:再コンパイルと再リンクの概要
第 5 章:ページ・サイズの拡大に対するアプリケーションの対応
第 6 章:共有データの整合性の維持
第 7 章:アプリケーション・データ宣言の移植性の確認
第 8 章:アプリケーション内の条件処理コードの確認
第 9 章:アプリケーションのトランスレート
第 10 章: ネイティブなイメージとトランスレートされたイメージの間の相互操作性の確認
第 11 章:OpenVMS Alpha コンパイラ
付録 A :アプリケーション評価チェックリスト
用語集
索引
PDF
OpenVMS ホーム
OpenVMS Alpha オペレーティング・システム | HPE 日本

OpenVMS Alpha
オペレーティング・システム
OpenVMS VAX から OpenVMS Alpha へのアプリケーションの移行


目次 索引



アプリケーションが実行するメモリ割り当てを変更しなければならないかどうかを判断するには,メモリがどこで割り当てられるかを確認しなければなりません。メモリ割り当てを実行するシステム・サービス・ルーチン($EXPREGと$CRETVA)を使用すれば,次の2種類の方法でメモリを割り当てることができます。

  • アプリケーションの仮想アドレス空間のP0またはP1領域のサイズを拡張する方法

  • 指定した位置からはじまり,アプリケーションの既存の仮想アドレス空間の領域を再要求する方法

Alphaアーキテクチャでは,VAXアーキテクチャと同じ仮想アドレス空間レイアウトを定義しており,VAXシステムの場合と同じ方向にP0領域とP1領域を拡大できます。 図 5-1 はこのレイアウトを示しています。

図 5-1 仮想アドレスのレイアウト




アプリケーションで$EXPREGシステム・サービスを使用して仮想アドレス空間を拡張することによりメモリを割り当てる場合には,ソース・コードを変更する必要はありません。これは,VAXシステムで引数として指定した値がAlphaシステムでも正しく動作するからです。この理由は次のとおりです。

  • Alphaシステムでは,$EXPREGシステム・サービスは要求されたメモリのサイズ (pagcnt 引数でページ・カウントとして指定した値)は512バイト単位で解釈されます。これはVAXシステムの場合と同じです。したがって,アプリケーションで指定した値は同じサイズのメモリを要求します。
    ただし,システム・サービスはページ・カウントをCPU固有のページに切り上げるため,アプリケーションに対してシステムが実際に割り当てるメモリ・サイズは,VAXシステムの場合よりAlphaシステムの場合の方が大きくなる可能性があります。割り当てられたメモリ全体はアプリケーションで使用できます。アプリケーションは通常,必要なバッファを確保するためにメモリを割り当てます。しかし,バッファのサイズは各プラットフォームで変化しないため,指定した値はアプリケーションの必要条件を満足できます。

  • 割り当ては仮想アドレス空間の拡張された領域で実行されるため,要求したサイズとシステムが実際に割り当てたサイズの違いは,アプリケーションの機能に影響を与えません。

対処方法

アプリケーションを変更する必要はありません。しかし,$EXPREGシステム・サービスが戻すメモリ・サイズは,Alphaアーキテクチャを実現した各システムで異なる可能性があるため,システムが割り当てた正確なメモリ境界を確認しておくことが適切でしょう。正確なメモリ境界を確認するには,$EXPREGシステム・サービスに対して省略可能な引数である retadr 引数を指定します(アプリケーションでこの引数がまだ指定されていない場合)。retadr 引数には,システム・サービスが割り当てたメモリの先頭アドレスと末尾アドレスが格納されます。

たとえば, 例 5-1 のプログラムは,$EXPREGシステム・サービスを呼び出すことにより10ページの追加メモリを要求します。このプログラムを VAXシステムで実行した場合には,$EXPREGシステム・サービスは5120バイトの追加メモリを割り当てます。このプログラムをAlphaシステムで実行した場合には,$EXPREGシステム・サービスは少なくとも8192バイトを割り当てます。また,Alpha アーキテクチャの特定の動作のページ・サイズによっては,それ以上のサイズのメモリを割り当てることもあります。

例 5-1 仮想アドレス空間の拡張によるメモリの割り当て

#include  <ssdef.h> 
#include  <stdio.h> 
#include  <stsdef.h> 
#include  <descrip.h> 
#include  <dvidef.h> 
 
#define  PAGE_COUNT 10  (1)
#define  P0_SPACE   0 
#define  P1_SPACE   1 
 
main( argc, argv ) 
int argc; 
char *argv[]; 
{ 
     int    status = 0; 
     long   bytes_allocated, addr_returned[2]; 
 
(2)   status = SYS$EXPREG( PAGE_COUNT, &addr_returned, 0, P0_SPACE); 
 
     bytes_allocated = addr_returned[1] - addr_returned[0]; 
 
     if( status == SS$_NORMAL) 
        printf("bytes allocated = %d\n", bytes_allocated ); 
     else 
        return (status); 
         
} 

この後の各項目は, 例 5-1 に示した番号に対応します。

  1. この例では,要求するページ数を意味するシンボルとしてPAGE_COUNTを定義しています。

  2. この例では,仮想アドレス空間のP0領域の末尾に10ページを追加することを要求しています。



5.2.2 既存の仮想アドレス空間でのメモリの割り当て

アプリケーションで$CRETVAシステム・サービスを使用することにより,仮想アドレス空間内のメモリを再割り当てする場合には,$CRETVAに対する引数のうち,次の引数の値を変更する必要があるかもしれません。

  • VAXページ境界にアラインするために,inadr 引数に指定したアドレスを 512の倍数になるように明示的に調整している場合には,アドレスを変更しなければなりません。Alphaシステムでは,$CRETVAシステム・サービスが先頭アドレスをCPU固有のページ境界で切り捨てますが,この値は各システムで異なります。

  • inadr 引数にアドレス範囲として指定する再割り当てのサイズは, Alphaシステムの方がVAXシステムの場合より大きくなる可能性があります。これは,要求がCPU固有のページ・サイズに切り上げられるからです。この結果,隣接データが破壊される可能性があり,これは1ページを割り当てる場合でも発生します (inadr引数に指定した先頭アドレスと末尾アドレスが一致する場合には,1ページが割り当てられます)。

対処方法

アプリケーションを変更しなければならないかどうかを判断するには,次の操作を実行してください。

  • 可能性のあるすべてのページ・サイズに対して,仮想アドレス空間の中で呼び出しの影響を受ける領域が重要なデータを破壊しないことを確認してください。

  • 可能性のあるすべてのページ・サイズに対して,割り当てが開始される先頭アドレスが常にページ境界にアラインされることを確認してください。

  • 省略可能な retadr 引数がアプリケーションで指定されていない場合には,この引数を指定して,$CRETVAシステム・サービスに対する呼び出しで割り当てられた正確なメモリの境界を判断してください。

例 5-2 は,バッファに割り当てたメモリを $CRETVAシステム・サービスによって再割り当てする方法を示しています。

例 5-2 既存のアドレス空間でのメモリの割り当て

#include  <ssdef.h> 
#include  <stdio.h> 
#include  <stsdef.h> 
#include  <descrip.h> 
#include  <dvidef.h> 
 
char _align(page) buffer[1024]; 
 
main( argc, argv ) 
int argc; 
char *argv[]; 
{ 
 
     int      status = 0; 
     long     inadr[2]; 
     long     retadr[2]; 
 
     inadr[0] = &buffer[0]; 
     inadr[1] = &buffer[1023]; 
 
     printf("inadr[0]=%u,inadr[1]=%u\n",inadr[0],inadr[1]); 
 
     status = SYS$CRETVA(inadr, &retadr, 0); 
 
     if( status & STS$M_SUCCESS ) 
     { 
        printf("success\n"); 
        printf("retadr[0]=%u,retadr[1]=%u\n",retadr[0],retadr[1]); 
     } 
     else 
     { 
        printf("failure\n"); 
        exit(status); 
     } 
} 



5.2.3 仮想メモリの削除

$EXPREGシステム・サービスと$CRETVAシステム・サービスによって割り当てたメモリを解除するために$DELTVAシステム・サービスを呼び出す場合, $DELTVAシステム・サービスに対して inadr 引数として, retadr 引数に戻されたアドレス範囲(メモリを割り当てるために使用したルーチンから戻された値)をアプリケーションで使用しているときは,アプリケーションを変更する必要はありません。実際に割り当てられるサイズは各システムで異なるため,割り当ての範囲に関してアプリケーションで何らかの仮定を設定することは望ましくありません。

5.3 メモリ・マッピング・ルーチンの確認

アプリケーションで実行するメモリ・マッピングを変更しなければならないかどうかを判断するには,アプリケーションが仮想メモリのどの部分でマッピングを実行するかを確認しなければなりません。メモリ・マッピング・システム・サービス($CRMPSCと $MGBLSC)を使用すれば,次の方法でメモリをマッピングできます。

  • アプリケーションの仮想アドレス空間の拡張領域に,メモリをマッピングする方法

  • 指定した位置(この位置は既存の仮想アドレス空間に存在してもかまいません)からはじまるアプリケーションの仮想アドレス空間に,メモリの1ページをマッピングする方法

  • 仮想アドレス空間の中で指定した先頭アドレスと末尾アドレスによって定義される既存の領域に,メモリをマッピングする方法

アプリケーションがセクションをマッピングする方法は,おもに $CRMPSCシステム・サービスと$MGBLSCシステム・サービスに対する次の引数によって決定されます。

  • inadr 引数は,セクションのサイズと位置を先頭アドレスと末尾アドレスによって指定します。$CRMPSCシステム・サービスはこの引数を次の方法で解釈します。

    • inadr 引数に指定した2つのアドレスがどちらも同じであり, SEC$M_EXPREGビットが flags 引数でセットされている場合には,システム・サービスは指定したアドレスが含まれるプログラム領域でメモリを割り当てますが,指定された位置は使用しません。

    • inadr 引数に指定されているアドレスがどちらも同じであり, SEC$M_EXPREGフラグがセットされていない場合には,指定した位置を先頭アドレスとして1ページがマッピングされます($CRMPSCシステム・サービスのこの操作モードはAlphaシステムではサポートされません。アプリケーションでこのモードを使用している場合には,ソース・コードの変更方法に関して 第 5.3.2 項 を参照してください)。

    • 2つのアドレスが異なる場合には,システム・サービスは指定された境界を使用して,セクションをメモリにマッピングします。

  • pagcnt (ページ・カウント)引数は,セクション・ファイルからマッピングするブロック数を指定します。

  • relpag (相対ページ番号)引数は,セクション・ファイルの中でマッピングを開始する位置を指定します。

$CRMPSCシステム・サービスと$MGBLSCシステム・サービスは少なくともCPU固有のページを1ページ分マッピングします。セクション・ファイルが1ページ未満の場合には,ページの残りの部分には0が格納されます。ページの残された空間をアプリケーションで使用すべきではありません。なぜなら,セクション・ファイルに格納できるデータだけがディスクに書き戻されるからです。

5.3.1 拡張した仮想アドレス空間へのマッピング

アプリケーションでアプリケーションの仮想アドレス空間の拡張領域にセクション・ファイルをマッピングする場合には,ソース・コードを変更する必要はありません。これは,拡張された仮想アドレス空間にマッピングされるため,たとえAlphaシステムで割り当てられるメモリのサイズがVAXシステムより大きくても,既存のデータの上にマッピングされる危険性がないからです。このように, VAXシステムで$CRMPSC システム・サービスに対して引数として指定した値は, Alphaシステムでも正しく機能します。

対処方法

セクションを仮想メモリの拡張領域にマッピングするアプリケーションは,変更しなくても正しく動作できますが,retadr 引数をアプリケーションで指定していない場合には,この引数を指定することにより,呼び出しによってマッピングされたメモリの正確な境界を判断するようにしてください。

注意

アプリケーションで relpag 引数を指定する場合には, retadr 引数も指定しなければなりません。これは省略可能な引数ではありません。relpag 引数の使用についての詳しい説明は, 第 5.3.4 項 を参照してください。

例 5-3 は,セクション・ファイルを拡張アドレス空間にマッピングする $CRMPSCシステム・サービスの呼び出しを示しています。この例では,次に示すように DCLのCREATEコマンドを使用して作成されたMAPTEST.DATという名前のセクション・ファイルをマッピングします。


$  CREATE maptest.dat 
test data test data test data test data test data 
test data test data test data test data test data 
test data test data test data test data test data 
test data test data test data test data test data 
test data test data test data test data test data 
test data test data test data test data test data 
test data test data test data test data test data 
test data test data test data test data test data 
[Ctrl/Z]

例 5-3 拡張された仮想アドレス空間へのセクションのマッピング

#include  <ssdef.h> 
#include  <string.h> 
#include  <stdlib.h> 
#include  <stdio.h> 
#include  <stsdef.h> 
#include  <descrip.h> 
#include  <dvidef.h> 
#include  <rms.h> 
#include  <secdef.h> 
 
struct FAB fab; 
 
char _align(page) buffer[1024]; 
char *filename = "maptest.dat"; 
 
main( argc, argv ) 
int argc; 
char *argv[]; 
{ 
 
     int    status = 0; 
     long   flags = SEC$M_EXPREG; 
     long   inadr[2]; 
     long   retadr[2]; 
     int    fileChannel; 
 
/********  create disk file to be mapped *************/ 
 
     fab = cc$rms_fab; 
     fab.fab$l_fna = filename; 
     fab.fab$b_fns = strlen( filename ); 
     fab.fab$l_fop = FAB$M_CIF | FAB$M_UFO;  /* must be UFO */ 
 
     status = sys$create( &fab ); 
 
     if( status & STS$M_SUCCESS ) 
        printf("%s opened\n",filename); 
     else 
     { 
        exit( status ); 
     } 
 
     fileChannel = fab.fab$l_stv; 
 
/**********  create and map the section  ****************/ 
 
     inadr[0] = &buffer[0]; 
     inadr[1] = &buffer[0]; 
 
     status = SYS$CRMPSC( inadr, /* inadr=address target for map */ 
                        &retadr, /* retadr= what was actually mapped */ 
                              0, /* acmode  */ 
                          flags, /* flags, with SEC$M_EXPREG bit set */ 
                              0, /* gsdnam, only for global sections */ 
                              0, /* ident, only for global sections */ 
                              0, /* relpag, only for global sections */ 
                    fileChannel, /* returned by SYS$CREATE */ 
                              0, /* pagcnt = size of sect. file used */ 
                              0, /* vbn = first block of file used */ 
                              0, /* prot = default okay */ 
                              0); /* page fault cluster size */ 
 
     if( status & STS$M_SUCCESS ) 
     { 
          printf("section mapped\n"); 
          printf("retadr[0]=%u,retadr[1]=%u\n",retadr[0],retadr[1]); 
     } 
     else 
     { 
          printf("map failed\n"); 
          exit( status ); 
     } 
 
} 



5.3.2 特定の位置への単一ページのマッピング

アプリケーションでセクション・ファイルを1ページのメモリにマッピングする場合には,Alphaシステムの$CRMPSCおよび$MGBLSCシステム・サービスでこの操作モードがサポートされないため,ソース・コードを変更しなければなりません。Alphaシステムのページ・サイズはVAXシステムのページ・サイズと異なっており,さらに Alpha アーキテクチャの各実装ごとに異なるため,アプリケーションでセクション・ファイルをマッピングするために正確なメモリ境界を指定しなければなりません。このような使い方をした場合,$CRMPSCシステム・サービスは,引数が誤っていることを示すエラー(SS$_INVARG)を戻します。

アプリケーションでこのモードを使用しているかどうかを判断するには, inadr 引数に指定した先頭アドレスと末尾アドレスを確認します。両方のアドレスが同じであり,同時に,flags 引数の SEC$M_EXPREGビットがセットされていない場合には,アプリケーションはこのモードを使用しています。

対処方法

このモードの$CRMPSCシステム・サービスの呼び出しを変更する場合には,次のガイドラインに従ってください。

  • マッピングの宛先となる位置が重要でない場合には,flags 引数の SEC$M_EXPREGビットをセットし,システム・サービスがアプリケーションの仮想アドレス空間の拡張領域に,セクション・ファイルをマッピングするようにしてください。この操作モードについての詳しい説明は, 第 5.3.1 項 を参照してください。

  • マッピングの宛先となる位置が重要な場合には, inadr 引数の先頭アドレスと末尾アドレスの両方を定義し,定義した領域にセクションをマッピングしてください。このモードについての詳しい説明は, 第 5.3.3 項 を参照してください。



5.3.3 定義されたアドレス範囲へのマッピング

アプリケーションで仮想アドレス空間の定義された領域にセクションをマッピングする場合には,ソース・コードを変更しなければならない可能性があります。これは, Alphaシステムでは$CRMPSCおよび$MGBLSCシステム・サービスがVAXシステムと異なる方法で一部の引数を解釈するからです。相違点は次のとおりです。

  • inadr 引数に指定する先頭アドレスは,CPU固有のページ境界にアラインされなければならず,指定する末尾アドレスもCPU固有のページの末尾にアラインされなければなりません。VAXシステムでは,$CRMPSCおよび$MGBLSCシステム・サービスは,これらのアドレスを調整して,ページ境界にアラインされるようにします。Alphaシステムでは,このようなアドレスの調整は実行されません。これは,ページ・サイズがはるかに大きいため,CPU固有のページ境界にアドレスを調整すると,メモリのより大きな部分に影響があるからです。したがって,Alphaシステムでは,仮想メモリ空間のどこにマッピングするかを明示的に指定しなければなりません。指定したアドレスがCPU固有のページ境界にアラインされない場合には,$CRMPSCシステム・サービスは,引数が誤っていることを示すエラー(SS$_INVARG)を戻します。

  • retadr 引数に戻されるアドレスは,呼び出しで実際にマッピングされたメモリの使用可能な部分だけを反映し,マッピングされたメモリ全体を反映するわけではありません。使用可能なサイズとは,pagcnt 引数に指定した値 (ページレット単位の値)とセクション・ファイルのサイズのうち,どちらか小さい方の値です。実際にマッピングされるサイズは,セクション・ファイルをマッピングするためにCPU固有のページが何ページ必要であるかに応じて異なります。セクション・ファイルがCPU固有のページより小さい場合には,ページの残りの部分に0が挿入されます。このページの残りの空間をアプリケーションで使用すべきではありません。retadr 引数に指定する末尾アドレスは,アプリケーションで使用できる上限を指定します。この場合,relpag 引数を指定するときは retadr 引数も指定しなければなりません。Alphaシステムではこの引数は, VAXシステムでのように省略可能ではありません。詳しくは, 第 5.3.4 項 を参照してください。

対処方法

可能な場合には,拡張された仮想アドレス空間にデータがマッピングされるように,アプリケーションを変更してください。アプリケーションがデータをマッピングする方法を変更できない場合には,次のガイドラインに従ってください。

  • オペレーティング・システムは少なくとも1物理ページをマップします。 Alphaシステム上の物理ページのサイズはVAXシステムより大きいため,アプリケーションの中で定義したバッファにセクションをマップする場合,隣接するデータが重ね書きされて破壊されないよう注意してください。多くの VAXシステム上のアプリケーションでは,たとえマップされるセクション・ファイルのサイズが512バイト以下でも,セクションがマップされるバッファのサイズをVAX システムのページ・サイズである512バイト単位で定義しています。Alphaでこの方針に従うためには,アプリケーションでバッファのサイズを64Kバイト単位で定義してください。
    セクションがマップされるときに,隣接データが重ね書きされないことを確認するためのよりよい方法は,リンカにバッファを独立したイメージ・セクションとして指定することです(リンカはイメージをイメージ・セクションから作成します。それぞれのイメージ・セクションは,イメージの各部分のメモリの必要量を定義しています)。リンカはイメージ・セクションをページ境界に配置し,隣接するデータはつぎのページ境界から配置します。このためバッファを独自のイメージ・セクションに独立されることによって,隣接データがマッピング操作によって重ね書きされないことが保証されます。このように,隣接するデータを破壊したり,バッファのサイズを変更することなく1ページ分のメモリをセクションにマップすることが可能です。
    リンカがセクション・ファイルを独自のイメージ・セクションに置いたことを確認するために,リンカのPSECT_ATTRオプションを使用してSOLITARYプログラム・セクション属性を設定する必要があります(詳しくは『OpenVMS Linker Utility Manual』を参照してください)。また,使用している高級または中級のプログラミング言語を,コンパイラが定義したバッファを別のプログラム・セクションに置くことを確認するために,使用する必要があるかもしれません。詳しくは,コンパイラの解説書を参照してください。

  • $CRMPSCKと$MGBLSCシステム・サービスの値として指定する先頭または末尾アドレスが, CPU固有ページの先頭または末尾アドレスとともにアラインされることを確認してください。VAXシステムでは,システム・サービスはアドレスがページ境界にそろうように調整します。Alphaシステムでは,システム・サービスは,ユーザが指定したアドレスをページ境界にそろうように調整しません。
    セクションを独自のイメージ・セクションに分離する場合には,SOLITARYプログラム・セクション属性を使用して,先頭アドレスはページ境界にアラインされます。これは,実行時のホスト・マシンのページ・サイズにかかわらず,リンカが省略時の設定によりイメージ・セクションをページ境界にアラインするからです。
    セクションの末尾アドレスがCPU固有のページ境界にアラインされたことを確認するためには,アプリケーションを実行しているマシンがサポートしているページ・サイズを知る必要があります。$GETSYI システム・サービスや LIB$GETSYI ランタイム・ライブラリ・ルーチンを呼ぶことにより,実行時にCPU固有のページ・サイズを得ることができます。また,得た値を使ってアラインされた末尾アドレスの値を計算し, inadr引数内でシステム・サービスに渡すこともできます。
    システムがマップした使用可能なメモリ量を判断するためには, retadr 引数を指定してください。たとえアプリケーションがページの一部分しか使用しないとしても,オペレーティング・システムは最低でも1ページをマップします。retadr 引数で指定された末尾アドレスは使用できるメモリの上限を示します(Alphaシステムでアプリケーションが$CRMPSCシステム・サービスに relpag 引数を指定する場合,必ず retadr 引数を指定しなければなりません)。


目次 索引

印刷用画面へ
プライバシー 本サイト利用時の合意事項