Skip to content

Commit e1eead3

Browse files
Nicolas Pitrekartben
authored andcommitted
ring_buffer: shrink size of struct ring_buf
Make struct ring_buf 12 bytes smaller by default. This comes with a 32KB buffer size limit which covers almost all cases. The previous limit of 2GB can be restored with CONFIG_RING_BUFFER_LARGE=y. Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
1 parent b97f11a commit e1eead3

File tree

4 files changed

+35
-18
lines changed

4 files changed

+35
-18
lines changed

include/zephyr/sys/ring_buffer.h

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,17 @@ extern "C" {
2929
/* The limit is used by algorithm for distinguishing between empty and full
3030
* state.
3131
*/
32-
#define RING_BUFFER_MAX_SIZE 0x80000000U
33-
#define RING_BUFFER_SIZE_ASSERT_MSG \
34-
"Size too big"
32+
#ifdef CONFIG_RING_BUFFER_LARGE
33+
typedef uint32_t ring_buf_idx_t;
34+
#define RING_BUFFER_MAX_SIZE (UINT32_MAX / 2)
35+
#else
36+
typedef uint16_t ring_buf_idx_t;
37+
#define RING_BUFFER_MAX_SIZE (UINT16_MAX / 2)
38+
#endif
39+
40+
#define RING_BUFFER_SIZE_ASSERT_MSG "Size too big"
3541

36-
struct ring_buf_index { int32_t head, tail, base; };
42+
struct ring_buf_index { ring_buf_idx_t head, tail, base; };
3743

3844
/** @endcond */
3945

@@ -61,7 +67,7 @@ int ring_buf_area_finish(struct ring_buf *buf, struct ring_buf_index *ring,
6167
*
6268
* Any value other than 0 makes sense only in validation testing context.
6369
*/
64-
static inline void ring_buf_internal_reset(struct ring_buf *buf, int32_t value)
70+
static inline void ring_buf_internal_reset(struct ring_buf *buf, ring_buf_idx_t value)
6571
{
6672
buf->put.head = buf->put.tail = buf->put.base = value;
6773
buf->get.head = buf->get.tail = buf->get.base = value;
@@ -90,7 +96,7 @@ static inline void ring_buf_internal_reset(struct ring_buf *buf, int32_t value)
9096
* @param size8 Size of ring buffer (in bytes).
9197
*/
9298
#define RING_BUF_DECLARE(name, size8) \
93-
BUILD_ASSERT(size8 < RING_BUFFER_MAX_SIZE,\
99+
BUILD_ASSERT(size8 <= RING_BUFFER_MAX_SIZE,\
94100
RING_BUFFER_SIZE_ASSERT_MSG); \
95101
static uint8_t __noinit _ring_buffer_data_##name[size8]; \
96102
struct ring_buf name = RING_BUF_INIT(_ring_buffer_data_##name, size8)
@@ -111,7 +117,7 @@ static inline void ring_buf_internal_reset(struct ring_buf *buf, int32_t value)
111117
* @param size32 Size of ring buffer (in 32-bit words).
112118
*/
113119
#define RING_BUF_ITEM_DECLARE(name, size32) \
114-
BUILD_ASSERT((size32) < RING_BUFFER_MAX_SIZE / 4,\
120+
BUILD_ASSERT((size32) <= RING_BUFFER_MAX_SIZE / 4, \
115121
RING_BUFFER_SIZE_ASSERT_MSG); \
116122
static uint32_t __noinit _ring_buffer_data_##name[size32]; \
117123
struct ring_buf name = { \
@@ -168,7 +174,7 @@ static inline void ring_buf_init(struct ring_buf *buf,
168174
uint32_t size,
169175
uint8_t *data)
170176
{
171-
__ASSERT(size < RING_BUFFER_MAX_SIZE, RING_BUFFER_SIZE_ASSERT_MSG);
177+
__ASSERT(size <= RING_BUFFER_MAX_SIZE, RING_BUFFER_SIZE_ASSERT_MSG);
172178

173179
buf->size = size;
174180
buf->buffer = data;
@@ -192,7 +198,7 @@ static inline void ring_buf_item_init(struct ring_buf *buf,
192198
uint32_t size,
193199
uint32_t *data)
194200
{
195-
__ASSERT(size < RING_BUFFER_MAX_SIZE / 4, RING_BUFFER_SIZE_ASSERT_MSG);
201+
__ASSERT(size <= RING_BUFFER_MAX_SIZE / 4, RING_BUFFER_SIZE_ASSERT_MSG);
196202
ring_buf_init(buf, 4 * size, (uint8_t *)data);
197203
}
198204

@@ -227,7 +233,9 @@ static inline void ring_buf_reset(struct ring_buf *buf)
227233
*/
228234
static inline uint32_t ring_buf_space_get(struct ring_buf *buf)
229235
{
230-
return buf->size - (buf->put.head - buf->get.tail);
236+
ring_buf_idx_t allocated = buf->put.head - buf->get.tail;
237+
238+
return buf->size - allocated;
231239
}
232240

233241
/**
@@ -255,15 +263,17 @@ static inline uint32_t ring_buf_capacity_get(struct ring_buf *buf)
255263
}
256264

257265
/**
258-
* @brief Determine used space in a ring buffer.
266+
* @brief Determine size of available data in a ring buffer.
259267
*
260268
* @param buf Address of ring buffer.
261269
*
262-
* @return Ring buffer space used (in bytes).
270+
* @return Ring buffer data size (in bytes).
263271
*/
264272
static inline uint32_t ring_buf_size_get(struct ring_buf *buf)
265273
{
266-
return buf->put.tail - buf->get.head;
274+
ring_buf_idx_t available = buf->put.tail - buf->get.head;
275+
276+
return available;
267277
}
268278

269279
/**

lib/utils/Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ config RING_BUFFER
1616
Some facilities such as kernel pipes are built on top of this.
1717
May be used directly e.g. when the pipe overhead is unnecessary.
1818

19+
config RING_BUFFER_LARGE
20+
bool "Allow large ring buffer sizes"
21+
depends on RING_BUFFER
22+
help
23+
Increase maximum buffer size from 32KB to 2GB. When this is enabled,
24+
all struct ring_buf instances become 12 bytes bigger.
25+
1926
config NOTIFY
2027
bool "Asynchronous Notifications"
2128
help

lib/utils/ring_buffer.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
uint32_t ring_buf_area_claim(struct ring_buf *buf, struct ring_buf_index *ring,
1313
uint8_t **data, uint32_t size)
1414
{
15-
uint32_t head_offset, wrap_size;
15+
ring_buf_idx_t head_offset, wrap_size;
1616

1717
head_offset = ring->head - ring->base;
1818
if (unlikely(head_offset >= buf->size)) {
@@ -31,7 +31,7 @@ uint32_t ring_buf_area_claim(struct ring_buf *buf, struct ring_buf_index *ring,
3131
int ring_buf_area_finish(struct ring_buf *buf, struct ring_buf_index *ring,
3232
uint32_t size)
3333
{
34-
uint32_t claimed_size, tail_offset;
34+
ring_buf_idx_t claimed_size, tail_offset;
3535

3636
claimed_size = ring->head - ring->tail;
3737
if (unlikely(size > claimed_size)) {

tests/lib/ringbuffer/src/concurrent.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -262,16 +262,16 @@ static void test_ztress(ztress_handler high_handler,
262262
uint32_t buf32[32];
263263
} buf;
264264
k_timeout_t timeout;
265-
int32_t offset;
265+
uint32_t offset;
266266

267267
if (item_mode) {
268268
ring_buf_item_init(&ringbuf, ARRAY_SIZE(buf.buf32), buf.buf32);
269269
} else {
270270
ring_buf_init(&ringbuf, ARRAY_SIZE(buf.buf8), buf.buf8);
271271
}
272272

273-
/* force internal 32-bit index roll-over */
274-
offset = INT32_MAX - ring_buf_capacity_get(&ringbuf)/2;
273+
/* force internal index roll-over */
274+
offset = (ring_buf_idx_t)-1 - ring_buf_capacity_get(&ringbuf)/2;
275275
ring_buf_internal_reset(&ringbuf, offset);
276276

277277
/* Timeout after 5 seconds. */

0 commit comments

Comments
 (0)