C99に対応した標準Cライブラリの実装レポートを行っていきます。

プロフィール 

Author:高木信尚

ホームページ
ブログ

最近の記事 

最近のコメント 

最近のトラックバック 

月別アーカイブ 

カテゴリー 

ブロとも申請フォーム 

この人とブロともになる

ホーム 全記事一覧 << 前の記事 次の記事 >>

 

2008/10/07 11:42|

 

raise関数は、明示的にシグナルを発生させるための関数です。非同期シグナルに対する処理とは異なり、raise関数と、raise関数を内部的に呼び出すabort関数によって呼び出されたシグナル処理ルーチンは、そこで行うことができる処理にほとんど制約がありません。

非同期シグナルの場合、シグナル処理ルーチンの中で呼び出せる標準関数は、abort関数と_Exit関数、そして同じシグナルに対するsignal関数だけです。今回の実装では、非同期シグナルは、タスク例外処理ルーチンからraise関数を呼び出すことで実現しますが、非同期の場合はraise関数を使っていても上記の制約があるものとします。

つまり、タスク例外処理ルーチンを介して呼び出されたシグナル処理ルーチンからは、ほとんどの標準関数を呼び出すことができず、longjmp関数を用いて脱出することもできなくなります。

ところで、前回のsignal関数の回には、raise関数をsignal関数と同じ翻訳単位に入れることを想定していましたが、よく考えてみるとその必要はなさそうです。では、実装をご覧ください。

#include <kernel.h>
#include <signal.h>

int raise(int sig)
{
  void (*func)(int) = signal(sig, SIG_DFL);
  uintptr_t f = (uintptr_t)func;
  if (f <= 2) {
    switch (f) {
    case 0: // SIG_DFL
      ext_tsk();
      // break;
    case 1: // SIG_IGN
      break;
    default:
      return -1;
    }
  }
  else {
    (*func)(sig);
  }
  return 0;
}

今回の実装では、SIG_DFLの処理は、問答無用でタスク終了としています。最初からswitch文で処理を分けてもよかったのですが、ユーザー定義のシグナル処理ルーチンを最速の方法で呼び出すには、いったんユーザー定義のものが登録されているのか、SIG_DFLやSIG_IGNが登録されているのかを「ふるい」にかけた方が得策と考えて、このように実装してみました。
2006/05/22 03:15|シグナル処理TB:0CM:0

コメント
コメントの投稿

管理者にだけ表示を許可する


トラックバック
トラックバックURLはこちら
http://libc.blog47.fc2.com/tb.php/55-c26ce81f

ホーム 全記事一覧 << 前の記事 次の記事 >>

ブログ内検索 

お勧め書籍 

RSSフィード 

リンク 

このブログをリンクに追加する

Powered By FC2ブログ 

Powered By FC2ブログ
ブログやるならFC2ブログ

Copyright(C) 2006 TAKAGI Nobuhisa All rights reserved.
Powered by FC2ブログ. 無料ホームページ アフィリエイト レンタルサーバー FC2ブログ 一戸建て template designed by 遥かなるわらしべ長者への挑戦.