★で示したような記述を追加してしてみます。

void log_output(char* message)
{
..static char buf[256];
..time_t t;

..time(&t);

★..INTR_DISABLE;

..strcpy(buf,ctime(&t));
..strcpy(buf+strlen(buf),message);

..puts(buf);

★..INTR_ENABLE;
}

★INTR_DISABLEからINTR_ENABLEは割込み禁止区間を示しています。
割込み禁止中に発生した割り込みは保留され、割込み有効化された瞬間に割込みが発生します。
これを割込みの遅延または遅延割込みというとのこと。

一般には「割込み処理は短く」「割込み禁止は最小に」が鉄則。
リアルタイム性を維持するためというのがよい見方かと思います。

ちなみに割込み禁止区間を示す命令は以下のような記述になります。

#define INTR_ENABLE asm volatile ("andc.b #0x3f,ccr")
#define INTR_DISABLE asm volatile ("orc.b #0xc0,ccr")
①プロセス化
「メモリ」という資源を複数のスレッドが共通資源として扱っている点に問題があるわけですが、タスク毎に独立した仮想的なメモリ空間を割り当て、まるでそのコンピュータのメモリ上には自分しか存在しないかのように振舞えばよいわけです。

それを実現するのが仮想メモリでMMUという専用ハードウェアを使用します。仮想メモリにより動作するアドレス空間が独立しているタスクをプロセスと呼びます。


②OS化
カーネル内部の処理中には割込み禁止になっています(KOZOSではそのようです。CCRのIbitが立てられ割込み禁止になります。が、他のOSでは一般的なことなのか知りません)。その特徴を利用してサービスをカーネルで実現するということで再入を防ぐことができるようです。

しかし、OSのカーネル肥大化、ポリシーのないカーネルになりあまりよくないとのこと。


③リエントラント化
グローバル変数やstatic変数をみんな自動変数にしてスタック領域を利用するようにしようというところです。なんか一番いいような気がします。

注意すべきは関数中で使用される関数の中でもスタック領域を使用しているよう関数設計時から明確に方向性を示しておく必要があります。
mallocってシステムコールによってカーネルがメモリを確保してくれるわけで、なんでそれをシステムコールでわざわざ実施するかというとスレッドの排他の問題を解決するためというのはあるよなぁ。

でもよくよく考えるとシステム・タスクでもよいわけで。

なんでmallocはシステム・タスクでなくカーネルなのか知りたくなってきた。
リアルタイム性を確保しているからだけだろうか?




それと誰かに聞いて忘れてしまったのだが、mallocってプロセス間のに対応していたっけなぁ。
恐らくプロセスごとに独立していたような。

要はMMUがからむとカーネルの動きはどのように振舞うのかということなのだけど。
プロセス間でメモリを共有したいときは共有メモリという別のキーワードがでてくるわけだが、mallocの動きと共有メモリの振る舞いってどのような違いがあるのだろう。