diff --git a/communication_techniques/include/c_cache_comm.h b/communication_techniques/include/c_cache_comm.h new file mode 100644 index 0000000..68750a7 --- /dev/null +++ b/communication_techniques/include/c_cache_comm.h @@ -0,0 +1,45 @@ +#ifndef _SPECIFIC_COMM_H_ +#define _SPECIFIC_COMM_H_ 1 + +#include + +/* Non standard include */ +#include + +/* This is not an error, we need this two-macro system */ +#define toString(x) doStringification(x) +#define doStringification(x) #x + +struct comm_channel +{ + volatile void *buf[2 * BUF_SIZE / sizeof(void *)] __attribute__ ((aligned (CACHE_LINE_SIZE))); + volatile int state __attribute__ ((aligned (CACHE_LINE_SIZE))); + int idx __attribute__ ((aligned (CACHE_LINE_SIZE))); +}; + +struct thread_comm +{ + struct comm_channel *channel; + int receiver_idx; +}; + +extern struct thread_comm *tcomms; +extern __thread struct comm_channel channel; + +__BEGIN_DECLS + +void init_thread_comm(void); +static inline void send(void **addr) +{ + channel.buf[channel.idx++] = addr; + channel.idx %= 2 * BUF_SIZE / sizeof(void *); + if (!(channel.idx % (BUF_SIZE / sizeof(void *)))) + { + while (channel.state); + channel.state = 1; + } +} + +__END_DECLS + +#endif diff --git a/communication_techniques/src/c_cache.c b/communication_techniques/src/c_cache.c new file mode 100644 index 0000000..0292594 --- /dev/null +++ b/communication_techniques/src/c_cache.c @@ -0,0 +1,62 @@ +#include +#include +#include + +/* Non standard include */ +#include +#include + + +__thread struct comm_channel channel; + +void init_thread_comm(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; + pthread_mutex_unlock(&i_lock); + tcomms[i].receiver_idx = 0; + tcomms[i].channel = &channel; + tcomms[i].channel->state = 0; + tcomms[i].channel->idx = 0; + pthread_mutex_lock(&i_lock); + i++; + pthread_mutex_unlock(&i_lock); +} + +char *dstr="buffer transition\n"; + +void reception(void (*on_receive)(volatile void *)) +{ + /* printf("Activate the consumer...\n"); */ + while (cont) + { + int i; + + for (i = 0; i < nb_prod; i++) + { + if(tcomms[i].channel->state) + { + int j, n; + /* + * cur->receiver_idx point to the last cache + * line we have read. We go to the next cache + * line "+ (CACHE_LINE_SIZE >> 2)" (because + * the line is full of integer (2^2 octets) + * and then if we are after the second cache + * line we correct the pointer to point to + * the first one (this is done by the modulo) + */ + j = tcomms[i].receiver_idx; + n = tcomms[i].receiver_idx + (BUF_SIZE / sizeof(void *)); + tcomms[i].receiver_idx = n % ((2 * BUF_SIZE) / sizeof(void *)); + for(; jbuf[j]); + tcomms[i].channel->state = 0; + } + } + } +}