comtechs bench: Better management of errors

This commit is contained in:
Thomas Preud'homme 2009-06-24 22:25:28 +02:00 committed by Thomas Preud'homme
parent 72db76b9fa
commit 8f0aecedec
18 changed files with 171 additions and 49 deletions

View File

@ -27,7 +27,8 @@ struct thread_comm
extern struct thread_comm *tcomms; extern struct thread_comm *tcomms;
extern int swap_buffer; 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) static inline void send(void **addr)
{ {
asm volatile("mov %%gs:channel@NTPOFF + 2 *" toString(BUF_SIZE) " + " toString(CACHE_LINE_SIZE) ", %%eax\n\t" asm volatile("mov %%gs:channel@NTPOFF + 2 *" toString(BUF_SIZE) " + " toString(CACHE_LINE_SIZE) ", %%eax\n\t"

View File

@ -26,7 +26,8 @@ extern __thread struct comm_channel channel;
__BEGIN_DECLS __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 inline void send(void **addr)
{ {
channel.buf[channel.idx++] = addr; channel.buf[channel.idx++] = addr;

View File

@ -13,7 +13,9 @@ extern long nb_prod;
__BEGIN_DECLS __BEGIN_DECLS
int init_library(void); 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 *)); void reception(void (*)(void *));
__END_DECLS __END_DECLS

View File

@ -12,7 +12,8 @@ extern struct thread_comm *tcomms;
__BEGIN_DECLS __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 inline void send(void **addr) {
static __thread void **store_var = NULL; static __thread void **store_var = NULL;
store_var = addr; store_var = addr;

View File

@ -15,7 +15,8 @@ extern struct thread_comm *tcomms;
__BEGIN_DECLS __BEGIN_DECLS
void init_thread_comm(struct thread_comm *); int init_thread_comm(struct thread_comm *);
int end_thread_comm(void);
void insert(void *); void insert(void *);
static inline void send(void **addr) static inline void send(void **addr)
{ {

View File

@ -16,7 +16,8 @@ __BEGIN_DECLS
extern __thread int pipefd[]; extern __thread int pipefd[];
extern struct thread_comm *tcomms; 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) { static inline void send(void **addr) {
write(pipefd[WRITE_IDX], &addr, sizeof(void *)); write(pipefd[WRITE_IDX], &addr, sizeof(void *));
} }

View File

@ -22,7 +22,8 @@ extern __thread volatile void **shared_space;
extern __thread volatile int prod_idx; extern __thread volatile int prod_idx;
extern __thread volatile int cons_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 inline void send(void **addr) {
while ((prod_idx + 1) % SHARED_SPACE_VOIDPTR == cons_idx); while ((prod_idx + 1) % SHARED_SPACE_VOIDPTR == cons_idx);
shared_space[prod_idx] = addr; shared_space[prod_idx] = addr;

View File

@ -22,7 +22,8 @@ extern __thread volatile void **shared_space;
extern __thread volatile int prod_idx; extern __thread volatile int prod_idx;
extern __thread volatile int cons_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 inline void send(void **addr) {
static __thread int local_cons_idx = 0; static __thread int local_cons_idx = 0;

View File

@ -1,4 +1,5 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h>
#define likely(x) __builtin_expect(!!(x), 1) #define likely(x) __builtin_expect(!!(x), 1)
@ -9,7 +10,7 @@ static int *mat, *vect;
static int li; static int li;
static int n, m; /* Size of the matrice: n lines, m columns */ static int n, m; /* Size of the matrice: n lines, m columns */
void init_calc(int size) int init_calc(int size)
{ {
int i; int i;
@ -17,10 +18,22 @@ void init_calc(int size)
m = size; m = size;
srand(42); srand(42);
mat = (int *) malloc(n * m * sizeof(int)); 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)); 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++) for (i = 0; i < n * m; i++)
mat[i] = rand(); mat[i] = rand();
li = 0; li = 0;
return 0;
} }
void *do_calc(void) void *do_calc(void)
@ -35,8 +48,9 @@ void *do_calc(void)
return &mat[li * m]; return &mat[li * m];
} }
void end_calc(void) int end_calc(void)
{ {
free(mat); free(mat);
free(vect); free(vect);
return 0;
} }

View File

@ -10,12 +10,18 @@
__thread struct comm_channel channel; __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->receiver_idx = 0;
comm->channel = &channel; comm->channel = &channel;
comm->channel->state = 0; comm->channel->state = 0;
comm->channel->idx = 0; comm->channel->idx = 0;
return 0;
}
int end_thread_comm(void)
{
return 0;
} }
char *dstr="buffer transition\n"; char *dstr="buffer transition\n";

View File

@ -10,12 +10,18 @@
__thread struct comm_channel channel; __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->receiver_idx = 0;
comm->channel = &channel; comm->channel = &channel;
comm->channel->state = 0; comm->channel->state = 0;
comm->channel->idx = 0; comm->channel->idx = 0;
return 0;
}
int end_thread_comm(void)
{
return 0;
} }
char *dstr="buffer transition\n"; char *dstr="buffer transition\n";

View File

@ -11,6 +11,7 @@
struct thread_comm *tcomms; struct thread_comm *tcomms;
volatile int cont = 1; volatile int cont = 1;
static int init = 0; static int init = 0;
static int error = 0;
static pthread_mutex_t init_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t init_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t init_cond = PTHREAD_COND_INITIALIZER; static pthread_cond_t init_cond = PTHREAD_COND_INITIALIZER;
@ -25,6 +26,12 @@ int init_library(void)
return 0; return 0;
} }
int end_library(void)
{
free(tcomms);
return 0;
}
int get_thread_number(void) int get_thread_number(void)
{ {
static int i = 0; static int i = 0;
@ -38,27 +45,35 @@ int get_thread_number(void)
return i_local; 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; int i_local;
pthread_mutex_lock(&i_lock); i_local = get_thread_number();
i_local = i; if (init_thread_comm(&tcomms[i_local]))
i++; {
pthread_mutex_unlock(&i_lock); error = 1;
init_thread_comm(&tcomms[i_local]); return -1;
}
pthread_mutex_lock(&init_lock); pthread_mutex_lock(&init_lock);
init = 1; init = 1;
pthread_cond_signal(&init_cond); pthread_cond_signal(&init_cond);
pthread_mutex_unlock(&init_lock); 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); pthread_mutex_lock(&init_lock);
if (!init) if (!init && !error)
pthread_cond_wait(&init_cond, &init_lock); pthread_cond_wait(&init_cond, &init_lock);
pthread_mutex_unlock(&init_lock); pthread_mutex_unlock(&init_lock);
if (error)
return -1;
return 0;
} }

View File

@ -9,8 +9,14 @@
#include <specific_comm.h> #include <specific_comm.h>
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 *)) void reception(void (*on_receive)(void *))

View File

@ -33,14 +33,25 @@ static struct double_linked_list *global_head = NULL;
static int bufsenqueued = 0; static int bufsenqueued = 0;
static unsigned int lock = 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; void **new_buffer;
new_buffer = (void **) malloc(BUFFER_SIZE); 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 - 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 (USABLE_BUFFER_BYTES % (1 << LOG_BYTES_IN_ADDRESS))) + BYTES_IN_ADDRESS; // The second parenthesis is equal to 0
local_tail_buffer_end = local_tail; 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) void set_next(struct double_linked_list *list, struct double_linked_list *next)

View File

@ -13,7 +13,7 @@
__thread int pipefd[2]; __thread int pipefd[2];
void init_thread_comm(struct thread_comm *comm) int init_thread_comm(struct thread_comm *comm)
{ {
int flags; int flags;
@ -21,6 +21,12 @@ void init_thread_comm(struct thread_comm *comm)
flags = fcntl(pipefd[READ_IDX], F_GETFL); flags = fcntl(pipefd[READ_IDX], F_GETFL);
fcntl(pipefd[READ_IDX], F_SETFL, flags | O_NONBLOCK); fcntl(pipefd[READ_IDX], F_SETFL, flags | O_NONBLOCK);
comm->pipefd = pipefd; comm->pipefd = pipefd;
return 0;
}
int end_thread_comm(void)
{
return 0;
} }
void reception(void (*on_receive)(void *)) void reception(void (*on_receive)(void *))

View File

@ -13,12 +13,18 @@ __thread volatile void **shared_space;
__thread volatile int cons_idx = 0; __thread volatile int cons_idx = 0;
__thread volatile int prod_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); shared_space = (volatile void **) malloc(SHARED_SPACE_SIZE);
comm->shared_space = shared_space; comm->shared_space = shared_space;
comm->cons_idx = &cons_idx; comm->cons_idx = &cons_idx;
comm->prod_idx = &prod_idx; comm->prod_idx = &prod_idx;
return 0;
}
int end_thread_comm(void)
{
return 0;
} }
void reception(void (*on_receive)(void *)) void reception(void (*on_receive)(void *))

View File

@ -13,12 +13,18 @@ __thread volatile void **shared_space;
__thread volatile int cons_idx = 0; __thread volatile int cons_idx = 0;
__thread volatile int prod_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); shared_space = (volatile void **) malloc(SHARED_SPACE_SIZE);
comm->shared_space = shared_space; comm->shared_space = shared_space;
comm->cons_idx = &cons_idx; comm->cons_idx = &cons_idx;
comm->prod_idx = &prod_idx; comm->prod_idx = &prod_idx;
return 0;
}
int end_thread_comm(void)
{
return 0;
} }
void reception(void (*on_receive)(void *)) void reception(void (*on_receive)(void *))

View File

@ -29,9 +29,9 @@
static long nb_bufs_sent = 0; static long nb_bufs_sent = 0;
long nb_prod = 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 *(*do_calc)(void) = NULL;
static void (*end_calc)(void) = NULL; static int (*end_calc)(void) = NULL;
static int shared = 0; static int shared = 0;
pthread_cond_t cond_cons_has_finished = PTHREAD_COND_INITIALIZER; pthread_cond_t cond_cons_has_finished = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex_cons_has_finished = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t mutex_cons_has_finished = PTHREAD_MUTEX_INITIALIZER;
@ -55,8 +55,9 @@ void usage(char *argv[])
printf("%s\n", options); printf("%s\n", options);
} }
void do_noinit(int unused) int do_noinit(int unused)
{ {
return 0;
} }
void *do_nocalc(void) void *do_nocalc(void)
@ -66,8 +67,9 @@ void *do_nocalc(void)
return &an_int; return &an_int;
} }
void do_noend(void) int do_noend(void)
{ {
return 0;
} }
int analyse_options(int argc, char *argv[]) int analyse_options(int argc, char *argv[])
@ -179,12 +181,27 @@ int analyse_options(int argc, char *argv[])
return 0; 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) void *producer(void *unused)
{ {
int i, j; int i, j;
struct timeval tv1, tv2, tv_result; 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) if (shared)
{ {
pthread_t tid; pthread_t tid;
@ -196,7 +213,8 @@ void *producer(void *unused)
if (pthread_setaffinity_np(tid, sizeof(cpu_set_t), &cpuset)) if (pthread_setaffinity_np(tid, sizeof(cpu_set_t), &cpuset))
{ {
perror("pthread_setaffinity_np"); perror("pthread_setaffinity_np");
return NULL; wait_consumer();
return &nb_prod; /* &nb_prod can't be NULL, whatever NULL is bound to */
} }
} }
else else
@ -210,10 +228,16 @@ void *producer(void *unused)
if (pthread_setaffinity_np(tid, sizeof(cpu_set_t), &cpuset)) if (pthread_setaffinity_np(tid, sizeof(cpu_set_t), &cpuset))
{ {
perror("pthread_setaffinity_np"); 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); gettimeofday(&tv1, NULL);
if (initialize_papi() != -1) if (initialize_papi() != -1)
{ {
@ -234,23 +258,28 @@ void *producer(void *unused)
else else
tv_result.tv_usec = tv2.tv_usec - tv1.tv_usec; 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, printf("total_time: %u.%06u / %u.%06u / %u.%06u\n", (unsigned) tv_result.tv_sec,
(unsigned) tv_result.tv_usec, (unsigned) tv_result.tv_usec,
DIV_SEC(tv_result.tv_sec, nb_bufs_sent), DIV_SEC(tv_result.tv_sec, nb_bufs_sent),
DIV_USEC(tv_result.tv_sec, tv_result.tv_usec, 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_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)); DIV_USEC(tv_result.tv_sec, tv_result.tv_usec, nb_bufs_sent * WORDS_PER_BUF));
end_calc(); 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()); printf("[%p] Producer finished !\n", (void*) pthread_self());
/* /*
* When a producer end its thread-local storage vanished. Thus, * When a producer end its thread-local storage vanished. Thus,
* producers must finish only after consumer has stopped using them * producers must finish only after consumer has stopped using them
*/ */
pthread_mutex_lock(&mutex_cons_has_finished); wait_consumer();
if (++producers_ended == nb_prod) if (end_producer_thread())
cont = 0; {
if (!consumer_has_finished) fprintf(stderr, "Uninitialization of thread has failed\n");
pthread_cond_wait(&cond_cons_has_finished, &mutex_cons_has_finished); return &nb_prod; /* &nb_prod can't be NULL, whatever NULL is bound to */
pthread_mutex_unlock(&mutex_cons_has_finished); }
return NULL; return NULL;
} }
@ -285,7 +314,7 @@ void *receptor(void *a)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int i; int i, global_return_value = EXIT_SUCCESS;
void *return_value; void *return_value;
pthread_t *tid; 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, producer, NULL);
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);
if (return_value != NULL)
global_return_value = EXIT_FAILURE;
}
pthread_join(tid[i], &return_value); pthread_join(tid[i], &return_value);
if (return_value != NULL)
global_return_value = EXIT_FAILURE;
free(tid); free(tid);
return EXIT_SUCCESS; if (end_library())
return EXIT_FAILURE;
return global_return_value;
} }