9 #include <linux/memfd.h>
11 #include <sys/syscall.h>
12 #include <sys/types.h>
17 static inline void queue_error(
const char* fmt, ...)
21 fprintf(stderr,
"queue error: ");
22 vfprintf(stderr, fmt, args);
23 fprintf(stderr,
"\n");
27 static inline void queue_error_errno(
const char* fmt, ...)
31 fprintf(stderr,
"queue error: ");
32 vfprintf(stderr, fmt, args);
33 fprintf(stderr,
" (errno %d)\n", errno);
39 void queue::init(
size_t s)
46 if(s % getpagesize() != 0)
48 queue_error(
"Requested size (%lu) is not a multiple of the page size (%d)",
54 if((q.fd = fileno(tmpfile())) == -1)
56 queue_error_errno(
"Could not obtain anonymous file");
60 if(ftruncate(q.fd, s) != 0)
62 queue_error_errno(
"Could not set size of anonymous file");
66 if((q.buffer = (uint8_t*)mmap(
67 NULL, 2 * s, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) == MAP_FAILED)
69 queue_error_errno(
"Could not allocate virtual memory");
73 if(mmap(q.buffer, s, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, q.fd, 0) ==
76 queue_error_errno(
"Could not map buffer into virtual memory");
80 if(mmap(q.buffer + s, s, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, q.fd, 0) ==
83 queue_error_errno(
"Could not map buffer into virtual memory");
87 if(pthread_mutex_init(&q.lock, NULL) != 0)
89 queue_error_errno(
"Could not initialize mutex");
91 if(pthread_cond_init(&q.readable, NULL) != 0)
93 queue_error_errno(
"Could not initialize condition variable");
95 if(pthread_cond_init(&q.writeable, NULL) != 0)
97 queue_error_errno(
"Could not initialize condition variable");
109 void queue::destroy()
111 if(munmap(q.buffer + q.size, q.size) != 0)
113 queue_error_errno(
"Could not unmap buffer");
116 if(munmap(q.buffer, q.size) != 0)
118 queue_error_errno(
"Could not unmap buffer");
123 queue_error_errno(
"Could not close anonymous file");
126 if(pthread_mutex_destroy(&q.lock) != 0)
128 queue_error_errno(
"Could not destroy mutex");
131 if(pthread_cond_destroy(&q.readable) != 0)
133 queue_error_errno(
"Could not destroy condition variable");
136 if(pthread_cond_destroy(&q.writeable) != 0)
138 queue_error_errno(
"Could not destroy condition variable");
143 void queue::put(int16_t*
data, int16_t data_size)
146 pthread_mutex_lock(&q.lock);
149 while(q.size - (q.tail - q.head) < data_size +
sizeof(data_size))
151 pthread_cond_wait(&q.writeable, &q.lock);
161 memcpy(q.buffer + q.tail, &data_size,
sizeof(data_size));
163 memcpy(q.buffer + q.tail +
sizeof(data_size),
data, data_size);
166 q.tail += data_size +
sizeof(data_size);
169 pthread_cond_signal(&q.readable);
172 pthread_mutex_unlock(&q.lock);
176 size_t queue::get(int16_t*
data, int16_t max_size)
179 pthread_mutex_lock(&q.lock);
187 while((q.tail - q.head) == 0)
189 pthread_cond_wait(&q.readable, &q.lock);
194 memcpy(&data_size, q.buffer + q.head,
sizeof(data_size));
210 memcpy(
data, q.buffer + q.head +
sizeof(data_size), data_size);
213 q.head += data_size +
sizeof(data_size);
224 pthread_cond_signal(&q.writeable);
227 pthread_mutex_unlock(&q.lock);