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

void log_output(char* message)
{
..static char buf[256];
..time_t t;
★..volatile static int locked=0;

..time(&t);

★..while(locked){
★....sleep(1);
★..}
★..locked=1;

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

..puts(buf);

★..locked=0;
}

ロックをかけるということを実施しています。
でもこれだと駄目。。

locked=0になりwhile(locked)を抜けたタイミングでスレッドが切り替わるとする。
locked=1は実行されていない状態。

切り替わったスレッドでもlog_output関数を実施した場合while(locked)を抜けた状態になったとする。
そうすると複数のタスクでstrcpy関数を実施しbuf[]を編集することになるわけだ。
そうなるとlockedが機能していないことになる。
lockedを参照してlocked=1をアトミックに行えないといけないということがわかる。
そのような動作を1命令で実施してくれるCPUがあるのだがこのような命令をTAS命令(TestAndSet)と呼ぶということだ。
似た処理でUNIX系OSではディレクトリ(ファイルではなく)の存在チェックと作成がアトミックに行えるようだ。