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