#include #include #include #include /* Non standard include */ #include #include __thread struct comm *comm; int init_library(void) { return 0; } int finalize_library(void) { return 0; } void *create_comm_channel(void) { struct comm *comm; if (!posix_memalign((void *) &comm, CACHE_LINE_SIZE, sizeof(struct comm))) { if (!posix_memalign((void *) &comm->shared_space, CACHE_LINE_SIZE, SHARED_SPACE_SIZE)) { int i; comm->head = 0; comm->tail = 0; for (i = 0; i < SHARED_SPACE_VOIDPTR; i++) comm->shared_space[i] = NULL; return comm; } else free(comm); } return NULL; } int destroy_comm_channel(void *comm) { free((void *) ((struct comm *) comm)->shared_space); free(comm); return 0; } int init_producer_thread(void *comm_param) { comm = (struct comm *) comm_param; return 0; } int finalize_producer_thread(void *unused) { comm = NULL; return 0; } int init_consumer_thread(void *comm_param) { comm = (struct comm *) comm_param; return 0; } int finalize_consumer_thread(void *unused) { comm = NULL; return 0; } int adjust_slip(void) { int dist, dist_old, unused; puts("adjust_slip is called"); /* Must be removed after calibration */ unused = 0; dist = (comm->head + SHARED_SPACE_VOIDPTR - comm->tail) % SHARED_SPACE_VOIDPTR; if (dist < DANGER) { dist_old = 0; do { int i; dist_old = dist; /* * I consider 20 as being the number of ++ which could * be done while one data is sent by the producer */ for (i = 0; i < 20 * ((GOOD + 1) - dist); i++) unused++; dist = (comm->head + SHARED_SPACE_VOIDPTR - comm->tail) % SHARED_SPACE_VOIDPTR; } while (dist < GOOD && dist_old < dist); } return unused; } void *recv_one_data(void) { void *result; static __thread int nb_iter = 0; if (nb_iter == ADJUST_FREQ) { adjust_slip(); nb_iter = 0; } while (1) { result = (void *) comm->shared_space[comm->tail]; if (NULL == result) continue; comm->shared_space[comm->tail] = NULL; comm->tail = (comm->tail + 1) % SHARED_SPACE_VOIDPTR; break; } return result; } ssize_t recv_some_data(void **buf, size_t count) { int n, next_adjust; static __thread int nb_iter = 0; next_adjust = ADJUST_FREQ - nb_iter; for(n = 0; n < count; n++) { /* if ((nb_iter + n) % ADJUST_FREQ == 0) */ if (n && (n % next_adjust == ADJUST_FREQ)) { adjust_slip(); nb_iter = 0; } /* * The behaviour of this is not documented but we know * the values inside buf won't change during this affectation */ *buf = (void *) comm->shared_space[comm->tail]; if (NULL == *buf) break; buf++; comm->shared_space[comm->tail] = NULL; comm->tail = (comm->tail + 1) % SHARED_SPACE_VOIDPTR; } nb_iter = (nb_iter + n) % ADJUST_FREQ; return n; }