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

プロフィール 

Author:高木信尚

ホームページ
ブログ

最近の記事 

最近のコメント 

最近のトラックバック 

月別アーカイブ 

カテゴリー 

ブロとも申請フォーム 

この人とブロともになる

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

 

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:0CM:0

コメント
コメントの投稿

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


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

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

ブログ内検索 

お勧め書籍 

RSSフィード 

リンク 

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

Powered By FC2ブログ 

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

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