From 471fdef61e39650a40faa0b4ee16ee8a3ea4f8cb Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Fri, 12 Jun 2009 00:34:33 +0200 Subject: [PATCH] Bug in communication techniques bench * producers can finish before consumer and thus free the thread-local storage they have which could lead to sigsegv from consumer --- communication_techniques/src/main.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/communication_techniques/src/main.c b/communication_techniques/src/main.c index bceb4a1..3c0ba16 100644 --- a/communication_techniques/src/main.c +++ b/communication_techniques/src/main.c @@ -20,6 +20,10 @@ static long nb_prod = 0; static long size_buf = 1; static char *calculation_lib = NULL; static int shared = 0; +pthread_cond_t cond_cons_has_finished = PTHREAD_COND_INITIALIZER; +pthread_mutex_t mutex_cons_has_finished = PTHREAD_MUTEX_INITIALIZER; +static int consumer_has_finished = 0; +static int producers_ended = 0; void usage(char *argv[]) { @@ -141,10 +145,12 @@ int analyse_options(int argc, char *argv[]) return 0; } -void *producer(void *unused) +void *producer(void *cont_ptr_void) { int i, j, k; + volatile int *cont; + cont = *((volatile int **) cont_ptr_void); if (shared) { pthread_t tid; @@ -173,7 +179,16 @@ void *producer(void *unused) } printf("[%p] Producer finished !\n", (void*) pthread_self()); remove_sender(); - /* Threads must wait the consumer because of thread-local storages */ + /* + * When a producer end its thread-local storage vanished. Thus, + * producers must finish only after consumer has stopped using them + */ + pthread_mutex_lock(&mutex_cons_has_finished); + if (++producers_ended == nb_prod) + *cont = 0; + if (!consumer_has_finished) + pthread_cond_wait(&cond_cons_has_finished, &mutex_cons_has_finished); + pthread_mutex_unlock(&mutex_cons_has_finished); return NULL; } @@ -199,6 +214,10 @@ void *receptor(void *a) } } reception(onMessage); + pthread_mutex_lock(&mutex_cons_has_finished); + consumer_has_finished = 1; + pthread_cond_broadcast(&cond_cons_has_finished); + pthread_mutex_unlock(&mutex_cons_has_finished); return NULL; } @@ -214,11 +233,10 @@ int main(int argc, char *argv[]) tid = (pthread_t *) malloc((nb_prod + 1) * sizeof(pthread_t)); cont = init_comm(); for(i = 0; i < nb_prod; i++) - pthread_create(&tid[i], NULL, producer, NULL); + pthread_create(&tid[i], NULL, producer, &cont); pthread_create(&tid[i], NULL, receptor, NULL); for(i = 0; i < nb_prod; i++) pthread_join(tid[i], &return_value); - *cont = 0; pthread_join(tid[i], &return_value); free(tid); return EXIT_SUCCESS;