★で示したような記述を追加してしてみます。
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ではディレクトリ(ファイルではなく)の存在チェックと作成がアトミックに行えるようだ。
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ではディレクトリ(ファイルではなく)の存在チェックと作成がアトミックに行えるようだ。