Supongamos que tenemos el siguiente fragmento de código:¿Puede un compilador C/C++ almacenar en caché legalmente una variable en un registro a través de una llamada de biblioteca pthread?
#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");
}
Puede un C compatible con los estándares/C++ siempre almacenar en caché el valor de do_shutdown
en un registro a través de la llamada a pthread_cond_wait()
? Si no, ¿qué normas/cláusulas garantizan esto?
El compilador podría hipotéticamente saber que pthread_cond_wait()
no modifica do_shutdown
. Esto parece bastante improbable, pero no conozco ningún estándar que lo impida.
En la práctica, ¿los compiladores C/C++ guardan en caché el valor de do_shutdown
en un registro a través de la llamada al pthread_cond_wait()
?
¿Qué función llama es el compilador garantizado para no almacenar en caché el valor de do_shutdown
a través? Está claro que si la función se declara externamente y el compilador no puede acceder a su definición, no debe hacer suposiciones sobre su comportamiento, por lo que no puede probar que no tiene acceso al do_shutdown
. Si el compilador puede alinear la función y demostrar que no tiene acceso al do_shutdown
, ¿puede caché do_shutdown
incluso en una configuración multiproceso? ¿Qué pasa con una función no en línea en la misma unidad de compilación?
Sí, pero puede hacerlo si, y solo si no hay manera legítima de que la función de la biblioteca pueda cambiar el valor de la variable (por ejemplo, si es una variable automática y su dirección nunca se toma). –
@R: corregir ... y en ese caso, es seguro hacerlo, ya que ningún otro hilo podría estar usando esa variable tampoco. –