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>
This commit is contained in:
parent
b97f11a752
commit
e1eead3925
@ -29,11 +29,17 @@ extern "C" {
|
||||
/* The limit is used by algorithm for distinguishing between empty and full
|
||||
* state.
|
||||
*/
|
||||
#define RING_BUFFER_MAX_SIZE 0x80000000U
|
||||
#define RING_BUFFER_SIZE_ASSERT_MSG \
|
||||
"Size too big"
|
||||
#ifdef CONFIG_RING_BUFFER_LARGE
|
||||
typedef uint32_t ring_buf_idx_t;
|
||||
#define RING_BUFFER_MAX_SIZE (UINT32_MAX / 2)
|
||||
#else
|
||||
typedef uint16_t ring_buf_idx_t;
|
||||
#define RING_BUFFER_MAX_SIZE (UINT16_MAX / 2)
|
||||
#endif
|
||||
|
||||
struct ring_buf_index { int32_t head, tail, base; };
|
||||
#define RING_BUFFER_SIZE_ASSERT_MSG "Size too big"
|
||||
|
||||
struct ring_buf_index { ring_buf_idx_t head, tail, base; };
|
||||
|
||||
/** @endcond */
|
||||
|
||||
@ -61,7 +67,7 @@ int ring_buf_area_finish(struct ring_buf *buf, struct ring_buf_index *ring,
|
||||
*
|
||||
* Any value other than 0 makes sense only in validation testing context.
|
||||
*/
|
||||
static inline void ring_buf_internal_reset(struct ring_buf *buf, int32_t value)
|
||||
static inline void ring_buf_internal_reset(struct ring_buf *buf, ring_buf_idx_t value)
|
||||
{
|
||||
buf->put.head = buf->put.tail = buf->put.base = value;
|
||||
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)
|
||||
* @param size8 Size of ring buffer (in bytes).
|
||||
*/
|
||||
#define RING_BUF_DECLARE(name, size8) \
|
||||
BUILD_ASSERT(size8 < RING_BUFFER_MAX_SIZE,\
|
||||
BUILD_ASSERT(size8 <= RING_BUFFER_MAX_SIZE,\
|
||||
RING_BUFFER_SIZE_ASSERT_MSG); \
|
||||
static uint8_t __noinit _ring_buffer_data_##name[size8]; \
|
||||
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)
|
||||
* @param size32 Size of ring buffer (in 32-bit words).
|
||||
*/
|
||||
#define RING_BUF_ITEM_DECLARE(name, size32) \
|
||||
BUILD_ASSERT((size32) < RING_BUFFER_MAX_SIZE / 4,\
|
||||
BUILD_ASSERT((size32) <= RING_BUFFER_MAX_SIZE / 4, \
|
||||
RING_BUFFER_SIZE_ASSERT_MSG); \
|
||||
static uint32_t __noinit _ring_buffer_data_##name[size32]; \
|
||||
struct ring_buf name = { \
|
||||
@ -168,7 +174,7 @@ static inline void ring_buf_init(struct ring_buf *buf,
|
||||
uint32_t size,
|
||||
uint8_t *data)
|
||||
{
|
||||
__ASSERT(size < RING_BUFFER_MAX_SIZE, RING_BUFFER_SIZE_ASSERT_MSG);
|
||||
__ASSERT(size <= RING_BUFFER_MAX_SIZE, RING_BUFFER_SIZE_ASSERT_MSG);
|
||||
|
||||
buf->size = size;
|
||||
buf->buffer = data;
|
||||
@ -192,7 +198,7 @@ static inline void ring_buf_item_init(struct ring_buf *buf,
|
||||
uint32_t size,
|
||||
uint32_t *data)
|
||||
{
|
||||
__ASSERT(size < RING_BUFFER_MAX_SIZE / 4, RING_BUFFER_SIZE_ASSERT_MSG);
|
||||
__ASSERT(size <= RING_BUFFER_MAX_SIZE / 4, RING_BUFFER_SIZE_ASSERT_MSG);
|
||||
ring_buf_init(buf, 4 * size, (uint8_t *)data);
|
||||
}
|
||||
|
||||
@ -227,7 +233,9 @@ static inline void ring_buf_reset(struct ring_buf *buf)
|
||||
*/
|
||||
static inline uint32_t ring_buf_space_get(struct ring_buf *buf)
|
||||
{
|
||||
return buf->size - (buf->put.head - buf->get.tail);
|
||||
ring_buf_idx_t allocated = buf->put.head - buf->get.tail;
|
||||
|
||||
return buf->size - allocated;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -255,15 +263,17 @@ static inline uint32_t ring_buf_capacity_get(struct ring_buf *buf)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Determine used space in a ring buffer.
|
||||
* @brief Determine size of available data in a ring buffer.
|
||||
*
|
||||
* @param buf Address of ring buffer.
|
||||
*
|
||||
* @return Ring buffer space used (in bytes).
|
||||
* @return Ring buffer data size (in bytes).
|
||||
*/
|
||||
static inline uint32_t ring_buf_size_get(struct ring_buf *buf)
|
||||
{
|
||||
return buf->put.tail - buf->get.head;
|
||||
ring_buf_idx_t available = buf->put.tail - buf->get.head;
|
||||
|
||||
return available;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -16,6 +16,13 @@ config RING_BUFFER
|
||||
Some facilities such as kernel pipes are built on top of this.
|
||||
May be used directly e.g. when the pipe overhead is unnecessary.
|
||||
|
||||
config RING_BUFFER_LARGE
|
||||
bool "Allow large ring buffer sizes"
|
||||
depends on RING_BUFFER
|
||||
help
|
||||
Increase maximum buffer size from 32KB to 2GB. When this is enabled,
|
||||
all struct ring_buf instances become 12 bytes bigger.
|
||||
|
||||
config NOTIFY
|
||||
bool "Asynchronous Notifications"
|
||||
help
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
uint32_t ring_buf_area_claim(struct ring_buf *buf, struct ring_buf_index *ring,
|
||||
uint8_t **data, uint32_t size)
|
||||
{
|
||||
uint32_t head_offset, wrap_size;
|
||||
ring_buf_idx_t head_offset, wrap_size;
|
||||
|
||||
head_offset = ring->head - ring->base;
|
||||
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,
|
||||
int ring_buf_area_finish(struct ring_buf *buf, struct ring_buf_index *ring,
|
||||
uint32_t size)
|
||||
{
|
||||
uint32_t claimed_size, tail_offset;
|
||||
ring_buf_idx_t claimed_size, tail_offset;
|
||||
|
||||
claimed_size = ring->head - ring->tail;
|
||||
if (unlikely(size > claimed_size)) {
|
||||
|
||||
@ -262,7 +262,7 @@ static void test_ztress(ztress_handler high_handler,
|
||||
uint32_t buf32[32];
|
||||
} buf;
|
||||
k_timeout_t timeout;
|
||||
int32_t offset;
|
||||
uint32_t offset;
|
||||
|
||||
if (item_mode) {
|
||||
ring_buf_item_init(&ringbuf, ARRAY_SIZE(buf.buf32), buf.buf32);
|
||||
@ -270,8 +270,8 @@ static void test_ztress(ztress_handler high_handler,
|
||||
ring_buf_init(&ringbuf, ARRAY_SIZE(buf.buf8), buf.buf8);
|
||||
}
|
||||
|
||||
/* force internal 32-bit index roll-over */
|
||||
offset = INT32_MAX - ring_buf_capacity_get(&ringbuf)/2;
|
||||
/* force internal index roll-over */
|
||||
offset = (ring_buf_idx_t)-1 - ring_buf_capacity_get(&ringbuf)/2;
|
||||
ring_buf_internal_reset(&ringbuf, offset);
|
||||
|
||||
/* Timeout after 5 seconds. */
|
||||
|
||||
Loading…
Reference in New Issue
Block a user