diff --git a/communication_techniques/Makefile b/communication_techniques/Makefile index ee50b7c..97fa3fe 100644 --- a/communication_techniques/Makefile +++ b/communication_techniques/Makefile @@ -13,7 +13,7 @@ PAPIHIGHLEVELINCDIR=include # I know -finline-functions and -finline-functions-called-once are enabled by # -O3 but I did this in case gcc behaviour change one day CFLAGS=-g -O3 -finline-functions -finline-functions-called-once -Wall -Werror -LDFLAGS=-L$(LIBDIR) -L$(LOCALDIR)/$(PAPIHIGHLEVELLIBDIR) -Wl,-rpath-link,$(HOME)/local/lib -lpthread -lpapihighlevel +LDFLAGS=-L$(LIBDIR) -L$(LOCALDIR)/$(PAPIHIGHLEVELLIBDIR) -Wl,-rpath-link,$(HOME)/local/lib -lpthread -lpapihighlevel -ldl # Executables CC=gcc diff --git a/communication_techniques/src/main.c b/communication_techniques/src/main.c index f11ee60..4e24fd2 100644 --- a/communication_techniques/src/main.c +++ b/communication_techniques/src/main.c @@ -9,6 +9,7 @@ #include #include #include +#include /* Non standards includes */ #include @@ -22,7 +23,9 @@ static long nb_bufs_sent = 0; long nb_prod = 0; -static char *calculation_lib = NULL; +static void (*init_calc)(void) = NULL; +static void *(*do_calc)(void) = NULL; +static void (*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; @@ -39,13 +42,24 @@ void usage(char *argv[]) "Facultative options :\n" "-h\t\t\tPrint this help\n" "-s\t\t\tShare the same L2 cache or not\n" - "-c calculation_lib\tLibrary to use for calculation\n" + "-c calculation_libname\tLibrary to use for calculation\n" "\t\t\tThis library must implement functions in calc.h\n"; printf("Usage : %s %s\n", argv[0], format); printf("Options :\n"); printf("%s\n", options); } +void do_nothing(void) +{ +} + +void *do_nocalc(void) +{ + static int an_int; + + return &an_int; +} + int analyse_options(int argc, char *argv[]) { int opt; @@ -56,12 +70,27 @@ int analyse_options(int argc, char *argv[]) switch (opt) { case 'c' : - calculation_lib = optarg; { struct stat file_stat; - if (stat(calculation_lib, &file_stat)) + void *dl_descriptor; + + if (stat(optarg, &file_stat)) { - printf("%s: %s\n", optarg, strerror(errno)); + fprintf(stderr, "%s: %s\n", optarg, strerror(errno)); + return -1; + } + dl_descriptor = dlopen(optarg, RTLD_LAZY | RTLD_LOCAL); + if (dl_descriptor == NULL) + { + fprintf(stderr, "dlopen error: %s\n", dlerror()); + return -1; + } + init_calc = dlsym(dl_descriptor, "init_calc"); + do_calc = dlsym(dl_descriptor, "do_calc"); + end_calc = dlsym(dl_descriptor, "end_calc"); + if ((init_calc == NULL) || (do_calc == NULL) || (end_calc == NULL)) + { + fprintf(stderr, "A symbol cannot be loaded: %s\n", dlerror()); return -1; } } @@ -131,13 +160,18 @@ 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"); return -1; } + if (do_calc == NULL) + { + init_calc = do_nothing; + do_calc = do_nocalc; + end_calc = do_nothing; + } return 0; } void *producer(void *unused) { int i, j; - void *k; init_producer_thread(); if (shared) @@ -168,20 +202,17 @@ void *producer(void *unused) return NULL; } } - k = (void *) 0x6384923; + init_calc(); if (initialize_papi() != -1) { for(i = 0; i < nb_bufs_sent; i++) { //printf("[%p] Send %d new CACHE_LINE\n", (void *) pthread_self(), BUF_SIZE / CACHE_LINE_SIZE); for(j = 0; j < (BUF_SIZE / sizeof(uintptr_t)); j++) - { - send(&k); - if (unlikely(calculation_lib != NULL)) - usleep(1000); - } + send(do_calc()); } print_results(BUF_SIZE / sizeof(uintptr_t), nb_bufs_sent); } + end_calc(); printf("[%p] Producer finished !\n", (void*) pthread_self()); /* * When a producer end its thread-local storage vanished. Thus,