日本-日本語
日本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 へのアプリケーション・ポーティング・ガイド


目次 索引

付録 C
アプリケーション固有のスタック切り換えコードの I64 へのポーティング

1 つのプロセスのコンテキストの内部で複数のタスクを実行するために,スタックを切り換える小さなプライベート・スレッド・パッケージが,多くのアプリケーションでサポートされています。これらのパッケージの多くは,アセンブリ言語 (VAX では Macro-32, Alpha では Macro-64) で作成された 1 つ以上の小さなルーチンを使用して,スタック・ポインタを操作することで,単一プロセスの内部でコンテキストの切り換えを行います。通常,タスクのストールと再起動を行う機能も必要です。置き換えられるスタックは,要求されたタスクにとって適切なモードであれば,どのモードでもかまいません。

I64 では,スタックの切り換えははるかに困難です。 I64 アーキテクチャには 2 つのスタックがあります。メモリ・スタックとレジスタ・スタック・エンジン・バッキング・ストア (一般には RSE スタックや単に レジスタ・スタックとも呼びます) です。 RSE スタックはハードウェアで管理され,アーキテクチャはスタックの非同期操作をサポートする機能を提供します。また,I64 アーキテクチャには,コンテキストの切り換えの前後で維持しなければならない,多くの専用ハードウェア・レジスタ (制御レジスタおよびアプリケーション・レジスタ) もあります。さらに,IAS アセンブラは OpenVMS ディストリビューションには含まれていません。

これらのタイプのアプリケーションに対応するために, OpenVMS では KP サービスというシステム・ルーチン・セットが提供されています。 KP サービスはもともと高級言語で作成されたデバイス・ドライバをサポートするように作成されていますが,どのモードでも,どの IPL でも動作するように拡張されています。 KP モデルがすべてのプライベート・スタック切り換えコードの要件を満たすわけではありませんが,このモデルに移行することを強くお勧めします。

KP サービスは Alpha と I64 の両方で提供されているため,共通のコードを使用できます。インプリメントの面ではいくつかの相違点がありますが,一方のアーキテクチャでのみ有効なオプションは,可能な限り,もう一方のアーキテクチャでは無視されるようになっています。

C.1 KP サービスの概要

KP モデルについて説明する場合,任意のストール機能と再開機能を備えた共通ルーチン・モデルとして説明するのが最も正確です。プロセス・コンテキストまたはシステム・コンテキストで動作するコード・ストリームは,既存のスタック・コンテキストを妨害せずに,同じモードで他のストリーム (KP ルーチン) を起動しようとします。そのとき,KP ルーチンは独自の異なるコンテキストを維持しながら,必要に応じてストールと再開を実行できます。 KP ルーチンの再開は,KP ルーチンを起動した元のコード・ストリームと非同期に行うことができます。

KP ルーチンは,プライベート・スタック (I64 では 2 つ 1 組のスタック) で動作するルーチンであると考えると最も簡単です。ルーチンは,ストールおよび再開することができます。コンパイラにとっては,起動するためのルーチン,ストールするためのルーチン,再開するためのルーチンは,単に OpenVMS 呼び出し規則に準拠した外部プロシージャ呼び出しに過ぎません。状態の保存とスタック切り換えは完全に KP ルーチンのコンテキストの内部で行われます。コード・ストリームが制御を放棄すると,再開ポイントでは,制御を切り換えた呼び出しが完了したかのように見えます。

ベース・サポートには,必要なスタックとデータ構造の割り当てを支援するルーチン,および KP ルーチンの起動,ストール,再起動,終了を行うルーチンが含まれています。

KP ルーチンは別の KP ルーチンを起動できます。

基本的な KP サポート・ルーチンは次のとおりです。

  • EXE$KP_START--- KP ルーチンを起動します。

  • EXE$KP_STALL_GENERAL--- 現在のルーチンをストールし,EXE$KP_START または EXE$KP_RESTART を最後に呼び出したルーチンに戻ります。

  • EXE$KP_RESTART--- EXE$KP_STALL_GENERAL の呼び出しによってストールされた KP ルーチンを再起動します。

  • EXE$KP_END--- KP ルーチンを終了します。

各ルーチンと必要なデータ構造については, 付録 C.2.2 項 を参照してください。

C.1.1 用語

メモリ・スタックとは,スタック・ポインタ・レジスタを参照するスタックです。 Alpha システムには,メモリ・スタックしかありません。

レジスタ・スタックとは, レジスタ・スタック・エンジン (RSE) バッキング・ストアの略称です。 I64 アーキテクチャには 96 個のスタック・レジスタがあり,ルーチン間で引数を受け渡したり,ルーチン内でのローカル・ストレージとして使用したりできます。ハードウェアはスタック・レジスタの状態を維持管理し,必要に応じてレジスタをバッキング・ストアに書き出します。

KP ルーチンとは,1 つ以上のプライベート・スタックで動作する一連のコードです。 EXE$KP_START の呼び出しによって起動され, EXE$KP_END の明示的な呼び出しまたは暗黙の呼び出しによって終了します。

KPB とは,1 つ以上のスタックを記述し, KP ルーチンの状態およびコンテキスト情報を保持するデータ構造です。

EXE$KP_START を呼び出すことで KP ルーチンをアクティブにするために KPB が使用されると, KPB は有効になります。 EXE$KP_END は KPB を無効としてマークします。 KPB の初期状態は無効です。

EXE$KP_START を呼び出すことで KP ルーチンが起動されるか,EXE$KP_RESTART を呼び出すことで再起動されると, KPB はアクティブになります。 EXE$KP_STALL_GENERAL と EXE$KP_END は, KPB を非アクティブとしてマークします。 KPB の初期状態は非アクティブです。

C.1.2 スタックとデータ構造

I64 では,3 つのメモリ領域が KP ルーチンに関連付けられています。 3 つのメモリ領域とは,メモリ・スタック, RSE スタック,KPB です。 KPB はこれらの 3 つのメモリ領域全部を結びつけるデータ構造です。 Alpha には RSE スタックがないため,RSE スタックに関連するパラメータとフィールドはすべて無視されます。

KPB とスタックはそれぞれ,適切な領域から割り当てる必要があり,KP ルーチンが実行されるモードと対応するように,適切なモード,保護,オーナーシップを選択する必要があります。既存のアプリケーションをポーティングする場合,アプリケーションはあらかじめ適切なメモリ・スタックを割り当てていると考えられます。既存のメモリ・スタック割り当てルーチンは,KP API に適応できます。以前のアーキテクチャと同様に,メモリ・スタックは最上位アドレス (スタックのベース) から最下位アドレスへの向きでアクセスされます。

レジスタ・スタック・エンジンはまったく新しい概念であり,以前の 32 ビット・コードに依存しないため, RSE スタックは通常,64 ビット空間から割り当てられます。一般的なアプリケーション・ニーズの大部分に対応できる多くの割り当てルーチンが提供されています。 RSE スタックは最下位アドレスから最上位アドレスへの向きにアクセスされます。

表 C-1 は,アプリケーションのモードとスコープ別に,割り当てのガイドラインを示しています。

表 C-1 モードおよびスコープ別割り当てガイドライン
モード---スコープ1 KPB メモリ・スタック レジスタ・スタック
カーネル---システム
EXE$KP_ALLOC_KPB 2
非ページング・プール
KW
EXE$ALONONPAGED
S0/S1
KW
EXE$KP_ALLOC_MEM_STACK
S2
KW
EXE$KP_ALLOC_RSE_STACK 3
カーネル---プロセス 非ページング・プールまたは P1
KW
EXE$ALONONPAGED または EXE$ALOP1PROC
P1---パーマネント
KW
$CREATE_REGION/$CRETVA
P2---パーマネント
KW
EXE$KP_ALLOC_RSE_STACK_P2
カーネル---イメージ
P1
KW
EXE$ALOP1IMAG
P1---非パーマネント
KW
$CREATE_REGION/$CRETVA
P2---非パーマネント
KW
$CREATE_REGION/$CRETVA
Exec---プロセス P1
EW
EXE$ALOP1PROC
P1---パーマネント
EW
$CREATE_REGION/$CRETVA
P2---パーマネント
EW
EXE$KP_ALLOC_RSE_STACK_P2
Exec---イメージ P1
EW
EXE$ALOP1IMAG
P1---非パーマネント
EW
$CREATE_REGION/$CRETVA
P2---非パーマネント
EW
$CREATE_REGION/$CRETVA
Super---プロセス P1
SW
EXE$ALOP1PROC
P1---パーマネント
SW
$CREATE_REGION/$CRETVA
P2---パーマネント
SW
EXE$KP_ALLOC_RSE_STACK_P2
Super---イメージ P1
SW
EXE$ALOP1IMAG
P1---非パーマネント
SW
$CREATE_REGION/$CRETVA
P2---非パーマネント
SW
$CREATE_REGION/$CRETVA
ユーザ---イメージ P0
UW
Heap/Malloc/LIB$GET_VM
P0---非パーマネント 4
UW
EXE$KP_ALLOC_MEM_STACK_USER
P2---非パーマネント
UW
EXE$KP_ALLOC_RSE_STACK_P2

1 イメージ・スコープはイメージの終了時に終了します。プロセス・スコープはプロセスの終了時に終了し,イメージがランダウンしても継続します。システム・スコープはプロセス・コンテキストを必要としません。
2 EXE$KP_ALLOC_KPB は,1 回の呼び出しでカーネル・モード KPB とカーネル・モード・スタックを割り当てます。
3 EXE$KP_ALLOC_RSE_STACK_P2 はパーマネント領域を作成します。
4 パーマネント・メモリ領域をユーザ・モードで作成することはできません。



KPB とは,KP ルーチンを起動するコード・ストリームと KP ルーチンの間で必要なコンテキストを保持するために使用されるデータ構造です。 KPB は半透過的です。一部のフィールドはアプリケーションで管理され,一部は KP ルーチンで管理され,一部は両方で共有されます。 KP ルーチンでは,KPB は割り当て時に 0 に初期化されるので,0 以外のフィールドには適切なデータが格納されていると解釈されます。

KPB の構造定義は,Macro-32 では $KPBDEF マクロで, C では KPBDEF.H で定義されます。 KPB 定義はシステムの内部的な定義であると考えられるため, LIB.MLB と SYS$LIB_C.TLB で提供されます。 BLISS の場合は,LIB.REQ または LIB.L32/LIB.L64 に KPB 定義が格納されています。

KPB は多くの領域またはサブ構造で構成される可変長構造です。すべての領域が必須なわけではありません。領域は以下のとおりです。

  • ベース領域

  • スケジューリング領域

  • VEST 領域

  • スピンロック領域

  • デバッグ領域

  • ユーザ・パラメータ領域

ベース領域は必須です。この領域には,標準構造ヘッダ,スタック・サイズとベース・アドレス,フラグ (他にどの領域が存在するかの情報を含む),非アクティブ・コード・ストリームのメモリ・スタック・ポインタ,他の領域を参照するポインタ,ベース KP ルーチンが必要とする追加フィールドが格納されます。

スケジューリング領域には,ストール,再起動,終了を取り扱うルーチンを参照するポインタ,フォーク・ブロック,追加フォーク・ブロックを参照するポインタが格納されます。終了ルーチンを除き,他のルーチンの大部分は,高い IPL で実行されるドライバ・レベルのコードでのみ必要とされます。 EXE$KP_USER_ALLOC_KPB を呼び出すルーチンは,割り当てられたメモリの必要なクリーンアップを実行する終了ルーチンを指定する必要があります。

VEST 領域とスピンロック領域は,主にドライバ・コードで使用されます。

デバッグ領域は,ドライバ・サポート・ルーチンでインプリメントされる,制限されたトレース機能を提供します。

ユーザ・パラメータ領域は,単に他の領域に連続的に割り当てられる未定義ストレージです。アプリケーションはそれぞれの要件に応じて,このメモリを自由に使用できます。

C.1.4 提供される KPB 割り当てルーチン

OpenVMS オペレーティング・システムでは,KPB および関連スタックを割り当てるために, 2 つの標準的な割り当てルーチンを提供しています。 Alpha で提供されていたカーネル・モードのドライバ・レベル・インタフェースは,そのまま変更されずに提供されるため,KP インタフェースを使用するデバイス・ドライバは,この部分に関してソースを変更する必要がありません。さらに,モードに依存しないルーチンも提供されます。モードに依存しないルーチンは,アプリケーションで指定されたルーチンを呼び出して,KPB と各スタックを割り当てます。大部分の新規アプリケーションや,KP API にポーティングされるアプリケーションは,モードに依存しないルーチンを使用します。

カーネル・モード・ルーチンも,モードに依存しないルーチンも, KPB を初期化します。提供されるすべてのルーチンの C プロトタイプは,ヘッダ・ファイル EXE_ROUTINES.H に格納されています。

C.1.5 カーネル・モードの割り当て

カーネル・モードの割り当ての形式は次のとおりです。

EXE$KP_ALLOCATE_KPB kpb, stack_size, flags, param_size 

C プロトタイプ

status = EXE$KP_ALLOCATE_KPB( KPB_PPS kpb, 
    int stack_size, 
    int flags, 
    int param_size) 

カーネル・モードでのみ使用します。このルーチンのプロトタイプは,元の Alpha ルーチンと同じです。

I64 では,RSE スタック・サイズ = メモリ・スタック・サイズです。

  注意
スタック・サイズはバイト数で表します。

パラメータ

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

  • STACK_SIZE--- 割り当てられるスタックのサイズをバイト数で示す 32 ビット値。このパラメータは値渡しされます。渡される値は,ハードウェア・ページ・サイズの倍数に切り上げられます。どの場合も,割り当てられる最小ページ・サイズが SYSGEN パラメータ KSTACKPAGES より小さくなることはありません。スタックはページ境界で割り当てられ,両端にはマッピングされないガード・ページが配置されます。メモリ・スタックは 32 ビット S0/S1 アドレス空間に割り当てられます。
    I64 システムでは,RSE スタックはメモリ・スタックと同じサイズに設定され,64 ビット S2 アドレス空間から割り当てられます。

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

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

  • PARAM_SIZE--- 値渡しされるロングワード。 KPB 内のユーザ・パラメータ領域のサイズをバイト数で示します。パラメータ領域が必要ない場合は,0 を渡します。
    戻り値 (状態):
    SS$_NORMAL
    SS$_INSFMEM
    SS$_INSFARG
    SS$_INSFRPGS


目次 索引

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