From 8f0aecedec098053775c1d95daa3898077dbc8b7 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Wed, 24 Jun 2009 22:25:28 +0200 Subject: [PATCH] comtechs bench: Better management of errors --- .../include/asm_cache_comm.h | 3 +- .../include/c_cache_comm.h | 3 +- communication_techniques/include/commtech.h | 4 +- communication_techniques/include/fake_comm.h | 3 +- .../include/jikes_barrier_comm.h | 3 +- communication_techniques/include/pipe_comm.h | 3 +- .../include/shared_mem_comm.h | 3 +- .../include/shared_mem_opt_comm.h | 3 +- .../src/calculation/calc_mat.c | 18 ++++- .../src/communication/asm_cache.c | 8 +- .../src/communication/c_cache.c | 8 +- .../src/communication/common.c | 35 +++++--- .../src/communication/fake.c | 8 +- .../src/communication/jikes_barrier.c | 13 ++- .../src/communication/pipe.c | 8 +- .../src/communication/shared_mem.c | 8 +- .../src/communication/shared_mem_opt.c | 8 +- communication_techniques/src/main.c | 81 ++++++++++++++----- 18 files changed, 171 insertions(+), 49 deletions(-) diff --git a/communication_techniques/include/asm_cache_comm.h b/communication_techniques/include/asm_cache_comm.h index d6b7c95..19a75ca 100644 --- a/communication_techniques/include/asm_cache_comm.h +++ b/communication_techniques/include/asm_cache_comm.h @@ -27,7 +27,8 @@ struct thread_comm extern struct thread_comm *tcomms; extern int swap_buffer; -void init_thread_comm(struct thread_comm *); +int init_thread_comm(struct thread_comm *); +int end_thread_comm(void); static inline void send(void **addr) { asm volatile("mov %%gs:channel@NTPOFF + 2 *" toString(BUF_SIZE) " + " toString(CACHE_LINE_SIZE) ", %%eax\n\t" diff --git a/communication_techniques/include/c_cache_comm.h b/communication_techniques/include/c_cache_comm.h index 49d39af..c11ce07 100644 --- a/communication_techniques/include/c_cache_comm.h +++ b/communication_techniques/include/c_cache_comm.h @@ -26,7 +26,8 @@ extern __thread struct comm_channel channel; __BEGIN_DECLS -void init_thread_comm(struct thread_comm *); +int init_thread_comm(struct thread_comm *); +int end_thread_comm(void); static inline void send(void **addr) { channel.buf[channel.idx++] = addr; diff --git a/communication_techniques/include/commtech.h b/communication_techniques/include/commtech.h index 539c977..f0deb87 100644 --- a/communication_techniques/include/commtech.h +++ b/communication_techniques/include/commtech.h @@ -13,7 +13,9 @@ extern long nb_prod; __BEGIN_DECLS int init_library(void); -void init_producer_thread(void); +int end_library(void); +int init_producer_thread(void); +int end_producer_thread(void); void reception(void (*)(void *)); __END_DECLS diff --git a/communication_techniques/include/fake_comm.h b/communication_techniques/include/fake_comm.h index fad7f07..b0d85a6 100644 --- a/communication_techniques/include/fake_comm.h +++ b/communication_techniques/include/fake_comm.h @@ -12,7 +12,8 @@ extern struct thread_comm *tcomms; __BEGIN_DECLS -void init_thread_comm(struct thread_comm *); +int init_thread_comm(struct thread_comm *); +int end_thread_comm(void); static inline void send(void **addr) { static __thread void **store_var = NULL; store_var = addr; diff --git a/communication_techniques/include/jikes_barrier_comm.h b/communication_techniques/include/jikes_barrier_comm.h index 4cf541d..803482d 100644 --- a/communication_techniques/include/jikes_barrier_comm.h +++ b/communication_techniques/include/jikes_barrier_comm.h @@ -15,7 +15,8 @@ extern struct thread_comm *tcomms; __BEGIN_DECLS -void init_thread_comm(struct thread_comm *); +int init_thread_comm(struct thread_comm *); +int end_thread_comm(void); void insert(void *); static inline void send(void **addr) { diff --git a/communication_techniques/include/pipe_comm.h b/communication_techniques/include/pipe_comm.h index 620000a..f5e4150 100644 --- a/communication_techniques/include/pipe_comm.h +++ b/communication_techniques/include/pipe_comm.h @@ -16,7 +16,8 @@ __BEGIN_DECLS extern __thread int pipefd[]; extern struct thread_comm *tcomms; -void init_thread_comm(struct thread_comm *); +int init_thread_comm(struct thread_comm *); +int end_thread_comm(void); static inline void send(void **addr) { write(pipefd[WRITE_IDX], &addr, sizeof(void *)); } diff --git a/communication_techniques/include/shared_mem_comm.h b/communication_techniques/include/shared_mem_comm.h index f9d4214..0bee7d7 100644 --- a/communication_techniques/include/shared_mem_comm.h +++ b/communication_techniques/include/shared_mem_comm.h @@ -22,7 +22,8 @@ extern __thread volatile void **shared_space; extern __thread volatile int prod_idx; extern __thread volatile int cons_idx; -void init_thread_comm(struct thread_comm *); +int init_thread_comm(struct thread_comm *); +int end_thread_comm(void); static inline void send(void **addr) { while ((prod_idx + 1) % SHARED_SPACE_VOIDPTR == cons_idx); shared_space[prod_idx] = addr; diff --git a/communication_techniques/include/shared_mem_opt_comm.h b/communication_techniques/include/shared_mem_opt_comm.h index 6126004..5184c73 100644 --- a/communication_techniques/include/shared_mem_opt_comm.h +++ b/communication_techniques/include/shared_mem_opt_comm.h @@ -22,7 +22,8 @@ extern __thread volatile void **shared_space; extern __thread volatile int prod_idx; extern __thread volatile int cons_idx; -void init_thread_comm(struct thread_comm *); +int init_thread_comm(struct thread_comm *); +int end_thread_comm(void); static inline void send(void **addr) { static __thread int local_cons_idx = 0; diff --git a/communication_techniques/src/calculation/calc_mat.c b/communication_techniques/src/calculation/calc_mat.c index 149c7e5..f3044de 100644 --- a/communication_techniques/src/calculation/calc_mat.c +++ b/communication_techniques/src/calculation/calc_mat.c @@ -1,4 +1,5 @@ #include +#include #define likely(x) __builtin_expect(!!(x), 1) @@ -9,7 +10,7 @@ static int *mat, *vect; static int li; static int n, m; /* Size of the matrice: n lines, m columns */ -void init_calc(int size) +int init_calc(int size) { int i; @@ -17,10 +18,22 @@ void init_calc(int size) m = size; srand(42); mat = (int *) malloc(n * m * sizeof(int)); + if (mat == NULL) + { + fprintf(stderr, "calc_mat: Unable to allocate memory for matrice calculation\n"); + return -1; + } vect = (int *) malloc(m * sizeof(int)); + if (vect == NULL) + { + free(mat); + fprintf(stderr, "calc_mat: Unable to allocate memory for matrice calculation\n"); + return -1; + } for (i = 0; i < n * m; i++) mat[i] = rand(); li = 0; + return 0; } void *do_calc(void) @@ -35,8 +48,9 @@ void *do_calc(void) return &mat[li * m]; } -void end_calc(void) +int end_calc(void) { free(mat); free(vect); + return 0; } diff --git a/communication_techniques/src/communication/asm_cache.c b/communication_techniques/src/communication/asm_cache.c index bf4589a..4a49dad 100644 --- a/communication_techniques/src/communication/asm_cache.c +++ b/communication_techniques/src/communication/asm_cache.c @@ -10,12 +10,18 @@ __thread struct comm_channel channel; -void init_thread_comm(struct thread_comm *comm) +int init_thread_comm(struct thread_comm *comm) { comm->receiver_idx = 0; comm->channel = &channel; comm->channel->state = 0; comm->channel->idx = 0; + return 0; +} + +int end_thread_comm(void) +{ + return 0; } char *dstr="buffer transition\n"; diff --git a/communication_techniques/src/communication/c_cache.c b/communication_techniques/src/communication/c_cache.c index 42f081d..b310595 100644 --- a/communication_techniques/src/communication/c_cache.c +++ b/communication_techniques/src/communication/c_cache.c @@ -10,12 +10,18 @@ __thread struct comm_channel channel; -void init_thread_comm(struct thread_comm *comm) +int init_thread_comm(struct thread_comm *comm) { comm->receiver_idx = 0; comm->channel = &channel; comm->channel->state = 0; comm->channel->idx = 0; + return 0; +} + +int end_thread_comm(void) +{ + return 0; } char *dstr="buffer transition\n"; diff --git a/communication_techniques/src/communication/common.c b/communication_techniques/src/communication/common.c index e7a7cca..4c4e39d 100644 --- a/communication_techniques/src/communication/common.c +++ b/communication_techniques/src/communication/common.c @@ -11,6 +11,7 @@ struct thread_comm *tcomms; volatile int cont = 1; static int init = 0; +static int error = 0; static pthread_mutex_t init_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t init_cond = PTHREAD_COND_INITIALIZER; @@ -25,6 +26,12 @@ int init_library(void) return 0; } +int end_library(void) +{ + free(tcomms); + return 0; +} + int get_thread_number(void) { static int i = 0; @@ -38,27 +45,35 @@ int get_thread_number(void) return i_local; } -void init_producer_thread(void) +int init_producer_thread(void) { - static int i = 0; - static pthread_mutex_t i_lock = PTHREAD_MUTEX_INITIALIZER; int i_local; - pthread_mutex_lock(&i_lock); - i_local = i; - i++; - pthread_mutex_unlock(&i_lock); - init_thread_comm(&tcomms[i_local]); + i_local = get_thread_number(); + if (init_thread_comm(&tcomms[i_local])) + { + error = 1; + return -1; + } pthread_mutex_lock(&init_lock); init = 1; pthread_cond_signal(&init_cond); pthread_mutex_unlock(&init_lock); + return 0; } -void wait_initialization(void) +int end_producer_thread(void) +{ + return end_thread_comm(); +} + +int wait_initialization(void) { pthread_mutex_lock(&init_lock); - if (!init) + if (!init && !error) pthread_cond_wait(&init_cond, &init_lock); pthread_mutex_unlock(&init_lock); + if (error) + return -1; + return 0; } diff --git a/communication_techniques/src/communication/fake.c b/communication_techniques/src/communication/fake.c index 68792f5..c92192c 100644 --- a/communication_techniques/src/communication/fake.c +++ b/communication_techniques/src/communication/fake.c @@ -9,8 +9,14 @@ #include -void init_thread_comm(struct thread_comm *comm) +int init_thread_comm(struct thread_comm *comm) { + return 0; +} + +int end_thread_comm(void) +{ + return 0; } void reception(void (*on_receive)(void *)) diff --git a/communication_techniques/src/communication/jikes_barrier.c b/communication_techniques/src/communication/jikes_barrier.c index e232797..0df0aea 100644 --- a/communication_techniques/src/communication/jikes_barrier.c +++ b/communication_techniques/src/communication/jikes_barrier.c @@ -33,14 +33,25 @@ static struct double_linked_list *global_head = NULL; static int bufsenqueued = 0; static unsigned int lock = 0; -void init_thread_comm(struct thread_comm *comm) +int init_thread_comm(struct thread_comm *comm) { void **new_buffer; new_buffer = (void **) malloc(BUFFER_SIZE); + if (new_buffer == NULL) + { + fprintf(stderr, "Failed to allocate a new buffer for the thread\n"); + return -1; + } local_tail = new_buffer + (USABLE_BUFFER_BYTES - BYTES_IN_ADDRESS - (USABLE_BUFFER_BYTES % (1 << LOG_BYTES_IN_ADDRESS))) + BYTES_IN_ADDRESS; // The second parenthesis is equal to 0 local_tail_buffer_end = local_tail; + return 0; +} + +int end_thread_comm(void) +{ + return 0; } void set_next(struct double_linked_list *list, struct double_linked_list *next) diff --git a/communication_techniques/src/communication/pipe.c b/communication_techniques/src/communication/pipe.c index dbec091..6172b79 100644 --- a/communication_techniques/src/communication/pipe.c +++ b/communication_techniques/src/communication/pipe.c @@ -13,7 +13,7 @@ __thread int pipefd[2]; -void init_thread_comm(struct thread_comm *comm) +int init_thread_comm(struct thread_comm *comm) { int flags; @@ -21,6 +21,12 @@ void init_thread_comm(struct thread_comm *comm) flags = fcntl(pipefd[READ_IDX], F_GETFL); fcntl(pipefd[READ_IDX], F_SETFL, flags | O_NONBLOCK); comm->pipefd = pipefd; + return 0; +} + +int end_thread_comm(void) +{ + return 0; } void reception(void (*on_receive)(void *)) diff --git a/communication_techniques/src/communication/shared_mem.c b/communication_techniques/src/communication/shared_mem.c index 0487236..d0a13b3 100644 --- a/communication_techniques/src/communication/shared_mem.c +++ b/communication_techniques/src/communication/shared_mem.c @@ -13,12 +13,18 @@ __thread volatile void **shared_space; __thread volatile int cons_idx = 0; __thread volatile int prod_idx = 0; -void init_thread_comm(struct thread_comm *comm) +int init_thread_comm(struct thread_comm *comm) { shared_space = (volatile void **) malloc(SHARED_SPACE_SIZE); comm->shared_space = shared_space; comm->cons_idx = &cons_idx; comm->prod_idx = &prod_idx; + return 0; +} + +int end_thread_comm(void) +{ + return 0; } void reception(void (*on_receive)(void *)) diff --git a/communication_techniques/src/communication/shared_mem_opt.c b/communication_techniques/src/communication/shared_mem_opt.c index 127e556..0be430a 100644 --- a/communication_techniques/src/communication/shared_mem_opt.c +++ b/communication_techniques/src/communication/shared_mem_opt.c @@ -13,12 +13,18 @@ __thread volatile void **shared_space; __thread volatile int cons_idx = 0; __thread volatile int prod_idx = 0; -void init_thread_comm(struct thread_comm *comm) +int init_thread_comm(struct thread_comm *comm) { shared_space = (volatile void **) malloc(SHARED_SPACE_SIZE); comm->shared_space = shared_space; comm->cons_idx = &cons_idx; comm->prod_idx = &prod_idx; + return 0; +} + +int end_thread_comm(void) +{ + return 0; } void reception(void (*on_receive)(void *)) diff --git a/communication_techniques/src/main.c b/communication_techniques/src/main.c index ff491f6..7a7bc8e 100644 --- a/communication_techniques/src/main.c +++ b/communication_techniques/src/main.c @@ -29,9 +29,9 @@ static long nb_bufs_sent = 0; long nb_prod = 0; -static void (*init_calc)(int) = NULL; +static int (*init_calc)(int) = NULL; static void *(*do_calc)(void) = NULL; -static void (*end_calc)(void) = NULL; +static int (*end_calc)(void) = 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; @@ -55,8 +55,9 @@ void usage(char *argv[]) printf("%s\n", options); } -void do_noinit(int unused) +int do_noinit(int unused) { + return 0; } void *do_nocalc(void) @@ -66,8 +67,9 @@ void *do_nocalc(void) return &an_int; } -void do_noend(void) +int do_noend(void) { + return 0; } int analyse_options(int argc, char *argv[]) @@ -179,12 +181,27 @@ int analyse_options(int argc, char *argv[]) return 0; } +void wait_consumer(void) +{ + 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); +} + void *producer(void *unused) { int i, j; struct timeval tv1, tv2, tv_result; - init_producer_thread(); + if (init_producer_thread()) + { + fprintf(stderr, "Initialization of thread has failed\n"); + wait_consumer(); + return &nb_prod; /* &nb_prod can't be NULL, whatever NULL is bound to */ + } if (shared) { pthread_t tid; @@ -196,7 +213,8 @@ void *producer(void *unused) if (pthread_setaffinity_np(tid, sizeof(cpu_set_t), &cpuset)) { perror("pthread_setaffinity_np"); - return NULL; + wait_consumer(); + return &nb_prod; /* &nb_prod can't be NULL, whatever NULL is bound to */ } } else @@ -210,10 +228,16 @@ void *producer(void *unused) if (pthread_setaffinity_np(tid, sizeof(cpu_set_t), &cpuset)) { perror("pthread_setaffinity_np"); - return NULL; + wait_consumer(); + return &nb_prod; /* &nb_prod can't be NULL, whatever NULL is bound to */ } } - init_calc(INIT_CALC_ARG); + if (init_calc(INIT_CALC_ARG)) + { + fprintf(stderr, "Initialization of calculation has failed\n"); + wait_consumer(); + return &nb_prod; /* nb_prod can't be NULL, whatever NULL is bound to */ + } gettimeofday(&tv1, NULL); if (initialize_papi() != -1) { @@ -234,23 +258,28 @@ void *producer(void *unused) else tv_result.tv_usec = tv2.tv_usec - tv1.tv_usec; printf("total_time: %u.%06u / %u.%06u / %u.%06u\n", (unsigned) tv_result.tv_sec, - (unsigned) tv_result.tv_usec, - DIV_SEC(tv_result.tv_sec, nb_bufs_sent), - DIV_USEC(tv_result.tv_sec, tv_result.tv_usec, nb_bufs_sent), - DIV_SEC(tv_result.tv_sec, nb_bufs_sent * WORDS_PER_BUF), - DIV_USEC(tv_result.tv_sec, tv_result.tv_usec, nb_bufs_sent * WORDS_PER_BUF)); - end_calc(); + (unsigned) tv_result.tv_usec, + DIV_SEC(tv_result.tv_sec, nb_bufs_sent), + DIV_USEC(tv_result.tv_sec, tv_result.tv_usec, nb_bufs_sent), + DIV_SEC(tv_result.tv_sec, nb_bufs_sent * WORDS_PER_BUF), + DIV_USEC(tv_result.tv_sec, tv_result.tv_usec, nb_bufs_sent * WORDS_PER_BUF)); + if (end_calc()) + { + fprintf(stderr, "uninitialization of calculation has failed\n"); + wait_consumer(); + return &nb_prod; /* &nb_prod can't be NULL, whatever NULL is bound to */ + } printf("[%p] Producer finished !\n", (void*) pthread_self()); /* * 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); + wait_consumer(); + if (end_producer_thread()) + { + fprintf(stderr, "Uninitialization of thread has failed\n"); + return &nb_prod; /* &nb_prod can't be NULL, whatever NULL is bound to */ + } return NULL; } @@ -285,7 +314,7 @@ void *receptor(void *a) int main(int argc, char *argv[]) { - int i; + int i, global_return_value = EXIT_SUCCESS; void *return_value; pthread_t *tid; @@ -303,8 +332,16 @@ int main(int argc, char *argv[]) pthread_create(&tid[i], NULL, producer, NULL); pthread_create(&tid[i], NULL, receptor, NULL); for(i = 0; i < nb_prod; i++) + { pthread_join(tid[i], &return_value); + if (return_value != NULL) + global_return_value = EXIT_FAILURE; + } pthread_join(tid[i], &return_value); + if (return_value != NULL) + global_return_value = EXIT_FAILURE; free(tid); - return EXIT_SUCCESS; + if (end_library()) + return EXIT_FAILURE; + return global_return_value; }