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

View File

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

View File

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

View File

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

View File

@ -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)
{

View File

@ -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 *));
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 *))

View File

@ -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)

View File

@ -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 *))

View File

@ -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 *))

View File

@ -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 *))

View File

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