時間に関する機能には、日付と時刻の取得の他にインターバル・タイマー(間隔計時機構)があります。一定時間おきに行う処理を作る際や一定時間プログラムの実行を止める場合などに利用されます。
10秒間プログラムの実行を停止する
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- LA R2,6 SET LOOP COUNTER TRYENQ DS 0H ENQ (SPFEDIT,DSNMEMB, TEST PDS MEMBER RESERVED BY + E,0,SYSTEMS), ISPF EDITOR OR NOT. + RET=TEST LTR RF,RF SUCCESSFUL ? BZ PROGEND YES, PROGRAM DONE WTO 'MYP001I MEMBER IS USED NOW' NO, INFORM ENQ ERROR SPACE , STIMER WAIT,BINTVL=WAITTIME SLEEP 10SECOND SPACE , BCT R2,TRYENQ TRY ENQ AGAIN SPACE , PROGEND DS 0H SVC 3 EXIT TO DISPATCHER SPACE , WAITTIME DC F'1000' 10.00SEC(1/100SEC ORDER) SPFEDIT DC CL8'SPFEDIT' ENQ CATEGORY DSNMEMB DC AL1(52) RESOURCE NAME LENGTH DC CL44'MY.JCL' DSNAME DC CL8'DATA1' MEMBER |
一定時間プログラムの実行を止めるには、STIMERサービスのWAIT機能を使います。STIMERマクロの最初の定位置パラメーターにWAITを指定し、続けて待ち合わせ時間を定義したパラメーターを指定します。サンプルでは、待ち合わせ時間を2進整数で指定しています。1/100秒単位で指定でき、1は1/100秒、100は1秒となります。STIMERマクロ発行後、OSサービスルーチン内で指定した時間が経過するまで待ち状態に入ります。指定した時間が経過するとプログラムに戻ってきます。
サンプルの処理内容は、指定した区分データセットのメンバーがISPFエディターで編集中かをENQマクロでテストします。編集中であればENQが失敗するので、その事をWTOマクロでコンソールにメッセージで通知して10秒間待ち状態に入ります。10秒経過後、再びENQをトライします。このサイクルで6回繰り返し、都合1分間リトライします。ENQに成功した場合と、リトライ回数をオーバーしたらプログラムは終了します。
ENQマクロによる排他制御が獲得できない時、一定回数リトライすることはよく行われますが、人間の操作が絡む資源の場合、単にループするよりはSTIMERマクロを組み合わせて一定時間待ってからリトライするのが一般的です。
指定した時刻になったら通知してもらう
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- MVI WKUPECB,0 CLEAR ECB STIMER REAL,TIMREXIT, SET TIMER + TOD=WKUPTIME WAIT ECB=WKUPECB WAKE-UP AT SPECIFIED TIME : : 指定した時刻に行う処理をここに書く : : WKUPECB DC F'0' ECB FOR WAKE-UP MAINLINE WKUPTIME DC ZL8'15000000' WAKE-UP TIME=15:00:00.00 : : TIMREXIT DS 0H USING *,RF DEFINE TIMER EXIT BASE REG ST RE,12(,RD) SAVE RETURN ADDRESS L R1,AECB LOAD ECB ADDRESS POST (1) WAKE-UP MAINLINE ROUTINE L RE,12(,RD) LOAD RETURN ADDRESS B 0(,RE) RETURN TO OS AECB DC A(WKUPECB) PTR TO MAINLINE ECB WORD DROP RF FORGET BASE REG |
目覚まし時計プログラムです。一定時間の経過ではなく、指定した時刻になったら起き上がるサンプルです。今度はWAITではなくREALを指定しています。REALは実時間の経過を通知する機能です。TODパラメーターは、間隔時間ではなく時刻を指定するパラメーターです。TODの代わりにLTパラメーターでもかまいません。
運用の自動化ソフトなどを使えば必要ありませんが、18:00になったらオンラインシステムを終了させる、21:00になったらバックアップのジョブを実行させるなど、決まった時刻になったら行う処理を自動化させるためには目覚まし時計が必要です。
10秒ループしたら自分で自分をキャンセルする
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- STIMER TASK,TIMREXIT, SET TIMER BY USED CPU TIME + TUINTVL=CPUTIMER : : LOOP DS 0H LOCAL CPU LOOP AT HERE LA R0,* I SLL R0,31 I ALR R0,R1 I SRDL R0,14 I B LOOP V : : CPUTIMER DC F'384000' AVAILABLE CPU TIME : : TIMREXIT DS 0H ABEND 322 ABEND US WITH U322 |
実時間ではなくCPU時間によるインターバルタイムの計測です。REALの代わりにTASKと指定します。間隔時間の指定方法はREALもTASKも同じです。このサンプルでは、CPUタイマー単位(約26.04166マイクロ秒)で指定しています。約10秒です。わかりにくいので、普通にBINTVLで指定してかまいません。
サンプルの処理は、一定のCPU時間を使い切ったらプログラムをABENDさせる例です。タイマーをセットしてから故意に無限ループに入ります。指定した時間のCPUを使い切ると、TIMREXITに飛び込んできます。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
TIMREXIT DS 0H USING *,RF DEFINE TEMP BASE REG STM RE,RC,12(RD) SAVE CALLER GPRS L RC,MAINBASE ESTABLISH OUR BASE ADDRESS DROP RF FORGET TEMP BASE REG : : POST WKUPECB POST TO WAKE-UP MAIN LINE : : LM RE,RC,12(RD) LOAD CALLER GPRS BR RE RETURN TO CALLER(OS) MAINBASE DC A(MAINENTR) MAIN LINE BASE ADDRESS |
サンプルではタイマー出口内で大した処理をしてませんので簡単に書いてますが、出口ルーチン内からメインライン側のデータ領域などを直接参照・更新したい場合は、上記のようなハウス・キーピングをすればいいでしょう。メインライン側のベース・アドレスを同じベース・レジスターに再設定します。STIMER出口ルーチンの規約では、汎用レジスター0~12の内容はSTIMERマクロ発行時の内容とは規定されていません。マニュアル通り、GR0~12は壊れていると言う前提で再設定します。STIMERに限らず全てのマクロの出口ルーチンについて言えます。マニュアルに記載されている、出口ルーチンのレジスター規約を必ず確認してそれに従います。
STIMERで設定したタイマーは、設定時間が経過して出口で通知されると無効になります。再びタイマーによる時間測定が必要なら、改めてSTIMERマクロを発行する必要があります。STIMERマクロは必ずしもメインルーチン内で出す必要はありません。出口ルーチン内でSTIMERマクロを発行してタイマーを再設定してもかまいません。
タイマー測定のキャンセル
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- STIMER REAL,TIMREXIT, SET TIMER BY REAL TIME + BINTVL=INTVLTMR : : L R0,=F'10000000' LOAD LOOP COUNTER LOOP DS 0H LOCAL CPU LOOP AT HERE SLR R2,R2 I LA R3,0 I XR R4,R4 I L R5,=F'0' I BCT R0,LOOP V : : TTIMER CANCEL CANCEL TIMER LTR R0,R0 HAVE ANY REMAINING TIME ? + REMAINING TIME STORED IN GR0 + WITH CPUTIMER FORMAT(26.04166) : : INTVLTMR DC F'1000' 10.00SEC : : TIMREXIT DS 0H BR RE NO OPERATING IN EXIT |
TTIMERマクロを使うと、一度設定したタイマーの残り時間を調べたりタイマー計測をキャンセルすることができます。サンプルでは10秒の実時間タイマーを設定してから、5命令×1千万回で計5千万回の命令を実行します。その後、TTIMERで設定したタイマーを取り消します。GR0にタイマーの残り時間がCPUタイマー形式(約26.04166マイクロ秒単位)で返されます。サンプルではタイマー出口は意味を持たないので、BR 14命令で何もせずに復帰しています。
タイマーを設定している常駐型のプログラムなどでは、オペレーター・コマンドなどによって処理を終了する時、TTIMERで不要になったタイマー設定を取り消します。TPモニターなどユーザー・アプリケーションを自分の制御で実行するようなソフトウェアでは、ユーザー・プログラム開始前にTASK指定のSTIMERでCPUタイマーを設定し、ユーザー・プログラムが終了した時点でそれを取り消したりします。
STIMERサービスは、1つのタスクで同時に複数使用することはできません。STIMERサービスによるインターバル・タイマーの設定は1つしか出来ないのです。同じタスクで複数のインターバルタイムを計測するためには、STIMERMマクロを利用します。