10
10
#include <time.h>
11
11
#include <unistd.h>
12
12
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)
14
17
15
18
typedef struct {
16
- uint32_t size , gap ;
19
+ uint32_t size_and_gap ;
17
20
} ringbuf_element_t ;
18
21
19
22
typedef struct {
@@ -54,7 +57,7 @@ static inline ringbuf_t *ringbuf_new(size_t minimum, bool release_and_acquire)
54
57
const size_t body_size = ringbuf_body_size (minimum );
55
58
const size_t total_size = sizeof (ringbuf_t ) + body_size ;
56
59
57
- posix_memalign ((void * * ) & ringbuf , sizeof ( ringbuf_element_t ) , total_size );
60
+ posix_memalign ((void * * ) & ringbuf , 8 , total_size );
58
61
mlock (ringbuf , total_size ); /* prevent memory from being flushed */
59
62
60
63
if (ringbuf )
@@ -170,19 +173,17 @@ static inline void ringbuf_write_advance(ringbuf_t *ringbuf, size_t written)
170
173
/* fill end of first buffer with gap */
171
174
ringbuf_element_t * element =
172
175
(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 ;
175
178
176
179
/* fill written element header */
177
180
element = (void * ) ringbuf -> buf ;
178
- element -> size = written ;
179
- element -> gap = 0 ;
181
+ element -> size_and_gap = written ;
180
182
} else {
181
183
/* fill written element header */
182
184
ringbuf_element_t * element =
183
185
(ringbuf_element_t * ) (ringbuf -> buf + head );
184
- element -> size = written ;
185
- element -> gap = 0 ;
186
+ element -> size_and_gap = written ;
186
187
}
187
188
188
189
/* advance write head */
@@ -226,7 +227,7 @@ static inline const void *ringbuf_read_request(ringbuf_t *ringbuf,
226
227
const size_t len1 = ringbuf -> size - tail ;
227
228
const ringbuf_element_t * element = (const ringbuf_element_t * ) buf1 ;
228
229
229
- if (element -> gap ) { /* gap element? */
230
+ if (element -> size_and_gap & GAP_MASK ) { /* gap element? */
230
231
/* skip gap */
231
232
_ringbuf_read_advance_raw (ringbuf , tail , len1 );
232
233
@@ -235,19 +236,19 @@ static inline const void *ringbuf_read_request(ringbuf_t *ringbuf,
235
236
/* there will always be at least on element after a gap */
236
237
element = (const ringbuf_element_t * ) buf2 ;
237
238
238
- * toread = element -> size ;
239
+ * toread = ( element -> size_and_gap ) & SIZE_MASK ;
239
240
return buf2 + sizeof (ringbuf_element_t );
240
241
}
241
242
242
243
/* valid chunk, use it! */
243
- * toread = element -> size ;
244
+ * toread = ( element -> size_and_gap ) & SIZE_MASK ;
244
245
return buf1 + sizeof (ringbuf_element_t );
245
246
}
246
247
247
248
/* available buffer is contiguous */
248
249
const uint8_t * buf = ringbuf -> buf + tail ;
249
250
const ringbuf_element_t * element = (const ringbuf_element_t * ) buf ;
250
- * toread = element -> size ;
251
+ * toread = ( element -> size_and_gap ) & SIZE_MASK ;
251
252
return buf + sizeof (ringbuf_element_t );
252
253
}
253
254
@@ -267,7 +268,9 @@ static inline void ringbuf_read_advance(ringbuf_t *ringbuf)
267
268
268
269
/* advance read tail */
269
270
_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 ));
271
274
}
272
275
273
276
/* Test program */
@@ -276,7 +279,7 @@ static const struct timespec req = {.tv_sec = 0, .tv_nsec = 1};
276
279
277
280
static uint64_t iterations = 10000 ;
278
281
#define THRESHOLD (RAND_MAX / 256)
279
- #define PAD (SIZE ) (((size_t)(SIZE) + 7U) & (~7U))
282
+ #define PAD (SIZE ) (((size_t) (SIZE) + 7U) & (~7U))
280
283
281
284
static void * producer_main (void * arg )
282
285
{
0 commit comments