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 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;