diff --git a/test.c b/test.c index 34ed407..0d530df 100644 --- a/test.c +++ b/test.c @@ -68,11 +68,12 @@ typedef struct shmem size_t size; uint32_t sent; uint32_t read; - size_t* a; + char* a; + uint32_t pos; } Shmem; -Shmem* s; +Shmem s; #else // SHMEM @@ -90,10 +91,8 @@ typedef union size #endif // SHMEM #ifdef SHMEM -static Shmem* shmem_create(void) +static void shmem_create(void) { - Shmem* s; - // Our memory buffer will be readable and writable: int protection = PROT_READ | PROT_WRITE; @@ -104,27 +103,18 @@ static Shmem* shmem_create(void) // The remaining parameters to `mmap()` are not important for this use case, // but the manpage for `mmap` explains their purpose. - s = mmap(NULL, SIZE, protection, visibility, -1, 0); - if (s == NULL) err("mmap of Shmem failed", 5); - - s->a = mmap(NULL, SIZE, protection, visibility, -1, 0); - if (s->a == NULL) err("mmap of array failed", 5); + s.a = mmap(NULL, SIZE, protection, visibility, -1, 0); + if (s.a == NULL) err("mmap of array failed", 5); -#ifndef NDEBUG - printf("s: %p, %p\n", s, s + sizeof(Shmem)); -#endif // NDEBUG - - s->size = SIZE; - s->sent = 0; - s->read = 0; - - return s; + s.size = SIZE; + s.sent = 0; + s.read = 0; + s.pos = 0; } static void shmem_destroy(Shmem* s) { if (munmap(s->a, SIZE)) err("could not unmap memory", 1); - if (munmap(s, SIZE)) err("could not unmap memory", 1); } static inline long futex(uint32_t* uaddr, int futex_op, uint32_t val, @@ -163,13 +153,31 @@ static inline void do_wake(uint32_t* f, uint32_t val) __attribute__((always_inline)) static inline uint32_t get_val(bool read, uint32_t val) { - return do_wait(read ? &s->read : &s->sent, val); + return do_wait(read ? &s.read : &s.sent, val); } __attribute__((always_inline)) static inline void set_val(unsigned int val, bool read) { - do_wake(read ? &s->read : &s->sent, val); + do_wake(read ? &s.read : &s.sent, val); +} + +__attribute__((always_inline)) +static inline uint32_t* get_write_ptr(void) +{ + return ((uint32_t*) s.a + ((s.pos + sizeof(uint32_t)) & MASK)); +} + +__attribute__((always_inline)) +static inline uint32_t* get_read_ptr(void) +{ + return ((uint32_t*) s.a + (s.pos & MASK)); +} + +__attribute__((always_inline)) +static inline size_t* get_data_ptr(void) +{ + return ((size_t*) s.a + ((s.pos + 2 * sizeof(uint32_t)) & MASK)); } #endif // SHMEM @@ -191,13 +199,24 @@ static size_t receive(unsigned int* rd) unsigned int val; - val = get_val(false, *rd); + uint32_t* read_ptr; + uint32_t* read_ptr2; + uint32_t* write_ptr; + size_t* data_ptr; + + read_ptr = get_read_ptr(); + write_ptr = get_write_ptr(); + data_ptr = get_data_ptr(); + + s.pos += 2 * sizeof(uint32_t) + sizeof(size_t); + + do_wait(write_ptr, 0); - idx = s->a[val & MASK]; + idx = *data_ptr; *rd += 1; - set_val(*rd, true); + do_wake(read_ptr, 8); #endif // KERNEL @@ -221,15 +240,30 @@ static void send(size_t idx, unsigned int* st) #else // KERNEL - unsigned int val; + uint32_t* read_ptr; + uint32_t* read_ptr2; + uint32_t* write_ptr; + uint32_t* write_ptr2; + size_t* data_ptr; - s->a[(*st) & MASK] = idx + 1; + read_ptr = get_read_ptr(); + write_ptr = get_write_ptr(); + data_ptr = get_data_ptr(); - *st += 1; + *data_ptr = idx + 1; + + s.pos += 2 * sizeof(uint32_t) + sizeof(size_t); - set_val(*st, false); + read_ptr2 = get_read_ptr(); + write_ptr2 = get_write_ptr(); + + *read_ptr2 = 0; + *write_ptr2 = 0; + + *st += 1; - val = get_val(true, *st - 1); + do_wake(write_ptr, 8); + do_wait(read_ptr, 0); #endif // KERNEL } @@ -248,7 +282,7 @@ int main(int argc, char* argv[]) #ifdef SHMEM - s = shmem_create(); + shmem_create(); #else @@ -347,7 +381,7 @@ int main(int argc, char* argv[]) if (CONSUMER(pid)) close(in); else close(out); #else // KERNEL - shmem_destroy(s); + shmem_destroy(&s); #endif // KERNEL return 0;