comtechs bench: Better management of errors
This commit is contained in:
parent
72db76b9fa
commit
8f0aecedec
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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 *));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#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;
|
||||
}
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -9,8 +9,14 @@
|
|||
#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 *))
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 *))
|
||||
|
|
|
@ -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 *))
|
||||
|
|
|
@ -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 *))
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue