HP OpenVMS Systems Documentation |
| 前へ | 次へ | 目次 | 索引 |
いくつかのレイヤード・プロダクトについては OpenVMS I64 にポーティングする計画がありません。 表 B-1 に,そのようなレイヤード・プロダクトと,弊社が推奨する代替製品を示します。
| 製品名 | 推奨する代替製品名 |
|---|---|
| BASEstar Classic | BASEstar Open |
| HP Ada Compiler for OpenVMS Alpha Systems | GNAT Ada for OpenVMS Integrity Servers---Ada Core Technologies 社製 |
| Pathworks 32 | Advanced Server |
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 サポート・ルーチンは次のとおりです。
各ルーチンと必要なデータ構造については,
付録 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 は,アプリケーションのモードとスコープ別に,割り当てのガイドラインを示しています。
| モード---スコープ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 |
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 は多くの領域またはサブ構造で構成される可変長構造です。すべての領域が必須なわけではありません。領域は以下のとおりです。
ベース領域は必須です。この領域には,標準構造ヘッダ,スタック・サイズとベース・アドレス,フラグ (他にどの領域が存在するかの情報を含む),非アクティブ・コード・ストリームのメモリ・スタック・ポインタ,他の領域を参照するポインタ,ベース 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 スタック・サイズ = メモリ・スタック・サイズです。
スタック・サイズはバイト数で表します。 |
パラメータ
| フラグ | 説明 |
|---|---|
| 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 を呼び出します。条件処理では正確なスタック・リミット値が必要なため,プロセス・スコープ・アプリケーションは常にこのフラグを設定する必要があります。 |
SS$_NORMAL
SS$_INSFMEM
SS$_INSFARG
SS$_INSFRPGS
| 前へ | 次へ | 目次 | 索引 |