Skip to content

Commit 0746421

Browse files
committed
Pack gap flag into size field LSB
Reduce `ringbuf_element_t` from 8 bytes to 4 bytes by encoding the "gap" flag into the LSB of the size field. Since all payload sizes are padded to 8 bytes, the lower 3 bits of size are always zero, making it safe to reuse bit 0. This shrinks the per-element header.
1 parent 0819ea6 commit 0746421

File tree

1 file changed

+14
-14
lines changed

1 file changed

+14
-14
lines changed

ringbuf-shm/ringbuffer.c

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@
1010
#include <time.h>
1111
#include <unistd.h>
1212

13-
#define RINGBUF_PAD(SIZE) (((size_t)(SIZE) + 7U) & (~7U))
13+
#define RINGBUF_PAD(SIZE) (((size_t)(SIZE) + 7U) & (~7U))/* size is padded to a multiple of 8 */
14+
#define GAP_MASK 1U
15+
#define SIZE_MASK (~GAP_MASK)
1416

1517
typedef struct {
16-
uint32_t size, gap;
18+
uint32_t size_and_gap;
1719
} ringbuf_element_t;
1820

1921
typedef struct {
@@ -54,7 +56,7 @@ static inline ringbuf_t *ringbuf_new(size_t minimum, bool release_and_acquire)
5456
const size_t body_size = ringbuf_body_size(minimum);
5557
const size_t total_size = sizeof(ringbuf_t) + body_size;
5658

57-
posix_memalign((void **) &ringbuf, sizeof(ringbuf_element_t), total_size);
59+
posix_memalign((void **) &ringbuf, 8, total_size);
5860
mlock(ringbuf, total_size); /* prevent memory from being flushed */
5961

6062
if (ringbuf)
@@ -170,19 +172,17 @@ static inline void ringbuf_write_advance(ringbuf_t *ringbuf, size_t written)
170172
/* fill end of first buffer with gap */
171173
ringbuf_element_t *element =
172174
(ringbuf_element_t *) (ringbuf->buf + head);
173-
element->size = ringbuf->gapd - sizeof(ringbuf_element_t);
174-
element->gap = 1;
175+
element->size_and_gap = ringbuf->gapd - sizeof(ringbuf_element_t);
176+
element->size_and_gap |= GAP_MASK;
175177

176178
/* fill written element header */
177179
element = (void *) ringbuf->buf;
178-
element->size = written;
179-
element->gap = 0;
180+
element->size_and_gap = written;
180181
} else {
181182
/* fill written element header */
182183
ringbuf_element_t *element =
183184
(ringbuf_element_t *) (ringbuf->buf + head);
184-
element->size = written;
185-
element->gap = 0;
185+
element->size_and_gap = written;
186186
}
187187

188188
/* advance write head */
@@ -226,7 +226,7 @@ static inline const void *ringbuf_read_request(ringbuf_t *ringbuf,
226226
const size_t len1 = ringbuf->size - tail;
227227
const ringbuf_element_t *element = (const ringbuf_element_t *) buf1;
228228

229-
if (element->gap) { /* gap element? */
229+
if (element->size_and_gap & GAP_MASK) { /* gap element? */
230230
/* skip gap */
231231
_ringbuf_read_advance_raw(ringbuf, tail, len1);
232232

@@ -235,19 +235,19 @@ static inline const void *ringbuf_read_request(ringbuf_t *ringbuf,
235235
/* there will always be at least on element after a gap */
236236
element = (const ringbuf_element_t *) buf2;
237237

238-
*toread = element->size;
238+
*toread = (element->size_and_gap) & SIZE_MASK;
239239
return buf2 + sizeof(ringbuf_element_t);
240240
}
241241

242242
/* valid chunk, use it! */
243-
*toread = element->size;
243+
*toread = (element->size_and_gap) & SIZE_MASK;
244244
return buf1 + sizeof(ringbuf_element_t);
245245
}
246246

247247
/* available buffer is contiguous */
248248
const uint8_t *buf = ringbuf->buf + tail;
249249
const ringbuf_element_t *element = (const ringbuf_element_t *) buf;
250-
*toread = element->size;
250+
*toread = (element->size_and_gap) & SIZE_MASK;
251251
return buf + sizeof(ringbuf_element_t);
252252
}
253253

@@ -267,7 +267,7 @@ static inline void ringbuf_read_advance(ringbuf_t *ringbuf)
267267

268268
/* advance read tail */
269269
_ringbuf_read_advance_raw(
270-
ringbuf, tail, sizeof(ringbuf_element_t) + RINGBUF_PAD(element->size));
270+
ringbuf, tail, sizeof(ringbuf_element_t) + RINGBUF_PAD(element->size_and_gap & SIZE_MASK));
271271
}
272272

273273
/* Test program */

0 commit comments

Comments
 (0)