次のコードがあるとします。
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
void guarantee(bool cond, const char *msg) {
if (!cond) {
fprintf(stderr, "%s", msg);
exit(1);
}
}
bool do_shutdown = false; // Not volatile!
pthread_cond_t shutdown_cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t shutdown_cond_mutex = PTHREAD_MUTEX_INITIALIZER;
/* Called in Thread 1. Intended behavior is to block until
trigger_shutdown() is called. */
void wait_for_shutdown_signal() {
int res;
res = pthread_mutex_lock(&shutdown_cond_mutex);
guarantee(res == 0, "Could not lock shutdown cond mutex");
while (!do_shutdown) { // while loop guards against spurious wakeups
res = pthread_cond_wait(&shutdown_cond, &shutdown_cond_mutex);
guarantee(res == 0, "Could not wait for shutdown cond");
}
res = pthread_mutex_unlock(&shutdown_cond_mutex);
guarantee(res == 0, "Could not unlock shutdown cond mutex");
}
/* Called in Thread 2. */
void trigger_shutdown() {
int res;
res = pthread_mutex_lock(&shutdown_cond_mutex);
guarantee(res == 0, "Could not lock shutdown cond mutex");
do_shutdown = true;
res = pthread_cond_signal(&shutdown_cond);
guarantee(res == 0, "Could not signal shutdown cond");
res = pthread_mutex_unlock(&shutdown_cond_mutex);
guarantee(res == 0, "Could not unlock shutdown cond mutex");
}
標準準拠の C/C++ コンパイラはdo_shutdown
、 への呼び出し全体で の値をレジスタにキャッシュできpthread_cond_wait()
ますか? そうでない場合、どの基準/条項がこれを保証していますか?
pthread_cond_wait()
コンパイラは、が を変更しないことを仮説的に知ることができdo_shutdown
ます。これはかなりありそうにないように思えますが、それを防止する標準を私は知りません。
実際には、C/C++ コンパイラdo_shutdown
は の呼び出し全体で の値をレジスタにキャッシュしますpthread_cond_wait()
か?
do_shutdown
コンパイラーがacrossの値をキャッシュしないことが保証されている関数呼び出しはどれですか? 関数が外部で宣言されていて、コンパイラがその定義にアクセスできない場合、コンパイラはその動作について何も仮定してはならないため、アクセスしないことを証明できないことは明らかですdo_shutdown
。コンパイラが関数をインライン化し、アクセスしないことを証明できる場合、マルチスレッド設定でもdo_shutdown
キャッシュできますか? do_shutdown
同じコンパイル単位内のインライン化されていない関数はどうですか?