lib: os: ring_buffer: Fix issues in rewinding

Two issues were found:
- subtracting rewinding value from head could result in negative value
- calling ring_buf_put_claim after tail got rewinded but before head
got rewinded resulted in error.

Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
Krzysztof Chruscinski 2021-12-16 11:56:38 +01:00 committed by Anas Nashif
commit 4433953e34

View file

@ -38,7 +38,12 @@ static uint32_t mod(struct ring_buf *buf, uint32_t val)
static uint32_t get_rewind_value(uint32_t buf_size, uint32_t threshold)
{
return buf_size * (threshold / buf_size);
/* Rewind value is rounded to buffer size and decreased by buffer_size.
* This is done to ensure that there will be no negative numbers after
* subtraction. That could happen because tail is rewinded first and
* head (which follows tail) is rewinded on next getting.
*/
return buf_size * (threshold / buf_size - 1);
}
int ring_buf_is_empty(struct ring_buf *buf)
@ -171,9 +176,16 @@ int ring_buf_item_get(struct ring_buf *buf, uint16_t *type, uint8_t *value,
uint32_t ring_buf_put_claim(struct ring_buf *buf, uint8_t **data, uint32_t size)
{
uint32_t space, trail_size, allocated, tmp_trail_mod;
uint32_t head = buf->head;
uint32_t tmp_tail = buf->misc.byte_mode.tmp_tail;
if (buf->misc.byte_mode.tmp_tail < head) {
/* Head is already rewinded but tail is not */
tmp_tail += get_rewind_value(buf->size, ring_buf_get_rewind_threshold());
}
tmp_trail_mod = mod(buf, buf->misc.byte_mode.tmp_tail);
space = (buf->head + buf->size) - buf->misc.byte_mode.tmp_tail;
space = (head + buf->size) - tmp_tail;
trail_size = buf->size - tmp_trail_mod;
/* Limit requested size to available size. */