ZLink

もし現在のプロセスがルーチンのコピーを含んでいない場合、ZLINKコマンドは、現在のプロセスに実行可能なGT.Mルーチンを追加します。もし現在のプロセスがルーチンのコピーを含んでいて、ルーチンがアクティブでない場合、ZLINKコマンドは、"新" バージョンを持つ現在のルーチンのプロセスを置き換えます。必要に応じて、ZLINKコマンドは、プロセスとそれを統合する以前のルーチンをコンパイルします。

VIEW "LINK":"RECURSIVE" を指定するか、または環境変数gtm_linkを "RECURSIVE"に設定してプロセスを開始すると、ZLINKコマンドは同じ名前のルーチンがアクティブで現在のスタックで使用可能な場合でも実行可能ルーチンを追加します。プロセスが既存のルーチンと同じ名前のルーチンをリンクすると、将来の呼び出しで新しいルーチンが使用されます。スタックによって参照されるそのルーチンの以前のバージョンは、QUITまでスタックに結び付けられており、その時点ではアクセスできない状態になります。これにより、長時間実行されるプロセスにパッチを当てる仕組みが提供されます。

[重要] 重要

アクティブなルーチンは、M仮想スタックの$STACK() または ZSHOW "S" と一緒に表示されます。デフォルトでは、アクティブなルーチンを置き換えると、実行時エラーが発生します。アクティブなルーチンを新しいバージョンに置き換えるには、VIEW "LINK":"RECURSIVE" を使用するか、またはZGOTOまたは適切な数のQUITを使用してスタックからアクティブなルーチンを削除してから、ZLINKコマンドを実行します。

ZLINKコマンドのフォーマットは:

ZL[INK][:tvexpr] [expr1[:expr2][,...]]

ZLINKコマンドがファイルを指定している時、GT.Mは、そのファイル名に $ZSOURCE をセットします。デフォルトでは、それらがない場合、または、null 引数がある場合、ZLINKとZEDITは、ファイル名として$ZSOURCEを使用します。引き続いて引数なしのZLINKは、ZLINK $ZSOURCEと同等です。$ZSOURCEの詳細については、第8章: “固有の特殊変数 の該当するセクションを参照してください。

[注意] 注意

ファイル名にパーセント記号(%)を許可しないGT.Mバージョンとの互換性を確保するために、パーセント記号で始まるルーチンのために、ZLINKファイル名にパーセントの代わりにアンダースコア(_)を使用します。

もし式に明示的にディレクトリが含まれている場合、ZLINKはそのディレクトリだけを検索します。そうでなければ、もし$ZROUTINES が null でない場合、ZLINKコマンドはファイルを見つけるために $ZROUTINES を使用します。もし$ZROUTINES が null の場合、 ZLINKはカレントディレクトリを使います。$ZROUTINESの詳細については、第8章: “固有の特殊変数 の該当するセクションを参照してください。

もしファイル名が明示的なファイル拡張子が含まれている場合、ZLINKは拡張子の オブジェクト( .o ) またはソース(通常は .m)に応じてファイルを処理します。もしファイル名がファイル拡張子を指定しない場合は、ZLINKは、ルーチンのオブジェクトとソースの両方を検索しマッチを試みます。

次の表は、ZLINKがファイル拡張子の3つの可能な処理する方法を示しています。

ZLINKの操作概要

拡張子の指定(EXTENSION SPECIFIED)

ZLINKに探索された拡張子(EXTENSION SOUGHT BY ZLINK)

結果(RESULT)

 

.o

.m

 

.o

found

N/A

link only

 

not found

N/A

error

.m

N/A

found

compile and link

  N/A

not found

error

None

not found

found

compile and link

  found not found link only
  not found not found error
 

found .o file newer than .m and version okay

found .m file older than .o

link only

 

found .o file older than .m or version mismatch

found .m file newer than .o

compile and link

ZLINK コンパイル

もしZLINKがルーチンをコンパイルする場合、かつ、 -OBJECT= 修飾子が出力をリダイレクトしない場合、、検索条件で指示されたディレクトリに生成されるオブジェクトファイルを配置します。ZLINKは、そのディレクトリの配置に関係なく、イメージに新しいオブジェクトファイルが組み込まれます。

もしコマンドがコンパイル修飾子(expr2で)を指定していない場合、かつ、$ZCOMPILE が null の場合、GT.MはデフォルトのMコマンド修飾子と -ignore, -labels=lower, -nolist, -object を使用します。$ZCOMPILEの詳細については、 第8章:“固有の特殊変数 の該当するセクションを参照してください。Mコマンドの修飾子の詳細な説明については、 第3章: “プログラム開発サイクルを参照してください。

オブジェクトファイルを生成するが、カレントイメージにそれらを追加しない方法については、 "ZCOMpile" を参照してください。

ZLINKの例

例:

GTM>ZLINK "test"

もし ZLINK が test.m または test.o を見つけた場合、カレントイメージへルーチン test を追加します。もし ZLINK が test.o を検出できない場合、または、test.o が test.m よりも古いことを検出する場合、GT.Mは新しい test.o を生成するために test.m をコンパイルし、イメージに新しいオブジェクトファイルの内容を追加します。この例では、 "test" が現在のMスタックにないと仮定しています - スタック上にある場合、GT.Mはエラーを返します。

例:

GTM>zlink "test.m":"-noobject -list"

これは、ルーチン " test " をコンパイルし、オブジェクトファイルがないリストを生成します。例ではオブジェクトファイルを生成しないので、既存のオブジェクトファイル(カレントイメージ内のすべてのコピーと同じになる可能性がある)を配置する必要があります; もし存在しない(noexisting)オブジェクトファイルがをそこにある場合、GT.Mはエラーを生成します。この例でZLINKでコンパイル修飾子を使用することを示している間に、-noobject -list のコンパイルは、より良いZCOMPILEが行われる可能性があります。

例:

GTM>zlink "sockexamplemulti2"
%GTM-E-LOADRUNNING, Cannot ZLINK an active routine sockexamplemulti2
GTM>zshow "S"
sockexamplemulti2+12^sockexamplemulti2    (Direct mode)
GTM>view "LINK":"RECURSIVE"
GTM>zlink "sockexamplemulti2"
GTM>

この例は、以前のバージョンがアクティブなM仮想スタックに既に存在しているときに、VIEW "LINK":"RECURSIVE" コマンドが、どのようにルーチンをZLINKするかを示しています。

Auto-ZLINK

GT.Mルーチンがプロセスメモリにリンクされていないルーチンを参照している場合、GT.Mは自動的にそのルーチンをZLINKしようとします。自動ZLINKは、指定されたディレクトリまたはファイル拡張子なしでルーチンの明示的なZLINKと機能的に同等です。

以下のGT.Mのコマンドおよび関数は、自動ZLINKで初期化が可能です:

  • DO

  • GOTO

  • ZBREAK

  • ZGOTO

  • ZPRINT

  • $TEXT()

次の条件が満たされている場合、GT.Mはルーチンを自動ZLINKします:

  • 前述のZLINK操作の概要表に示されているように、ZLINKはルーチンファイルを検索して処理できます。

  • ルーチンの名前は、ソースファイルの名前と同じですが; 唯一の例外は、GT.Mがファイル名の先頭をパーセント記号(%)からアンダースコア(_)へ変換することです。

Auto-ZLINK セットアップ

このセクションでは、自動再リンク機能を設定する手順について説明します。GT.Mは、オブジェクト・ディレクトリ($ZROUTINES内)から *-suffix(すなわち auto-relink-enabled)でリンクされたオブジェクトファイルを共有メモリセグメント(以下、Rtnobj 共有メモリセグメントと呼ぶ)にロードします。ルーチン名(ルーチン名のないラベルとは対照的に)を含む entryref を指定する DO, GOTOまたはZGOTO, 外部関数, ZBREAK, ZPRINT または $TEXT() の呼び出し時に、 GT.Mプロセス(およびトリガロジックを実行するMUPIPプロセス)は、自動的に再リンク ("auto-relink") され、公開された新しいバージョンのルーチンを実行します。

[注意] 注意
  • ラベル参照(ルーチン名なし)は、直接か間接かに関わらず、常に現在のルーチンを参照し、自動再リンク・ロジックを呼び出さない。

  • gtmroutines環境変数のディレクトリ名にアスタリスクを付加する場合は、シェルの引用符規則を使用します - アスタリスクはGT.Mに渡され、シェルによって展開されません。

  • GT.Mは、自動再リンクを提供しないx86プラットフォーム上の32ビットLinux上のディレクトリ名に対するアスタリスク接尾辞を受け入れますが無視します。

ZRUPDATEコマンドは、新しいバージョンのルーチンをサブスクライバに発行します。ルーチンを削除するには、オブジェクトファイルを削除し、削除されたオブジェクトファイルの名前を公開します。ワイルドカードを含むパターンは削除されたファイルと一致できないため、削除するとファイル名が明示的に指定されている必要があります。

もしファイルへのパスが存在しない場合、現在共有されているオブジェクトファイル(削除される前にアクセスされたもの)が共有されなくなることを望む場合を除いて、要求は無視されます。

GT.Mプロセスが$ZROUTINESを介して検索中にアクセスするそれぞれ自動再リンク対応ディレクトリについて、GT.M は $gtm_linktmpdir で指定されたディレクトリに小さな制御ファイル(Relinkctl)を作成します(デフォルトは $gtm_tmpで、次にもし未指定の場合 デフォルトは /tmp になります)。これらのファイルの名前は、gtm-relinkctl-<murmur>の形式です。ここで、<murmur>は自動再リンクディレクトリへのrealpath()のハッシュです; たとえば、次のようになります: /tmp/gtm-relinkctl-f0938d18ab001a7ef09c2bfba946f002)。Relinkctlファイルごとに、GT.Mは関連する制御構造を含む共有メモリのブロックを作成して関連付けます。構造の中には、ルーチンディレクトリにある各ルーチンに対応するサイクル番号があります; サイクル番号の変更は、ルーチンに新しいバージョンがあるかどうかを判断する必要がある可能性があるプロセスに通知します。GT.Mはディスクに実際に存在するルーチンの relinkctl レコードしか作成しませんが、ディスク上に存在しなくても既存のrelinkctlレコードのサイクル番号を増やすことがあります。

GT.Mは、管理および操作ガイドの "共有リソースの承認権限"の章の"IPCの権限" の項で説明したロジックに基づいて、Relinkctlファイルと共有メモリの両方を作成します。ただし、オブジェクトディレクトリではなく、データベースファイルは、ベースのアクセス許可を提供します。

MUPIP RCTLDUMPコマンドは、relinkctlファイルおよび関連する共用メモリー・セグメントに関連する情報を報告します。

環境変数 gtm_autorelink_keeprtn が1、t [rue]、またはy [es]に設定されていると、既存のプロセスは共有メモリ・リポジトリに自動再リンクされたオブジェクトコードを残し、未定義、0、f [alse]、または n[o] の場合は、既存のプロセスが、現在プロセスなしで使用しているルーチンを一掃します。すべての値は大文字と小文字を区別しません。gtm_autorelink_keeprtn が定義され、それがTRUEの場合:

  • プロセスの終了は簡素化され、パフォーマンスの向上を伴い、つまりプロセスの高速終了 - 多数のプロセスが同時に終了した場合にのみ、観察される可能性があります。

  • ルーチンがプロダクション環境など他のプロセスによって繰り返し使用される可能性がある場合、既存のプロセスでもはや使用されなくなっても共有メモリーにルーチンを残すと、将来のプロセスによりそのルーチンのリンクがわずかに速くなりますが、しかし、アプリケーションが短命のプロセスを頻繁に使用する場合を除いて、その影響は観測できない場合があります(CGIインターフェースを使用してWebサーバーによって呼び出されるGT.Mルーチンなど)。

FISでは、プロセスの $zroutine 内のディレクトリが、プロセスの稼働中に自動再リンク可能または自動再リンク不可(auto-relink-enabled or auto-relink-disabled) のいずれかになることを推奨しています。プロセス内のディレクトリの自動再リンクモードを変更すると、直感的とは逆の結果が得られます。

引数として、ZRUPDATE は $ZSEARCH() によって受け入れられたフォームのワイルドカードを含むオブジェクトファイル名をとります。もしZRUPDATEが引数をワイルドカードと突き合わせるために少なくとも1つのファイルを見つけられなかった場合は、INFOメッセージを発行します($PRINCIPAL にCENABLEがある場合のみ表示されます)。引数がワイルドカードなしの明示的な名前を指定していても、ディレクトリにファイルがないか、または Relinkctl の対応するエントリがない場合、ZRUPDATEはエラーを生成します。ZRUPDATEはほとんどのエラーをFILEPARSEエラーとして発行しますが、実際の問題を説明する2次エラーがありますが、ZRUPDATEが検出した理由とパスによってはエラーが発生する可能性があります。

明示的なZLINKまたは自動再リンクは、オブジェクトのハッシュとその置換をチェックします。それらが同一であれば、GT.Mは現在のオブジェクトを置き換える何もせず、メモリと時間の両方を節約できます。GT.Mは、次のいずれかの状況で、要求されたオブジェクトが現在リンクされているオブジェクトファイルと一致すると判断した場合、ルーチンの動的リンクをバイパスします:

  • 同じディレクトリからの自動再リンク

  • オリジナルのオブジェクトも新しいオブジェクトも自動再リンクされない明示的なZLINK

それ以外の場合、GT.Mは常に動的リンクを実行します

自動再リンクディレクトリからの明示的なZLINKは、暗黙のZRUPDATEとして機能します。

ルーチン内のZBREAKは、すべてのZBREAKが削除されるまで、そのルーチンがプロセスによって自動再リンクされるのを無効にします。

再帰的再リンクが有効になっていない場合、M仮想マシンスタック内で現在アクティブなルーチンは、完了するまで(またはZGOTOによってスタックから削除されるまで)自動再リンクから無効になります。

Auto-zlinkの利点と例

自動再リンク(auto-relink)の利点は次のとおりです:

  • 自動再リンク機能は、ほとんどの状況下で現在のルーチンを自動的に実行する利便性を提供します。

    VIEW "LINK":"RECURSIVE" と組み合わせると、自動再リンクは、それらがアクティブで現在のスタックで利用可能であっても自動的に再リンクします。VIEW "LINK":"RECURSIVE" を使わずに自動再リンクを実行することは可能ですが、スタック内で現在アクティブなルーチンは自動再リンクされません、そして、もし明示的にZLINKされた場合、スタックが完了するかスタックから削除されるまで、LOADRUNNINGエラーが発生します。

  • 自動再リンクを使用すると、ルーチン・オブジェクト・ファイルが共有メモリーにロードされます。したがって、複数のプロセスによる特定のルーチンの使用は、大幅なメモリ節約をもたらします(ユーザーあたり1つのコピーではなく、システムごとに1つのコピー)。これは、共有オブジェクトライブラリを使用したメモリ共有に似ていますが、共有ライブラリは動的更新を許可しません。

  • -embed_source オプションで明示的にコンパイルされたルーチンや、$ZCOMPILEが "-embed_source"に設定された状態で自動コンパイルされたルーチンと組み合わせると、自動再リンクは$TEXT() と ZPRINT がディスクの代わりに共有メモリからソースコードにアクセスする際のパフォーマンスを向上させる可能性があります。

  • $gtm_autorelink_keeprtn が定義されTRUEに設定されている場合、短い実行プロセスでGT.Mルーチンを頻繁に呼び出すアプリケーション(CGIのようなインターフェースを介したものなど)は、ルーチンが共有メモリに保持され、短時間の実行中のプロセスで必要とされるときに再利用できるため、パフォーマンスが向上する可能性があります。

自動再リンク機能の使用と設定は、要件によって異なります。 次に例を示します。次に例を示します:

$ /usr/lib/fis-gtm/V6.2-001_x86_64/gtm
GTM>w $zroutines
/home/jdoe/.fis-gtm/V6.2-001_x86_64/o*(/home/jdoe/.fis-gtm/V6.2-001_x86_64/r /home/jdoe/.fis-gtm/r) /usr/lib/fis-gtm/V6.2-001_x86_64/plugin/o/_POSIX.so /usr/lib/fis-gtm/V6.2-001_x86_64/plugin/o(/usr/lib/fis-gtm/V6.2-001_x86_64/plugin/r) /usr/lib/fis-gtm/V6.2-001_x86_64/libgtmutil.so /usr/lib/fis-gtm/V6.2-001_x86_64

$ZROUTINESでは、オブジェクト・ディレクトリの後の *-suffix は自動再リンク機能を有効にします。デフォルトでは、sourceforge.net のGT.Mディストリビューションの一部として利用可能な gtm/gtmprofile スクリプトには、自動再リンクが有効になっています。

自動再リンクが有効になっていると、 GT.Mは、オブジェクト・ディレクトリから、明示的なZLINK、暗黙的なZLINK(DO、GOTO、ZPRINT、$TEXT() )、他の同時/将来のプロセスによってルーチンにアクセス可能な外部関数呼び出し($$)などのRtnobj 共有メモリセグメントにオブジェクトファイルをロードします 。

[注意] 注意

auto-relinkを使用すると、GT.Mは、1 MiB(ヒュージ・ページ(hugepages)が設定されている場合は2 MiB以上)の初期 Rtnobj 共有メモリセグメントを作成し、自動再リンク機能を管理するために92MiBの共有メモリセグメントを割り当てます。したがって、システムに適切な共有メモリが設定されていることを常に確認してください; そうでない場合、GT.Mは以下の行に沿ってメッセージを表示します。

%GTM-E-SYSCALL, Error received from system call shmget() failed

共有メモリの制限を設定するには、OSのマニュアルを参照してください(通常のLinuxシステムの場合、/etc/sysctl.conf の kernel.shmmaxパラメータなど)。

ルーチンがより多くのMiB共有メモリを必要とする場合は、環境変数 $gtm_autorelink_shm を整数値(2の累乗)に設定します。自動再リンクでルーチンを保存するための共有メモリが必要な場合、GT.Mは自動再リンク操作のために $gtm_autorelink_shm MiB の2倍のサイズを自動的に割り当てます。

GTM>zedit "myprogram.m"
GTM>

ZEDITは $ZROUTINES の最初のソースディレクトリ、つまり/home/jdoe/.fis-gtm/V6.2-001_x86_64/rディレクトリに新しいファイルを置きます。

GTM>do ^myprogram

暗黙的なZLINK(DO、GOTO ZGOTO、ZPRINT、$ TEXT()または関数/外部呼び出しの最初の呼び出し)または明示的なZLINK "myprogram.m"またはZRUPDATE "/home/jdoe/.fis-gtm/V6.2 -001_x86_64 / myprogram.o " は、Relinkctlファイルが存在しない場合はそれを作成し、関連する共有メモリーを作成します。relinkctlファイルには、ディレクトリのハッシュに関連付けられた名前があり、プロセスがルーチンを見つけることができるように、共有メモリへのセグメントIDの形式でポインタを提供します。

gtm_linktmpdir 環境変数は、デフォルトで gtm/gtmprofile スクリプトに設定されていないため、gtm_tmp環境変数が指すディレクトリにRelinkctlファイルが保存されます。

GTM>zshow "A"
Object Directory : /home/jdoe/.fis-gtm/V6.2-001_x86_64/o
Relinkctl filename : /tmp/fis-gtm/V6.2-001_x86_64/gtm-relinkctl-43b26ca8384ddbf74b94d90a830c0bc9
# of routines : 1
# of attached processes : 1
Relinkctl shared memory : shmid: 375586821 shmlen: 0x5800000
Rtnobj shared memory # 1 : shmid: 375619590 shmlen: 0x200000 shmused: 0x400 shmfree: 0x1ffc00 objlen: 0x280
rec#1: rtnname: myprogram cycle: 1 objhash: 0xd81f1cdcc275e13d numvers: 1 objlen: 0x280 shmlen: 0x400

ZSHOW "A"コマンドは、relinkctl ファイルとそれが指し示すルーチン・レコードに関連する情報を共有メモリー・セグメントに表示します。ルーチンのレコードは、relinkctlファイルのコンテキストで共有メモリに挿入された順に表示されます。

GTM>zedit "myprogram2.m"

ZEDITは $ZROUTINES の最初のソースディレクトリ、つまり/home/jdoe/.fis-gtm/V6.2-001_x86_64/rディレクトリに新しいファイルを置きます。

GTM> zrupdate "/home/jdoe/.fis-gtm/V6.2-001_x86_64/o/*.o"

ZRUPDATEコマンドは、オブジェクト・ハッシュが Rtnobj共有メモリに最後にロードされたものとは異なるそれらのルーチンレコードのサイクルカウンタをインクリメントします。この場合、それは rec#2、つまりmyprogram.oになります。ZRUPDATEはルーチンを再コンパイル/再リンクしません。代わりに、現在および将来のすべてのプロセスに、オブジェクトコードが古くなっていることを指示し、次回の呼び出し時に必要に応じて自動再リンクする必要があります。明示的なZLINKまたは自動再リンク(いずれか最初に起こるいずれか)は、オブジェクトとその置換のハッシュをチェックし、同一でないことを発見した場合に再コンパイル/再リンクを開始します。

GTM>zshow "A":zru

何100ものルーチンがある場合、ZSHOW "A":zruのようなコマンドは、ZSHOW "A"の出力をローカル変数に転送します。次の例では、その結果を使用して、disprtn関数に渡された文字列を含むすべてのルーチンに関する情報を表示します。

GTM>zprint ^disprtn
disprtn(rtn)
set x="" for set x=$order(zru("A",x)) quit:x="" write:$piece(zru("A",x),":",3)[rtn zru("A",x),!
quit ""

次のような結果が得られます:

GTM>w $$^disprtn("myprogram")
rec#1: rtnname: myprogram2 cycle: 1 objhash: 0x436c855d5891e7cf numvers: 1 objlen: 0x370 shmlen: 0x400
rec#2: rtnname: myprogram cycle: 1 objhash: 0xd81f1cdcc275e13d numvers: 1 objlen: 0x280 shmlen: 0x400
GTM>

ZLINK, auto-ZLINK と ルーチン名

GT.Mでは、ソースファイルの名前は、GT.Mルーチンの名前を決定します。オブジェクトファイルのファイル名がルーチンの名前と一致する必要はありません。オブジェクトファイルをリンクすると、GT.M.に知られている内部ルーチン名(ソースファイルから派生)を作ります。ZLINKと自動ZLINKの両方が、ルーチンを見つけるために、オブジェクトファイルの名前を使用するので、しかしながら、潜在的な混乱につながることがあります。オブジェクトファイル名がルーチンの名前と異なる場合、自動ZLINKは、実行時エラーを生成します。

[注意] 注意

それらの引数に .m または .o ファイル拡張子を付けないAuto-ZLINKおよびZLINKコマンドは、オブジェクトファイルが基となるシステムコールによって提供されたナノ秒単位の時間を使用してソースファイルよりも最近変更されたかどうかに基づいて再コンパイルする必要があるかどうかを判断します。ファイル変更のタイムスタンプのフォーマットはナノ秒の精度を提供しますが、サポートされている多くのOSは現在、ファイルのタイムスタンプを1秒の精度で更新しています。

inserted by FC2 system