シグナルの使い方

本文

SSS-PCのシステムコールを直につかったサンプルを書こうと思ったのですが、 UNIX互換libcを使っているなら、通常のsignal()等の関数を お使いになられるのが便利です。 この場合は、SIGUSR1かSIGUSR2を使うことになりますが、 これらが他の用途で埋まっていると元のコードを少し変更する 必要があります。

互換ライブラリを使っていない場合は、 以下のような感じでsiganlの関数を登録してください。

void
signal_dispatch(interrupt,sw_f)
int	interrupt;
int	sw_f;
{
   int pattern;

   printf("interrupt=0x%x\n",interrupt);
   if (interrupt & TASK_SIGALRM) {
   	printf("SIGALRM catched!!\n");
	/* SIGALRM 処理 */
   }
   if (interrupt & TASK_SIGLIBC) {
   	printf("SIGLIBC catched!!\n");
	pattern = self_getparam(TASK_GETPARAM_SIGLIBC_VALUE_CLR);
	/* SIGLIBC 処理 */
   }
   clear_signal_blkmask(0xffffffff);
   return;
}

main()
{
   set_signal_func(signal_dispatch);
   set_signal_event(0xffffffff);
   clear_signal_blkmask(0xffffffff);
   for(;;)
       self_sleep(100);
}

発生したsignalはsignal_dispatch()の第一引数である interruptのビットパタンで表します。 例えば、

SIGHUP: 1 (TASK_SIGHUP)
SIGALRM: 0x2000 (TASK_SIGALRM)

です。 複数の要因が同時にセットされる場合もあります。

signal_blkmaskはsigmaskに相当して、

clear_signal_blkmask(0xffffffff);

はすべてのシグナル要因で割り込みを受け付けることを意味します。

set_signal_blkmask(0xffffffff);

なら、すべてのシグナル要因をブロックすることを意味します。

set_signal_event(0xffffffff);

はUNIXにはない仕様ですが、使用するsignal要因をセットします。 ここで1がセットされていないsignal要因は使用されません (ブロックではないのでシグナルが発生したことも忘れます)。

シグナルを発生させるには、

       send_task_signal(taskID,sig_pattern);

を使うか、nikomonコマンドで

:-) signal -send <taskID> <sig_pattern>

と打ってください。

ただし、現在農工大に出荷しているバージョンでは、 同じnikomonシェルから起動されていないタスク間には このUNIXライクsignalは飛ばせない仕様になってます。 最新版では権限がrootであれば、違うnikomonシェルを 親に持っていても、飛ばせることになっています。

set_signal_func()でユーザがsignal処理関数を登録してしまうと、 UNIX互換ライブラリが設定したsignal処理関数が無効になって しまうため、signalに関するUNIX互換性はなくなります。

TASK_SIGLIBC 0x80000000  /* special signal for u-libc, siglibc_value */

というのが拡張としてもうけられていて、 interruptのビットパタンが0x80000000 だった場合には、

	pattern = self_getparam(TASK_GETPARAM_SIGLIBC_VALUE_CLR);

でもう一つintのベクタを取り出すことができます。 SIGLIBCのsignalは

send_libc_signal(task,sig_pattern)

:-) signal -sendlibc <taskID> <sig_pattern>

で発生させられます。

UNIXライクsignalにはもう一つ拡張があって、 それが前回のメールに添付したsgid=1に相当する signalです。 こちらはUNIX互換libcではまだ使っていないので、 UNIX互換libcと両立できる可能性があります。

set_signal_event_ex(pattern,sgid) /* 1が立ったbitに相当するsignalが使用可能になる */
set_signal_blkmask_ex(pattern,sgid) /* 1が立ったbitに相当するsignalがblockされる */
void(*set_signal_func_ex(func,sgid))()
clear_signal_blkmask_ex(pattern,sgid) /* 1が立ったbitに相当するsignalがunblockされる */
send_task_signal_ex(task,sig_pattern,sgid)

で使用できます。

sgid=0の場合は最初に説明したUNIXライクsignalと同じ物です。

sgid=1のケースも割り込み要因はシステムでほとんど埋まっていて、 ビット30,ビット31ぐらいを使っていただけるとありがたいです。 ssscore.hにSIGTASKQ0とかいった定数ででているものが割り込み要因で、 主にMBCF関係のユーザプログラムの非同期呼び出しに使います。 ユーザプログラム内で明示的に使用するように設定しなければ これらの割り込み要因は発生しませんが、トラブルを避けるためには なるべく用途が決まったビットは使用しない方がよいでしょう。

参考情報

Subject: [Fwd: Re: ちょっと質問です]

Date: Mon, 26 Sep 2005 17:58:28 +0900

Lab/SSS-PC


トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS