|
|
|
| 2008/10/07 11:49||▲
|
|
|
atexit関数は、終了時に呼び出される処理を登録するための関数です。この関数を実装するには、組み込みでは扱われることが少ない、プログラムの終了について、少し突っ込んで検討する必要があります。
TOPPERS/JSPカーネルでは、atexit関数で登録した処理を呼び出すために、call_atexit関数というのをターゲット依存部で定義することになっています。この関数が何を行うかというと、内部でsoftware_term_hookを呼び出しています。
atexit関数を使用する場合、software_term_hookは、atexit関数で登録した処理を後入れ先出しで実行するように記述してやる必要があります。
#define ATEXIT_MAX (32 + 1)
static void (*atexit_table[ATEXIT_MAX])(void); static int atexit_num;
void software_term_hook(void) { int i;
for (i = atexit_num - 1; i >= 0; i--) (*atexit_table[i])(); }
実際には、software_term_hook関数では、上記の処理だけでなく、標準ストリームのクローズ処理を行う必要があるのですが、これについては、<stdio.h>ヘッダを実装する際に先送りすることにします。
ところで、atexit関数で登録可能な最大の数は、少なくとも32関数です。ここでは、32+1とすることで、1関数余分に登録できるようにしています。これは、C++を使ったときに、静的オブジェクトのデストラクタを呼び出すためのものです。
それでは、atexit関数の本体の実装を示します。
#include <kernel.h>
int atexit(void (*func)(void)) { int result = -1; _Bool sync = !vsns_ini();
if (sync) loc_cpu();
if (atexit_num < ATEXIT_MAX) { atexit_table[atexit_num++] = func; result = 0; }
if (sync) unl_cpu();
return result; }
排他制御にはloc_cpuを使用していますが、サービスコールを呼び出すことができるのは、カーネルが動作しているときだけですので、カーネルの動作状態をvsns_iniであらかじめ調べています。カーネルが動いていないときは、排他制御の必要はありませんので、そのまま配列を操作しています。
|
| 2006/06/02 00:20|一般ユーティリティ|TB:0|CM:0|▲
|
|
|
コメント
|
|
コメントの投稿
|
|
|
|
|
トラックバック
|
トラックバックURLはこちら
http://libc.blog47.fc2.com/tb.php/63-4791d501
|
|
|
|
|
ホーム
全記事一覧
<< 前の記事
次の記事 >>
|