1010#include <time.h>
1111#include <unistd.h>
1212
13- #define RINGBUF_PAD(SIZE) (((size_t)(SIZE) + 7U) & (~7U))
13+ #define RINGBUF_PAD(SIZE) \
14+ (((size_t) (SIZE) + 7U) & (~7U)) /* size is padded to a multiple of 8 */
15+ #define GAP_MASK 1U
16+ #define SIZE_MASK (~GAP_MASK)
1417
1518typedef struct {
16- uint32_t size, gap ;
19+ uint32_t size_and_gap ;
1720} ringbuf_element_t;
1821
1922typedef struct {
@@ -54,7 +57,7 @@ static inline ringbuf_t *ringbuf_new(size_t minimum, bool release_and_acquire)
5457 const size_t body_size = ringbuf_body_size(minimum);
5558 const size_t total_size = sizeof(ringbuf_t) + body_size;
5659
57- posix_memalign((void **) &ringbuf, sizeof(ringbuf_element_t) , total_size);
60+ posix_memalign((void **) &ringbuf, 8 , total_size);
5861 mlock(ringbuf, total_size); /* prevent memory from being flushed */
5962
6063 if (ringbuf)
@@ -170,19 +173,17 @@ static inline void ringbuf_write_advance(ringbuf_t *ringbuf, size_t written)
170173 /* fill end of first buffer with gap */
171174 ringbuf_element_t *element =
172175 (ringbuf_element_t *) (ringbuf->buf + head);
173- element->size = ringbuf->gapd - sizeof(ringbuf_element_t);
174- element->gap = 1 ;
176+ element->size_and_gap = ringbuf->gapd - sizeof(ringbuf_element_t);
177+ element->size_and_gap |= GAP_MASK ;
175178
176179 /* fill written element header */
177180 element = (void *) ringbuf->buf;
178- element->size = written;
179- element->gap = 0;
181+ element->size_and_gap = written;
180182 } else {
181183 /* fill written element header */
182184 ringbuf_element_t *element =
183185 (ringbuf_element_t *) (ringbuf->buf + head);
184- element->size = written;
185- element->gap = 0;
186+ element->size_and_gap = written;
186187 }
187188
188189 /* advance write head */
@@ -226,7 +227,7 @@ static inline const void *ringbuf_read_request(ringbuf_t *ringbuf,
226227 const size_t len1 = ringbuf->size - tail;
227228 const ringbuf_element_t *element = (const ringbuf_element_t *) buf1;
228229
229- if (element->gap ) { /* gap element? */
230+ if (element->size_and_gap & GAP_MASK ) { /* gap element? */
230231 /* skip gap */
231232 _ringbuf_read_advance_raw(ringbuf, tail, len1);
232233
@@ -235,19 +236,19 @@ static inline const void *ringbuf_read_request(ringbuf_t *ringbuf,
235236 /* there will always be at least on element after a gap */
236237 element = (const ringbuf_element_t *) buf2;
237238
238- *toread = element->size ;
239+ *toread = ( element->size_and_gap) & SIZE_MASK ;
239240 return buf2 + sizeof(ringbuf_element_t);
240241 }
241242
242243 /* valid chunk, use it! */
243- *toread = element->size ;
244+ *toread = ( element->size_and_gap) & SIZE_MASK ;
244245 return buf1 + sizeof(ringbuf_element_t);
245246 }
246247
247248 /* available buffer is contiguous */
248249 const uint8_t *buf = ringbuf->buf + tail;
249250 const ringbuf_element_t *element = (const ringbuf_element_t *) buf;
250- *toread = element->size ;
251+ *toread = ( element->size_and_gap) & SIZE_MASK ;
251252 return buf + sizeof(ringbuf_element_t);
252253 }
253254
@@ -267,7 +268,9 @@ static inline void ringbuf_read_advance(ringbuf_t *ringbuf)
267268
268269 /* advance read tail */
269270 _ringbuf_read_advance_raw(
270- ringbuf, tail, sizeof(ringbuf_element_t) + RINGBUF_PAD(element->size));
271+ ringbuf, tail,
272+ sizeof(ringbuf_element_t) +
273+ RINGBUF_PAD(element->size_and_gap & SIZE_MASK));
271274}
272275
273276/* Test program */
@@ -276,7 +279,7 @@ static const struct timespec req = {.tv_sec = 0, .tv_nsec = 1};
276279
277280static uint64_t iterations = 10000;
278281#define THRESHOLD (RAND_MAX / 256)
279- #define PAD(SIZE) (((size_t)(SIZE) + 7U) & (~7U))
282+ #define PAD(SIZE) (((size_t) (SIZE) + 7U) & (~7U))
280283
281284static void *producer_main(void *arg)
282285{
0 commit comments