日本-日本語
日本HPホーム 製品 & サービス OpenVMS製品情報
≫  お問い合わせ


OpenVMS マニュアル


 

OpenVMS ドキュメント
ライブラリ

タイトルページ
目次
まえがき
第1章:はじめに
第2章:基本的な相違点
第3章:アプリケーションの調査
第4章:ソース・モジュールの移行
第5章:OpenVMS I64 開発環境
第6章:ポーティングの準備
第7章:その他の検討事項
付録A :アプリケーション評価チェックリスト
付録B :サポート対象外のレイヤード・プロダクト
付録C :アプリケーション固有のスタック切り換えコードの I64 へのポーティング
用語集
索引
PDF
OpenVMS ホーム

HP OpenVMS
OpenVMS Alpha から OpenVMS I64 へのアプリケーション・ポーティング・ガイド


目次 索引



モードに依存しない割り当ての構文は次のとおりです。

EXE$KP_USER_ALLOC_KPB kpb, flags, param_size, *kpb_alloc, mem_stack_bytes, 
*memstk_alloc, rse_stack_bytes, *rsestk_alloc, *end_rtn 

C プロトタイプ

status = EXE$KP_USER_ALLOC_KPB(  KPB_PPS kpb, int flags, 
     int param_size, 
     int (*kpb_alloc)(), 
     int mem_stack_bytes, 
     int(*memstk_alloc)(), 
     int rse_stack_bytes, 
     int(*rsestk_alloc)(), 
     void(*end_rtn)()) 

パラメータ

  • KPB--- 割り当てられたデータ構造のアドレスが返されるロングワードのアドレス。 OpenVMS API の規則では,32 ビット・ポインタは 32 ビット・アドレス (struct KPB を参照するショート・ポインタを参照するショート・ポインタ) 渡しされます。

  • FLAGS--- フラグのロングワード・ビットマスク。値渡しされます。 表 C-3 はこのパラメータに対して定義されているフラグを示しています。

    表 C-3 モードに依存しない割り当てのフラグ
    フラグ 説明
    KP$M_VEST OpenVMS システム KPB。一般に,このフラグは設定する必要があります。
    KP$M_SPLOCK KPB の内部にスピンロック領域を割り当てます。
    KP$M_DEBUG KPB の内部にデバッグ領域を割り当てます。
    KP$M_DEALLOC_AT_END カーネル・プロセス・ルーチンの終了時に,KPB の割り当てを自動的に解除しなければならないことを指定します。
    KP$M_SAVE_FP (I64 のみ,Alpha では無視されます) 汎用レジスタだけなく,浮動小数点コンテキストも保存します。 I64 システムでの整数乗算や除算などの特定の演算は,浮動小数点演算を使用してインプリメントできます。これらの演算では,最小浮動小数点レジスタ・セットを使用しますが,定義では,これらは保存されるレジスタ・セットに含まれていません。アプリケーションで最小浮動小数点レジスタ・セットだけを使用する場合は,このビットを設定する必要はありません。アプリケーションで浮動小数点データを使用する場合は,このビットを設定して,スタック切り換えの前後で正しい浮動小数点コンテキストを保存する必要があります。
    KP$M_SET_STACK_LIMITS スタック切り換えのたびに $SETSTK_64 を呼び出します。条件処理では正確なスタック・リミット値が必要なため,プロセス・スコープ・アプリケーションは常にこのフラグを設定する必要があります。

  • PARAM_SIZE -- 値渡しされるロングワード。 KPB 内のユーザ・パラメータ領域のサイズをバイト数で示します。パラメータ領域が必要ない場合は,0 を渡します。

  • KPB_ALLOC -- KPB を割り当てるルーチンのプロシージャ記述子のアドレス。割り当てルーチンは,2 つのパラメータを指定して呼び出されます。 1 つは長さパラメータ,もう 1 つは割り当てられた KPB のアドレスが返されるロングワードです。長さパラメータはバイト数で指定し,参照渡しされます。割り当てルーチンは,KP ルーチンが実行されるモードにとって適切な 32 ビット空間から,少なくとも要求されたバイト数を割り当てなければなりません。アドレスは少なくともクォドワード境界でアラインメントされる必要があり,実際の割り当てサイズを長さ引数に書き戻す必要があります。

  • MEM_STACK_BYTES -- 割り当てられるメモリ・スタックのサイズをバイト数で示す 32 ビット値。値渡しされます。返される値は,ハードウェア・ページ・サイズの倍数に切り上げられます。

  • MEMSTK_ALLOC -- メモリ・スタックを割り当てるルーチンのプロシージャ記述子のアドレス。 付録 C.1.7 項 はこのルーチンの形式と必要な動作を示しています。

  • RSE_STACK_BYTES -- 割り当てられるメモリ・スタックのサイズをバイト数で示す 32 ビット値。値渡しされます。返される値は,ハードウェア・ページ・サイズの倍数に切り上げられます。

  • RSESTK_ALLOC -- メモリ・スタックを割り当てるルーチンのプロシージャ記述子のアドレス。 付録 C.1.7 項 はこのルーチンの形式と必要な動作を示しています。

  • END_RTN -- 終了ルーチンのプロシージャ記述子のアドレス。終了ルーチンは,EXE$KP_END を呼び出すか,または呼び出しルーチンに戻ることで,KP ルーチンが終了するときに呼び出されます。終了ルーチンは,スタックと KPB をキャッシングしたり,割り当てを解除したりするのに必要です。



C.1.7 スタック割り当て API

スタック割り当てルーチンの API は,メモリ・スタック割り当ての場合も RSE スタック割り当ての場合も同じです。ルーチンを呼び出すときは,割り当てられている KPB の 64 ビット・アドレスと,割り当てられるハードウェア固有のページ数 (ページレット数ではない) を整数で指定します。

スタック割り当てルーチンを指定する構文は次のとおりです。

status = alloc-routine (KPB_PQ kpb, const int stack_pages) 

  • KPB--- すでに割り当てられている KPB の 64 ビット・アドレス。 64 ビット参照渡しされます。

  • STACK_PAGES--- 割り当てるページ数 (整数)。 32 ビットの値渡しされます。

割り当てルーチンは,ページ境界でアラインメントされたアドレス空間を割り当てるものと考えられます。厳密に必須というわけではありませんが,両端にアクセスされないガード・ページを配置することで,スタックを保護することを強くお勧めします。また,最小スタック・サイズは,少なくとも SYSGEN パラメータ KSTACKPAGES (グローバル・セル SGN$GL_KSTACKPAG) の値になるようにしてください。このように設定すると,アプリケーションを再コンパイルしなくても,スタック・サイズに関して特定の制御を行うことができます。また,I64 でのスタックの使い方は,従来のアーキテクチャとは大きく異なっているため,前に割り当てられていたスタック・サイズが適切でない可能性もあります。

メモリ・スタック割り当てルーチンでは,次の KPB フィールドを次のように設定する必要があります。

  • KPB$IS_STACK_SIZE--- ガード・ページを除く,スタックのサイズ (バイト数)。

  • KPB$PQ_STACK_BASE--- スタックのベース・アドレス。メモリ・スタックの場合は,割り当てられたスタックの末尾の次のバイトのアドレスです。つまり,割り当てられたアドレスに,割り当てサイズ (バイト数) を加算した値です。

メモリ・スタック割り当てルーチンでは,次の KPB フィールドを次のように設定できます。

  • KPB$Q_MEM_REGION_ID--- $CREATE_REGION システム・サービスから返された領域 ID。この情報は,スタックの割り当てを解除するときに必要です。

RSE スタック割り当てルーチンでは,次の KPB フィールドを次のように設定する必要があります。

  • KPB$IS_STACK_SIZE--- ガード・ページを除く,スタックのサイズ (バイト数)。

  • KPB$PQ_STACK_BASE-- スタックのベース・アドレス。 RSE スタックの場合は,割り当てられた最下位アドレスです。

RSE スタック割り当てルーチンでは,次の KPB フィールドを次のように設定できます。

  • KPB$Q_REGION_ID--- $CREATE_REGION システム・サービスから返された領域 ID。この情報は,スタックの割り当てを解除するときに必要です。

どちらのルーチンも状態を呼び出しルーチンに返す必要があります。

C.1.8 システムで提供される割り当てルーチンと割り当て解除ルーチン

本システムでは,多くの標準割り当てルーチンが提供されます。これらのルーチンは,KP 割り当て API に準拠しており,アプリケーションの要件を満たす場合は,ユーザ作成ルーチンの代わりに使用できます。次の割り当てルーチンが提供されています。

  • EXE$KP_ALLOC_MEM_STACK (カーネル・モード,S0/S1 空間)

  • EXE$KP_ALLOC_MEM_STACK_USER (ユーザ・モード,P0 空間)

  • EXE$KP_ALLOC_RSE_STACK (呼び出しルーチンのモード,S2 空間)

  • EXE$KP_ALLOC_RSE_STACK_P2 (呼び出しルーチンのモード,P2 空間)

次の割り当て解除ルーチンが提供されています。すべての割り当て解除ルーチンに, 1 つの引数 (KPB のアドレス) が必要です。

  • EXE$KP_DEALLOCATE_KPB

    • EXE$KP_ALLOCATE_KPB が割り当てた KPB のみ。

    • スタックと KPB の割り当てを解除します。

  • EXE$KP_DEALLOC_MEM_STACK

  • EXE$KP_DEALLOC_MEM_STACK_USER

  • EXE$KP_DEALLOC_RSE_STACK

  • EXE$KP_DEALLOC_RSE_STACK_P2



C.1.9 終了ルーチン

終了ルーチンは,EXE$KP_END が明示的に呼び出されるか,または KP ルーチンの最後に到達したときに, KP サービスから呼び出されます。 EXE$KP_USER_ALLOC_KPB には任意の割り当てルーチンを指定できるので,終了ルーチンは,アプリケーションで将来使用するために KPB をキャッシュに保存しておくか,またはスタックおよび KPB に対して必要な割り当て解除ルーチンを呼び出す必要があります。

終了ルーチンを呼び出すには,次に示すように, 2 つのパラメータを指定します。

void end_routine (KPB_PQ KPB, int status) 

  • KPB--- すでに割り当てられている KPB の 64 ビット・アドレス。 64 ビット参照渡しされます。

  • STATUS--- 省略可能な状態値。 EXE$KP_END が明示的に呼び出された場合は,状態値は,EXE$KP_END の 2 番目の引数に指定された値になります。 2 番目の引数が省略されている場合は, SS$_NORMAL になります。呼び出しルーチンに戻ることで KP ルーチンが終了する場合は,状態値は KP ルーチンの戻り値になります。



C.2 KP 制御ルーチン

KPB とスタックが割り当てられた後,KP ルーチンの状態を判断する 4 つのルーチンを使用できます。

C.2.1 概要

KP ルーチンは,EXE$KP_START を呼び出すことで開始されます。 KP ルーチンは,実行中に EXE$KP_STALL_GENERAL を呼び出すことで,制御を放棄することができます。ストールされた KP ルーチンは,EXE$KP_RESTART を呼び出すことで再開できます。 KP ルーチンは,EXE$KP_END を明示的に呼び出すか,またはルーチンから戻ることで終了します。ルーチンから戻る場合は,KP サービスは EXE$KP_END を暗黙に呼び出します。

KP ルーチンが起動されると,現在の実行状態スレッドは現在のスタックに保存され,KP スタックがロードされ, KP ルーチンが呼び出されます。

KP ルーチンがストールされると,KP ルーチンのコンテキストは KP スタックに保存され,スタックは元のスタックに切り換えられ,メイン・ルーチンのコンテキストがスタックからロードされます。その結果,ストールによって,EXE$KP_START または EXE$KP_RESTART の最後の呼び出しから元のルーチンに戻ります。

KP ルーチンが再起動されると,現在のコンテキストは現在のスタックに保存され,スタックは KP ルーチンのスタックに切り換えられ,KP ルーチンのコンテキストがスタックから復元されます。 EXE$KP_STALL_GENERAL の最後の呼び出しから KP ルーチンに戻ります。

ストールと再開のシーケンスは 0 回以上実行できます。 KP ルーチンをあらかじめストールしなければならないわけではありません。ストールされたルーチンは,再開されるまでストールできません。実行中の KP ルーチンは,ストールされるまで再起動できません。完全にチェックする SYSTEM_PRIMITIVES.EXE で,これらのルールが適用されています。これらのルールに従わないと, KP ルーチンが実行されているモードに応じて, KP_INCONSTATE バグチェックが発生することがあります。

EXE$KP_END を明示的に呼び出すか,呼び出しルーチンに戻ることによって,KP ルーチンが終了する場合,現在のコンテキストは保存されず,スタックは切り換えられ,元のスレッド・コンテキストが復元されます。この時点で,DEALLOCATE_AT_END フラグが設定されているか (カーネル・モードのみ),終了ルーチンのアドレスが指定されている場合は,適切な処理が実行されます。 KP ルーチンを起動または再起動した呼び出しから,元のスレッドに戻ります。

図 C-1 は全体的なコード・フローを示しています。

図 C-1 KP ルーチンの実行


  注意
この図で,メイン実行スレッドは連続ストリームとして示されていますが,実際の実行スレッドには非同期コンポーネントが含まれることがあります。アプリケーションは必要な KPB のスコープを維持するだけでなく,必要なすべての同期化も実行しなければなりません。



ここでは,各ルーチンについて説明します。

構文:

status = EXE$KP_START(kpb, routine, reg-mask) 

  • kpb--- 前に割り当てられ,初期化されている KPB のアドレス。 32 ビット参照渡しされます。

  • routine--- KP ルーチンのアドレス。

  • reg-mask--- レジスタ保存マスク。ロングワードです。値渡しされます。この引数は Alpha でのみ読み取られます。 I64 インタフェースでは,レジスタの保存に関して OpenVMS 呼び出し規則だけがサポートされます。 Alpha での高級言語からの呼び出しに対しては, KPBDEF に定義されている定数 KPREG$K_HLL_REG_MASK を使用して,呼び出し規則のレジスタ・マスクを指定できます。

このルーチンは,現在の実行スレッドを中断し,新しいスタックにスワップし,指定されたルーチンを呼び出します。 KP ルーチンの呼び出しには,割り当てられている KPB の 32 ビット・アドレスを引数として指定します。 KPB は無効かつ非アクティブでなければなりません。

構文:

status = EXE$KP_STALL_GENERAL(kpb) 

  • kpb--- このルーチンの起動時に渡される KPB のアドレス。 32 ビット参照渡しされます。

このルーチンは,現在の実行スレッドをストールし,コンテキストを KP スタックに保存し,このルーチンを最後に起動または再起動した呼び出しに戻ります。 KPB は有効かつアクティブでなければなりません。

このルーチンからの戻り値 status は,このプロシージャを再起動したルーチンから渡されます。

構文:

EXE$KP_RESTART(kpb [, thread_status]) 

  • kpb--- このルーチンをストールするために最後に使用された KPB のアドレス。 32 ビット参照渡しされます。

  • thread_status -- KP ルーチンを最後にストールした EXE$KP_STALL_GENERAL の呼び出しの戻り値として渡される状態値。値渡しされます。省略可能です。このパラメータを省略した場合は,SS$_NORMAL が返されます。

このルーチンを呼び出すと,EXE$KP_STALL_GENERL の最後の呼び出しから戻ることで,ストールされていたルーチンが再起動されます。この処理は,KP ルーチンを起動した元の実行スレッドとは完全に非同期に行われる操作です。 KPB は有効かつ非アクティブでなければなりません。

構文:

status = EXE$KP_END(kpb [, status]) 

  • kpb--- このルーチンを起動または再起動するために最後に使用された KPB のアドレス。 32 ビット参照渡しされます。

  • status--- KPB に指定されていた場合は,終了ルーチンに渡される状態値。値渡しされます。省略可能です。このパラメータを省略した場合は,SS$_NORMAL が返されます。

このルーチンは,KP ルーチンを終了し,KP ルーチンを起動または再起動した最後の実行スレッドに制御を返します。 KPB は有効かつアクティブでなければなりません。 KPB は無効かつ非アクティブとしてマークされるため,最初に EXE$KP_START を呼び出して別の KP ルーチンを起動しない限り,この後の EXE$KP_RESTART や EXE$KP_STALL_GENERAL の呼び出しで KPB を使用することはできません。

EXE$KP_END を呼び出す代わりに,KP ルーチンは呼び出しルーチンに戻ることもできます。呼び出しルーチンに戻る場合,KP コードは KP_END を自動的に呼び出します。その場合,KP プロシージャからの戻り値 status は,状態引数として使用されます。

C.3 設計上の考慮点

  • KP ルーチンは単一プロセス内で動作します。複数の CPU を搭載したシステムで並列処理しても, KP サービス自体にメリットはありません。

  • EXE$KP_STALL_GENERAL,EXE$KP_RESTART, EXE$KP_END の呼び出しはすべて,EXE$KP_START の呼び出しと同じモードで実行する必要があります。呼び出しの前後でモードを変更してもかまいませんが,呼び出しはすべて,同じモードで行わなければなりません。

  • 複数の KPB が同時に有効になることがあります。

  • 複数の KPB が同時にアクティブになることがあります。これは,KP ルーチンが別の KPB を起動または再起動したことを示します。最も単純な場合を除き,アクティブ KPB の数が増加するにつれて,コード・フローは非常に複雑になります。このような場合,ワーク・キュー・モデルとディスパッチャを使用すると,複数のアクティブ KPB が必要になるという状況を回避できる可能性が高くなります。

  • スタックの割り当てと割り当て解除には,システム時間およびリソースが大量に必要となるため,アプリケーションの内部である程度,KPB のキャッシングを検討する必要があります。

  • カーネル・モードのプロセス・コンテキストで KP サービスを使用するアプリケーションは,スタックをワーキング・セットにロックする必要があります。


目次 索引

© 2012 Hewlett-Packard Development Company, L.P.