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:
parent
e6912c4048
commit
471fdef61e
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue