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
This commit is contained in:
Thomas Preud'homme 2009-06-12 00:34:33 +02:00 committed by Thomas Preud'homme
parent e6912c4048
commit 471fdef61e
1 changed files with 22 additions and 4 deletions

View File

@ -20,6 +20,10 @@ static long nb_prod = 0;
static long size_buf = 1; static long size_buf = 1;
static char *calculation_lib = NULL; static char *calculation_lib = NULL;
static int shared = 0; 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[]) void usage(char *argv[])
{ {
@ -141,10 +145,12 @@ int analyse_options(int argc, char *argv[])
return 0; return 0;
} }
void *producer(void *unused) void *producer(void *cont_ptr_void)
{ {
int i, j, k; int i, j, k;
volatile int *cont;
cont = *((volatile int **) cont_ptr_void);
if (shared) if (shared)
{ {
pthread_t tid; pthread_t tid;
@ -173,7 +179,16 @@ void *producer(void *unused)
} }
printf("[%p] Producer finished !\n", (void*) pthread_self()); printf("[%p] Producer finished !\n", (void*) pthread_self());
remove_sender(); 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; return NULL;
} }
@ -199,6 +214,10 @@ void *receptor(void *a)
} }
} }
reception(onMessage); 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; return NULL;
} }
@ -214,11 +233,10 @@ int main(int argc, char *argv[])
tid = (pthread_t *) malloc((nb_prod + 1) * sizeof(pthread_t)); tid = (pthread_t *) malloc((nb_prod + 1) * sizeof(pthread_t));
cont = init_comm(); cont = init_comm();
for(i = 0; i < nb_prod; i++) 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); pthread_create(&tid[i], NULL, receptor, NULL);
for(i = 0; i < nb_prod; i++) for(i = 0; i < nb_prod; i++)
pthread_join(tid[i], &return_value); pthread_join(tid[i], &return_value);
*cont = 0;
pthread_join(tid[i], &return_value); pthread_join(tid[i], &return_value);
free(tid); free(tid);
return EXIT_SUCCESS; return EXIT_SUCCESS;