以下で説明するのは、 東陽テクニカ製 CAMAC クレートコントローラ CC/7000 および AT 互換機用インターフェースCC/7000AT-IF (ISAバス) を用いて、 Linux から CAMAC をコントロールするためのデバイスドライバです。 特に、原子核・素粒子実験で行なわれるような、 イベントタイプのデータ収集を支援する事に重点が置かれています。 ドライバは九州大学タンデム加速器施設で開発されたもので、 若干の修正と簡単なデータ収集システムのサンプルの作成、 および文書の整備を岡村が行ないました。 再配布は自由との事ですので多いに利用してください。
まず対象と考えているのは、 簡単なカウンターテストや学生実験レベルのデータ収集に適した 小規模なシステムです。 フロントエンドとホストが分離された本格的システムと比較するのは、 無意味ですから止めましょう。
Pentium-100MHz マシンを用いて行なった簡単なデータ収集テストでは、 LAM 発生から測った1イベント処理に要する最短時間は
でした。 CC/7000 は I/O ポートを通してしか制御されない (例えば CES2180 StarBurst J11 のように CAMAC アクセスを ハード的にマッピングする仕掛けを持っていない) 事を考慮すると、妥当な値と思われます。
Linux (および一般の UNIX) はリアルタイム OS ではないので、 カーネルが他のサービスを行なっていると、 それが終了するまで CAMAC の割り込み処理は遅延されます。 その影響は、システムにどの程度の負荷がかかっているかに 依存しますが、通常のディスクアクセスやグラフィックス描画 等を行なった所では、 50〜100μs程度のデッドタイムの増大として観測されました。 系統的なテストは行なっていませんが (調べられた方が居ましたら報告してください)、 実用上問題になる事は少ないと思われます。
OS のオーバーヘッドが少ないという意味では、 MS-DOS 等の (ハードウェア資源が自由自在に使える) 単純なシステムの方が有利とされています。 しかし、一方でヒストグラミングからディスプレイまで全てを備えた プログラムを開発しないと使い物にならないという難点が挙げられます。 速度に関しては、 CC/7000 のような I/O ポート経由の制御では所詮限界が有り、 むしろOS のオーバーヘッドは 今日の驚異的な CPU 速度向上によって マイナーな問題と化して来たように思われます。 Linux 等の本格的 OS を使う事は、 マルチプロセス、ネットワーク制御、充実した数々のツールと言った点で 大きなアドバンテージをもたらしてくれます。 ちょっとしたカウンターテストでも、 出来合いのヒストグラミングツールを流用して paw++ で表示したりできるのは、 素晴らしいと言えるのではないでしょうか。
/dev/dc
{,1,2,3}
という名前が major number 61 に割り当てられます。
LAM の enable/disable、バスの初期化等の速度を要求されない
オペレーションは、このデバイスに ioctl コマンドを
発行する事によって行なわれます。
しかし、 原子核・素粒子実験で一般的なイベントタイプのデータ収集では、 非同期に発生するイベントに対して遅延無く データの読み出しを行なう必要が有り、 ユーザープログラムがデバイスドライバを介して処理していたのでは とても間に合いません。 そこで、割り込み発生時の処理をデバイスドライバの中に記述し、 取り敢えずデータを適当なバッファに貯めておいて、 ユーザープログラムがデバイスドライバから read で読み出す方法が採られます。 つまり、実験装置や読み出しデータに応じて、 デバイスドライバを書き換える必要があるわけです。
元々 Linux は、 複雑になり過ぎて実現が困難になった OS に対するアンチテーゼ(?)として、 モノリシックカーネルによる、小さくて軽いシステムの実装を基本としていました。 しかしモノリシックカーネルでは、 デバイスドライバを変更するとカーネル全体を作り直す事になってしまいます。 これでは次から次に現れる有象無象のデバイスや、 PCMCIA 等の着脱型デバイスに対応できないので、 カーネルを止めずに組み込み/削除可能なデバイスドライバの仕組みが 加えられました。これがローダブルモジュールです。 ローダブルモジュールによるデバイスドライバの作成に関しては、 Linux Jounal #23 (Mar. '96) から 5 号連載で 非常に判りやすく解説されていますので、興味の有る方は参照してください。 また、この記事の日本語訳が LINUX JAPAN 創刊号にまとめて掲載されています。
本デバイスドライバもローダブルモジュールによる実装をサポートしています (カーネルに静的に組み込む事を拒むものではありませんが)。 ユーザーは、測定条件に応じて一つのルーチンを用意するだけで済むように なっています。 加えて、後述するように一部の (あまり危険でないと思われる?) コマンドを setuid すれば、 全く root 権限を要求する事無しに データ収集システムを構築する事が可能です。
README.html ... このファイル Makefile ... デバイスドライバ作成/組み込み、および サンプルシステム作成用 make ファイル cc7000.gif ... CC/7000 のレジスタ表 デバイスドライバ関連 camac.h ... 関連ソースのヘッダファイル camack.c ... 割り込み処理支援ファンクション集 dc.c ... デバイスドライバ本体 dc_int.c ... 割り込み処理ルーチン (int_test.c へのシンボリックリンク) int_test.c ... 割り込み処理ルーチンのサンプル test_led.c ... テストプログラム データ収集システムのサンプル crashm.h ... 共通ヘッダファイル commander.c ... コマンド解釈メインプログラム recorder.c ... データ記録プロセス analyzer.c ... オンライン解析プロセス event1.f ... analyzer から呼ばれる 1 イベント解析ルーチン player.c ... データ読み出しプロセス rei ... Tcl/Tk による GUI 制御スクリプト camac.gif ... rei の実行画面サンプルインストールは以下の手順で行ないます。
先ず、Makefile の中の
DEVICE = dc MAJOR = 61 IOPORT = 0x310 IRQ = 11 DELIM = 0x8001を適当に編集してください。 特に IOPORT と IRQ は、 ハードウェアの設定と一致している事をよく確認してください (ハードの設定に関しては 付録A を参照してください)。 現在の所、Linux の多くのデバイスドライバが行なうような 自動検出の機能はサポートしていません。
DELIM
(デリミタ) は
イベントの区切り子に使いますが、
データ収集システム全体の整合性のために
Makefile の中で指定しています。
次に root になって
% make devicesを実行すると、(デフォルトの設定では)
/dev/dc
{,1,2,3}のデバイスが定義されます。
恒久的な設定はこれで終りです。
以下は測定毎の手順です。
先ず読み込みたいデータを記述した割り込みルーチンを
"dc_int.c"
として用意します
(詳しくは後述の説明を参照してください)。
次に
% make [all]によってデバイスドライバをコンパイルします。 生成されるオブジェクトファイル
"dc.o"
がローダブルモジュールです。
dc.o
をカーネルに組み込むには
% make installを実行します。 古いバージョンが組み込まれている場合には入れ換えを行ないます。
make install (および uninstall) は 本来 root になって行なうべきものですが、
% chmod +s /sbin/insmodによってコマンドを setuid しておくと、 平ユーザーでもデバイスの組み込み/切り離しができるようになります (これによるセキュリティの問題は無いと思いますが…)。
正常にドライバが組み込まれれば、
Character devices: ..... 61 dc .....といったメッセージが出力されるはずです。 また、
... ... ... <<< dc >>> ... ... ... installed. dc: Buffer size is 131072 bytesというメッセージが
/var/adm/messages
というファイルの
最後に書き加えられます。
通常このファイルは root のみが読み出し可の設定となっていますが、
% dmesgによって、 平ユーザーでも末尾部分を出力させる事ができます。 デバイスがうまく組み込まれなかった場合には、 失敗となった原因のヒント (およびダンプ情報) が
/var/adm/messages
に書き込まれますから、参照してください。
最も有り勝ちなのは
IRQ や I/O ポートの衝突です。
ドライバが組み込まれたら、簡単なテストをしてみましょう。
プログラム "test_led.c"
は
Dataway Indicator (LED) を点滅表示させるものです。
これをコンパイルし (ライブラリは何も要りません)、
% cc -o test_led test_led.c % test_led 4のように、LED のステーションナンバーを引数に与えて 起動してみてください。
以上で CAMAC 制御の準備は完了です。 dc.o をカーネルから切り離すには
% make uninstallを実行してください。 dmesg コマンドの出力の末尾には
... ... ... <<< dc >>> ... ... ... uninstalled.の一行が加えられるはずです。
参考のために、 ローダブルモジュールおよびデバイスドライバに関連する コマンドを以下に列挙しておきます。 make … は、内部でこれらを実行しているだけです。
% /sbin/lsmod
% /sbin/insmod
module
% /sbin/rmmod
module
% mknod /dev/name c
major minor
% cat /proc/devices
% cat /proc/ioports
% cat /proc/interrupts
/proc/intterupts
に表示されない)。
/proc/...
には cat しか使えません
(more や less、ましてエディタは使えません)。
/dev/dc
に ioctl コマンドを
発行する事によって行なわれます。
実際のプログラムのテンプレートとしては、
以下のようなものになります。
#include <fcntl.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #include "camac.h" int fd , result ; .... fd = open ( "/dev/dc" , O_RDWR ) ; result = ioctl ( fd , DC_<func> , <arg> ); .... close ( fd ) ;DC_<func> に指定可能なシンボルは
"camac.h"
中で
定義されています。
各々のコマンドの機能と <arg> の説明を以下に示します。
DC_INITIAL と DC_I を例外として、
<arg> にはポインタを渡す事に注意してください。
*
<arg> に返します。
ビット 0 はステーションナンバー 1 のモジュールに対応します。
camac.h
の中で定義されている
DCCycle という構造型の変数です。
例えば
DCCycle dcc ; .... dcc.n = 8 ; dcc.a = 0 ; dcc.f = 16 ; dcc.data = 0xffff ; result = ioctl ( fd , DC_CYCLE , &dcc ) ;は
N=8
, A=0
に
0xFFFF
の値を書き込むオペレーションです。
戻り値は 0 (success) または -1 (failure) です。
"dc_int.c"
の中で
以下のシンボルを定義しておくと、
DC_INTON の中にちょっと便利な機能が付加されます。
F=26
(LAM Enable) を送出します。
N=OUTREG
に対し、
データ 0xFF00
を
F=16
で送出します。
多くの Output Register (海津、テクノランド製等) は
F=16
がレベル出力ですから、
トリガロジックやスケーラのゲートに用いる事ができます。
"dc_int.c"
の中で
以下のシンボルを定義しておくと、
DC_INTON と同様に便利な機能が付加されます。
F=24
(LAM Disable) を送出します。
N=OUTREG
に対し、
データ 0x0000
を F=16
で送出します。
(0xFFFF)
を書き込み、
データ待ちのプロセスが有ればフラッシュします。
データ書き込みプロセスにファイルクローズを合図するために使います。
<arg> は参照しません。
"dc_int.c"
という名前のファイルに記述してください。
デバイスドライバの make の際に自動的にインクルードされます。
実際には、実験のセットアップ毎に適当なファイル名
(例えば hogehoge.c
) を付け、
% ln -s hogehoge.c dc_int.cによってシンボリックリンクを張るのが便利でしょう。
割り込みルーチンでは、概ね以下の事柄を記述します。
"int_test.c"
というファイルを用意しましたので、
あまり内部に立ち入りたくないという人は、
その中の
#define COINREG 1 #define OUTREG 5 #define ADC1 6 #define LAM_N ADC1 #define LAM_A 0 ..... /* Data AcQuisition */ camacCcycle2(COINREG,0,2,&dc_evbuff[(dc_wp++)%EV_MAX],&stat); for (i=0;i<8;i++) camacCcycle2(ADC1,i,0,&dc_evbuff[(dc_wp++)%EV_MAX],&stat); ..... camacCcycle2(ADC1,0,9,0,&stat); /* clear module */辺りを書き換えて使うのが簡単です。 camacCcycle2 等のファンクションの類の説明は 次節を参照してください。 この例では、 先ずステーションナンバー1の Coincidence Register の値を読み込み、 次にステーションナンバー6にある ADC のサブアドレス0〜7のデータを 順次読み込んでバッファにストアします。 最後にモジュールをクリアしますが、 この例では
F=9
を使って個別にクリアしています。
camacCc()
によって
バスにクリア信号を送出する方法は処理が短時間で済みますが、
スケーラを使ったり Output Register のレベル出力を使っている場合には、
これらも一緒にクリアされてしまうので不適当です。
例題では更に、 イベントデータを以下のレコード形式に整えて バッファに書き込んでおり、 後述のデータ収集システムのサンプル に適合させています。
+--1--2--+------------------L-+---L+2-+ | EVTLEN | Contents | DELIM | +--------+--------------------+-------+EVTLEN はバイト単位のイベント長 (ここでは L+2)、 DELIM は区切り子
(0x8001)
です。
LAM_N および LAM_A のシンボルは割り込みルーチンでは使用されませんが、
これらを定義して make すると
DC_INTON 等の動作が便利に使えます
ので、OUTREG と合わせて宣言しておく事を薦めます。
"int_test.c"
の例題では、
Output Register の下位 8 ビットにのみ
パルスを出力 (上位はレベルで使うので) している事に注意してください。
以下は、自分でもっと便利なルーチンを書きたい、 或いは、通常と異なる凝った処理をしたいという人向けですので、 深入りしたくない方は読み飛ばしてください。
データ収集ルーチンとは言え、 Linux のような汎用 OS のデバイスドライバの一部を書くわけですから、 次のような一般的注意が考えられます。
例えば、 インテリジェント補助クレートコントローラ (ACC) で 割り込みを記述する場合には、 (Interrupt Register や ACC への直接のシグナル等によって) 出来るだけ早いタイミングで割り込みを発生させ、 割り込みルーチンの中では Q を見ながら ADC/TDC の変換終了を待って、 データ読み出しを行なうのが一般的と思います。 これは、データ収集の dead time を最小に抑えようとする配慮の結果ですが、 ACC が割り込み処理以外に重要な仕事をしていないからこそ 許される方法と言えます。
一方 Linux (を含む汎用 OS) では、 システムの他のサービスに対する遅延を防ぐために、 個々の割り込み処理を出来るだけ短時間に終了させたいという要請が有ります。 データ収集の効率は多少犠牲になりますが、 システム全体の有効な運用としては、 例えば以下のような方法が薦められます。
/var/adm/messages
となります
(ただし、カーネル 1.3.37 以降はコンソールに出力されるそうです)。
/var/adm/messages
への出力は
(万が一カーネルパニックが起こった時も最期の断末魔の記録を残すため)
バッファされません。
従って、頻繁に printk() を行なうとシステムの負荷が
グッと増える事に注意してください。
/var/adm/messages
の末尾部分は
dmesg によって出力する事ができます。
最後の注意は当たり前の事ですが、
/var/adm/messages
に“Oops”というメッセージ
とダンプ情報を残すだけで大事に至る事は少ないようです。
しかし用心に越した事はありません。
camack.c
で定義されている関数です。
dc_int.c
の最初で include しておくと便利です。
int camacCinitialize ()
int camacCz ()
int camacCc ()
int camacCi (int onoff)
long camacClamp ()
int camacClam ()
int camacCcycle
(int N, int A, int F, long *data, int *state)
int camacCcycle2
(int N, int A, int F, short *data, int *state)
/dev/dc
open(..., O_NONBLOCK)
で
実現する機能ですが、本ドライバではデバイスのマイナー番号で
機能を分離しており、
O_NONBLOCK
フラグはサポートしていません。
/dev/dc1
/dev/dc2
/dev/dc3
% cat /dev/dc1 > hogehoge.datで用が足ります。 UNIX のファイルシステムでは close 以前に他のプロセスからもアクセス可能 (VMS の shared open に相当) なので、 データ収集中に
hogehoge.dat
から
データを読み込んで解析する事もできます。
なお、バッファデータの一区切り (DC_INTCLR 実行から次の DC_INTCLR 実行までに収集されるデータ量) は、ポインタの都合上符合無し 32 ビットポインタで表される範囲に とどめておいてください (8 Gbytes のデータを区切り無しに 採る事はまず無いと思いますが)。
/dev/dc1
から読み込み、
ファイルに書いたり analyzer に渡したりします。
analyzer の処理が遅くデータ収集に追い付かない時は、
イベント単位で間引きを行ないます。
void hstdef_()
void hstend_()
void event1_(unsigned short data[])
SUBROUTINE HSTDEF
SUBROUTINE HSTEND
SUBROUTINE EVENT1(DATA)
INTEGER*2 DATA(*)
"event1.f"
を付けましたので参考にしてください。
"crashm.h"
に記述されています。
また、analyzer/recorder 間のデータ待ち/解除の制御はセマフォを
使っています。
いずれも常識的な方法ですが、詳しく知りたい人は
SystemV IPC (Inter-Process Communication) に
関する参考書を読んでください
(BSD のプロセス間通信の方法はこれと少し異なります…、
と教科書には書いてありますが、
実際は FreeBSD でも SunOS4 でも使えたります)。
上記のソースは、いずれも 1〜2 ページの極短いものなので、
このテの「お勉強」をしたい人にも適当かも知れません。
所謂オフライン解析のためのプログラムも用意しました。
サンプルシステムの実行形式の make は
% make DAQで行なわれます。 ただし analyzer に関しては、ユーザールーチンの記述 および使用するライブラリの問題がありますので、 Makefile を適当に修正する必要があるでしょう。
さて、 commander は最低限の機能しか持っていないので、 とても使い易いとは言えません (VMS 風のコマンドの省略ぐらいはサポートしていますが)。 そこで、Tcl/Tk による GUI の「皮」を被せて使い易さの向上を図ったのが "rei" というスクリプトです。
Tcl/Tk とはスクリプト言語 (インタープリタ) で、 近年では当たり前となったマウス操作による制御を 短いステップで書く事ができ、 速度の要求されない処理 (大抵の対話型処理はそうですが) の部分を 手っ取り早く記述するには便利です。 Tcl/Tk に関する詳細は適当な参考書を御覧ください。 ただし "rei" はバージョン 4.0 以降の Tk でしか動きませんが、 原典 (Tcl/Tk の作者自身による解説書) は 3.6 を対象にしているので 注意が必要です。 ちなみに "rei" というのは例題の rei ではなく、 火川神社の巫女さんの名前のつもりで付けました。
使用に際しては、"rei" の一行目に書かれている
#!/usr/bin/wishを、実際の Tk インタープリタの所在に換えてください。
% make wishを実行すれば自動的に書き換えられるはずです。 後は、このスクリプトをコマンドラインから直接起動すれば、 commander, recorder, analyzer がサブプロセスとして立ち上げられます。 "rei" の起動は、PATH 指定でも alias でもシンボリックリンクでも構いません。 ただし、commander, recorder, analyzer は "rei" と同じディレクトリに なければなりません。 また、起動時に
% rei offlineのように引数を与えれば、player が起動されます。
"rei" の実行画面は以下のようなものです。 使える機能は全てボタンに割り当てられていますので、 説明が無くても使い方はわかると期待します。 誤操作を防ぐために、 システムの状態 (データ収集中、ファイル書き込み中) に応じて 危険なボタンはグレーアウト (使用禁止) されます。 ボタンをマウスクリックする代わりに、 下線の引かれた文字と ALT キーを同時に押しても 同様の動作をします。
一秒毎に表示が更新される統計情報は以下の意味を持っています。
/dev/dc1
から読み出したイベントの個数です。
一回の Start/Stop サイクルでは Interrupt - Lost になると
期待されます。
スケーラ情報をイベントデータと同等に扱うのは難があるので (もちろん“スケーライベント”をハード的に作れば別ですが)、 システムの無垢な性格(?)を残すために、 デバイスドライバまで巻き込んで スケーラの扱いを支援する事は止めました。 が、実際上は不便な事も多かろうと思いまして、 このような形の支援を付け加えた次第です。
デフォルトではスケーラ情報の更新間隔は一秒となっていますが、起動時に
% rei 2000という形式でミリ秒単位の指定が可能です。
さて、 "rei" を eXit によって正常終了すると、 commander, recorder, analyzer のサブプロセスは自動的に消去され、 共有メモリおよびセマフォも削除されます。 しかし何らかの理由で異常終了した場合には、 サブプロセスが残っているため "rei" を再起動できなくなりますので、 ps によってプロセス状態を確認し、kill してください。 特にデータ収集の最中に異常終了した場合は 割り込みが発生し続けてしまいますから、 再起動により初期化を行なうのは重要です。 一方、共有メモリやセマフォは残っていても ("rei" を使い続ける限り) 特に害はありませんが、 状態の確認 (ipcs) や削除 (ipcrm) をしたい場合には、 次節の方法を参照してください。
先ず、ヒストグラミングを行なうプログラムでは、 通常の HLIMIT の代わりに HLIMAP を使います。
PARAMETER (NHOGE=10000) ...... CALL HLIMAP(NHOGE,'sample') CALL HBOOK1(1,'Hogehoge',100,0.,100.,0.) ......ソースをコンパイルし、
(lib)packlib.a
とリンクして実行すると
共有メモリが割り当てられます。
その状況は、
% ipcs -m ------ Shared Memory Segments -------- shmid owner perms bytes nattch status 1408 okamura 666 40000 0という具合に確認する事ができます。 次に、paw を起動して
PAW > hist/hio/global sample PAW > cdir Current Working Directory = //SAMPLE PAW > ldir 1 1D Hogehoge .......等とやれば、 共有メモリ上に定義されたヒストグラムが
//SAMPLE
としてアクセスできる事がわかります。
以降の作業は通常の //PAWC
に定義されたヒストグラムと同様です。
ところで、HBOOK は割り当てた共有メモリを解放する機能を
持っていないようです。
先程の例ですと (shmid
が 1408
でしたので)、
プログラム終了後に
% ipcrm shm 1408を実行して共有メモリを解放してください (少なくとも 95a-97a のソースを眺める限りでは、
HFREEM
が共有メモリ解放を意図したルーチンと思われるのですが、
肝心の部分 shmctl
がコメントアウトされているのです。何故…?)。
スイッチ | ビット | デフォルト | スイッチ | ビット | デフォルト |
---|---|---|---|---|---|
1-1 | [12] | ON | 2-1 | [ 7] | ON |
1-2 | [11] | ON | 2-2 | [ 6] | ON |
1-3 | [10] | ON | 2-3 | [ 5] | ON |
1-4 | [ 9] | OFF | 2-4 | [ 4] | OFF |
1-5 | [ 8] | OFF | 2-5 | [ 3] | ON |
0x310
(ベース) 〜 0x317
が使用されます。
スイッチ | デフォルト |
---|---|
3-1 | OFF |
3-2 | OFF |
3-3 | OFF |
3-4 | OFF |
3-5 | OFF |
スイッチ | デフォルト | 意味 |
---|---|---|
4-1 | ON | I/O ch ready WAIT |
4-2 | OFF | IRQ5 |
4-3 | OFF | IRQ10 |
4-4 | OFF | IRQ11 |
4-5 | OFF | IRQ12 |
割り込みを使用する場合には、SW 4 の 2〜5 のいずれかを ON にしておきます。 CC/7000 の SW-14 も ON にする必要があります。
言うまでも有りませんが、他のデバイスと競合しない
IRQ および I/O アドレスを使用してください。
PCI マシンの場合には、Plag & Play が該当 IRQ を使用しないように
ICU や BIOS で設定しておく必要があります。
Linux で使用している IRQ や I/O ポートは、
以下のコマンドで見る事ができます。
% cat /proc/interrupts % cat /proc/ioportsただし、Linux カーネルが使用していないデバイスについては、 この方法ではわかりません (例えばグラフィックスボードが IRQ を使用するタイプでも、 X サーバーがカーネルに申告しなければ表示されない) ので、 MS-DOS の MSD 等も使って確認してください (MSD も絶対信用できる わけではありませんが。 Windows95 が使える環境ならば、 デバイスマネージャで確認するのが最も簡単/確実です)。
図の意味はかなり自明と思いますが、幾つか捕捉します。
D1 の説明が不完全ですが、クレート番号 (0〜3) の選択に使います。 CC/7000 の最初のバージョンではシングルクレートのみのサポート だったので、D1 という如何にも後から付け足した事を暗示する ポートが使われています。
D7 の GO とは、 この I/O ポートへのアクセスによって 実際の CAMAC アクションが行なわれる事を意味します。 従って、それ以前に各パラメータをセットしなければなりません。
また、
16 ビットポートは 16 ビットアクセス
(outw
, inw
) でしか
入出力できません。
例えば、ファンクション (F) をセットするのに
outb(...,BASE+6)
を
用いるのは間違いです。
LSAM が点灯していない場合は、 LAM を発生させようとするモジュールに対して
を確認してください。
/dev/dc?
からリアルタイムで読み出せない
(データ収集をストップすると一気に読み出される) ?
/dev/dc?
からの読み出しは、
バッファが空である場合に wait 状態になります。
wait 状態の解除は kernel からの割り込みによって行われますが、
LAM による割り込みとの区別は、
LAM が立っているか否かで行われるからです。
/etc/Xaccel.ini
" (または相当するファイル) に
[SETTINGS] ……… BackingStore = YES;という記述を加える必要があります。 XFree86 の場合はデフォルトで BackingStore が有効になっているようです。 X Server によっては (例えば Windows95/NT 上の X エミュレータ等)、 BackingStore を有効にすると随分描画速度が落ちるものも有るので 注意が必要です。
"evnet1"
だけ
FORTRAN で書かれているか?