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


前へ 次へ 目次 索引


表 5-2 に示したランタイム・ライブラリ・ルーチンは,メモリ・ページを割り当てるか,または解放します。互換性を維持するために,これらのルーチンでは,ユーザが指定したページ・カウント情報をページレットの値として解釈します。

表 5-2 ランタイム・ライブラリ・ルーチンでページ・サイズに依存する可能性のある部分
ルーチン 引き数 Alphaシステムでの解釈
LIB$GET_VM_PAGE number-of-pages
割り当てる連続ページのページ数を指定する。
ページレット単位の値として解釈され,CPU固有のページに切り上げられるか,または切り捨てられる。
LIB$FREE_VM_PAGE number-of-pages
割り当てを解除する連続ページのページ数を指定する。
ページレット単位の値として解釈され,CPU固有のページになるように切り上げられるか,または切り捨てられる。

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

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

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

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


5.2.1 拡張された仮想アドレス空間でのメモリの割り当て

アプリケーションで$EXPREGシステム・サービスを使用して仮想アドレス空間を拡張することによりメモリを割り当てる場合には,ソース・コードを変更する必要はありません。これは,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に対する引数のうち,次の引数の値を変更する必要があるかもしれません。

対処方法

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

例 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)を使用すれば,次の方法でメモリをマッピングできます。

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

$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システム・サービスの呼び出しを変更する場合には,次のガイドラインに従ってください。


前へ 次へ 目次 索引