日本-日本語
≫  お問い合わせ

製品とサービス >  ソフトウェアとOS >  OpenVMS >  マニュアル

OpenVMS マニュアル


≫ 

OpenVMS
ライブラリ

タイトルページ
目次
まえがき
第 1 章:はじめに
第 2 章:ページサイズの拡大に対するアプリケーションの対応
第 3 章:共有データの整合性の維持
第 4 章:アプリケーションデータ宣言の移植性の確認
第 5 章: アプリケーション内の条件処理コードの確認
第 6 章:ネイティブイメージとトランスレートイメージの相互操作性の確認
付録 A :OpenVMS AXPコンパイラ
索引
PDF
OpenVMS ホーム
OpenVMS AXP オペレーティング・システム | HPE 日本

OpenVMS AXP
オペレーティング・システム
OpenVMS AXP オペレーティング・システムへの移行:
再コンパイルと再リンク


目次 索引




2.2 メモリ割り当てルーチンの確認

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

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

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

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

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




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

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

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

対処方法

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

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

例 2-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); 
         
} 

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

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

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



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

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

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

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

対処方法

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

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

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

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

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

例 2-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); 
     } 
} 



2.2.3 仮想メモリの削除

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

対処方法

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

注意

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

例 2-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]

例 2-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); 
     } 
 
} 



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

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

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

対処方法

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

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

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


目次 索引

印刷用画面へ
プライバシー 本サイト利用時の合意事項 ウェブマスターに連絡