Add a "sent words == received words" check

This commit is contained in:
Thomas Preud'homme 2011-05-04 19:32:24 +02:00
parent cea65bd1bc
commit 9c835d4c46
1 changed files with 144 additions and 8 deletions

View File

@ -23,6 +23,8 @@
#define doStringification(x) #x #define doStringification(x) #x
#define WORDS_PER_LINE (CACHE_LINE_SIZE / sizeof(uintptr_t)) #define WORDS_PER_LINE (CACHE_LINE_SIZE / sizeof(uintptr_t))
typedef int inc_check_t;
static long nb_bufs_sent = 0; static long nb_bufs_sent = 0;
long nb_prod = 0; long nb_prod = 0;
@ -34,7 +36,10 @@ 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;
static int init_calc_arg = 0; static int init_calc_arg = 0;
static int block_reception = 1; static int block_reception = 1;
static int check_recv_match_send = 0;
static int page_size = 0; static int page_size = 0;
static uintptr_t single_prod_check_val; // /!\ Implies only one real producer
static inc_check_t *single_prod_check_ctxt; // /!\ Implies only one real producer
void usage(char *argv[]) void usage(char *argv[])
{ {
@ -43,11 +48,12 @@ void usage(char *argv[])
"-n nb_buffer_sent\t\tNumber of buffer to send to another core\n" "-n nb_buffer_sent\t\tNumber of buffer to send to another core\n"
"\t\t\t\tBuffer size is " toString(BUF_SIZE) " bytes\n" "\t\t\t\tBuffer size is " toString(BUF_SIZE) " bytes\n"
"Facultative options :\n" "Facultative options :\n"
"b\t\t\t\tReceive the biggest amount of data available (The default)\n" "-b\t\t\t\tReceive the biggest amount of data available (The default)\n"
"-c calculation_libname arg\tLibrary to use for calculation with its argument\n" "-c calculation_libname arg\tLibrary to use for calculation with its argument\n"
"\t\t\t\tThis library must implement functions in calc.h\n" "\t\t\t\tThis library must implement functions in calc.h\n"
"\t\t\t\t(default to none)\n" "\t\t\t\t(default to none)\n"
"d\t\t\t\tReceive one piece of data\n" "--check\t\t\t\tCheck we receive what is sent\n"
"-d\t\t\t\tReceive one piece of data\n"
"-h\t\t\t\tPrint this help\n" "-h\t\t\t\tPrint this help\n"
"-s <level>\t\t\tShare the same L<level> cache or not\n" "-s <level>\t\t\tShare the same L<level> cache or not\n"
"\t\t\t\tIf level is:\n" "\t\t\t\tIf level is:\n"
@ -76,12 +82,57 @@ int do_noend(void)
return 0; return 0;
} }
int inc_check_init(int init_value, inc_check_t **context)
{
inc_check_t *ctxt;
ctxt = malloc(sizeof(*ctxt));
if (ctxt == NULL)
return -1;
*ctxt = init_value;
*context = ctxt;
return 0;
}
int inc_check_next(inc_check_t *context, uintptr_t *next_value)
{
*next_value = (*context)++;
return 0;
}
int inc_check_end(inc_check_t *context)
{
free(context);
return 0;
}
int do_checkinit(int init_value)
{
return inc_check_init(init_value, &single_prod_check_ctxt);
}
void **do_checkcalc(void)
{
int ret;
ret = inc_check_next(single_prod_check_ctxt, &single_prod_check_val);
if (ret)
return NULL;
else
return (void **) single_prod_check_val;
}
int do_checkend(void)
{
return inc_check_end(single_prod_check_ctxt);
}
int analyse_options(int argc, char *argv[]) int analyse_options(int argc, char *argv[])
{ {
int opt; int opt;
opterr = 0; opterr = 0;
while ((opt = getopt(argc, argv, ":hs::c:n:p:")) != -1) while ((opt = getopt(argc, argv, ":bc:dhkn:s::"/*p:"*/)) != -1)
{ {
switch (opt) switch (opt)
{ {
@ -141,6 +192,9 @@ int analyse_options(int argc, char *argv[])
case 'h' : case 'h' :
usage(argv); usage(argv);
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
case 'k' :
check_recv_match_send = 1;
break;
case 'n' : case 'n' :
{ {
char *inval; char *inval;
@ -192,7 +246,8 @@ int analyse_options(int argc, char *argv[])
return -1; return -1;
} }
/* TODO: Real management of shared memory level */ /* TODO: Real management of shared memory level */
if (share_level <= 0) /* -x: We wan't level x not to be shared; 0 do as we want, only memory is guaranteed to be shared */ /* TODO: -x: We want level x not to be shared; 0 do as we want, only memory is guaranteed to be shared */
if (share_level <= 0)
shared = 0; shared = 0;
else else
shared = 1; shared = 1;
@ -201,6 +256,14 @@ int analyse_options(int argc, char *argv[])
break; break;
case '?' : case '?' :
fprintf(stderr, "Option inconnue\n"); fprintf(stderr, "Option inconnue\n");
/*if (!strncmp("--check", argv[optind], strlen("--check")))
{
check_recv_match_send = 1;
optind++;
optopt = (int) *argv[optind];
fprintf(stderr, "--check required\n");
break;
}*/
return -1; return -1;
case ':' : case ':' :
fprintf(stderr, "Option %s needs an argument\n", argv[optind]); fprintf(stderr, "Option %s needs an argument\n", argv[optind]);
@ -227,11 +290,25 @@ int analyse_options(int argc, char *argv[])
fprintf(stderr, "Too many producers to fit with the consumer in processors which share a same cache\n"); fprintf(stderr, "Too many producers to fit with the consumer in processors which share a same cache\n");
return -1; return -1;
} }
if (check_recv_match_send && do_calc)
{
fprintf(stderr, "Can't specifying a computation library with check activated\n");
return -1;
}
if (do_calc == NULL) if (do_calc == NULL)
{ {
init_calc = do_noinit; if (check_recv_match_send)
do_calc = do_nocalc; {
end_calc = do_noend; init_calc = do_checkinit;
do_calc = do_checkcalc;
end_calc = do_checkend;
}
else
{
init_calc = do_noinit;
do_calc = do_nocalc;
end_calc = do_noend;
}
} }
printf("buf size: %lu\n", WORDS_PER_LINE); printf("buf size: %lu\n", WORDS_PER_LINE);
return 0; return 0;
@ -309,6 +386,11 @@ void on_message(void *val)
void *consumer(void *channel) void *consumer(void *channel)
{ {
int delayed_error;
uintptr_t cons_check_value;
inc_check_t *cons_check_context;
delayed_error = 0;
if (shared) if (shared)
{ {
pthread_t tid; pthread_t tid;
@ -328,6 +410,13 @@ void *consumer(void *channel)
fprintf(stderr, "Initialization of thread has failed\n"); fprintf(stderr, "Initialization of thread has failed\n");
return &page_size; /* &page_size can't be NULL, whatever NULL is bound to */ return &page_size; /* &page_size can't be NULL, whatever NULL is bound to */
} }
if (inc_check_init(init_calc_arg, &cons_check_context))
{
fprintf(stderr, "Initialization of check has failed\n");
finalize_consumer_thread(channel);
return &page_size; /* &page_size can't be NULL, whatever NULL is bound to */
}
cons_check_value = init_calc_arg;
if (block_reception) if (block_reception)
{ {
long long total_data_received = 0; long long total_data_received = 0;
@ -341,7 +430,25 @@ void *consumer(void *channel)
nb_data_received = recv_some_data(data_buf, MAX_BLOCK_ENTRIES); nb_data_received = recv_some_data(data_buf, MAX_BLOCK_ENTRIES);
total_data_received += nb_data_received; total_data_received += nb_data_received;
for (i = 0; i < nb_data_received; i++) for (i = 0; i < nb_data_received; i++)
{
if (inc_check_next(cons_check_context, &cons_check_value))
{
if (!delayed_error)
{
fprintf(stderr, "Error while checking received value match sent value\n");
delayed_error = 1;
}
}
if (cons_check_value != (uintptr_t) data_buf[i])
{
if (!delayed_error)
{
fprintf(stderr, "Mismatch between expected(%lu) and received values(%lu)\n", cons_check_value, (uintptr_t) data_buf[i]);
delayed_error = 1;
}
}
on_message(data_buf[i]); on_message(data_buf[i]);
}
//printf("[%p] Just received %d word-sized data%s\n", (void *) pthread_self(), nb_data_received, nb_data_received ? "s" : ""); //printf("[%p] Just received %d word-sized data%s\n", (void *) pthread_self(), nb_data_received, nb_data_received ? "s" : "");
} }
} }
@ -352,14 +459,43 @@ void *consumer(void *channel)
for(i = 0; i < nb_bufs_sent; i++) { for(i = 0; i < nb_bufs_sent; i++) {
//printf("[%p] About to receive %d new cache line%s\n", (void *) pthread_self(), BUF_SIZE / CACHE_LINE_SIZE, (BUF_SIZE / CACHE_LINE_SIZE > 1) ? "s" : ""); //printf("[%p] About to receive %d new cache line%s\n", (void *) pthread_self(), BUF_SIZE / CACHE_LINE_SIZE, (BUF_SIZE / CACHE_LINE_SIZE > 1) ? "s" : "");
for(j = 0; j < WORDS_PER_LINE; j++) for(j = 0; j < WORDS_PER_LINE; j++)
on_message(recv_one_data()); {
void *data;
data = recv_one_data();
if (inc_check_next(cons_check_context, &cons_check_value))
{
if (!delayed_error)
{
fprintf(stderr, "Error while checking received value match sent value\n");
delayed_error = 1;
}
}
if (cons_check_value != (uintptr_t) data)
{
if (!delayed_error)
{
fprintf(stderr, "Mismatch between expected(%lu) and received values(%lu)\n", cons_check_value, (uintptr_t) data);
delayed_error = 1;
}
}
on_message(data);
}
} }
} }
if (inc_check_end(cons_check_context))
{
fprintf(stderr, "Finalization of check has failed\n");
finalize_consumer_thread(channel);
return &page_size; /* &page_size can't be NULL, whatever NULL is bound to */
}
if (finalize_consumer_thread(channel)) if (finalize_consumer_thread(channel))
{ {
fprintf(stderr, "Finalization of thread has failed\n"); fprintf(stderr, "Finalization of thread has failed\n");
return &page_size; /* &page_size can't be NULL, whatever NULL is bound to */ return &page_size; /* &page_size can't be NULL, whatever NULL is bound to */
} }
if (delayed_error)
return &page_size; /* &page_size can't be NULL, whatever NULL is bound to */
return NULL; return NULL;
} }