From 982a2c161a199e0fda0e17a775c521c361f016c4 Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Wed, 11 Dec 2024 14:41:33 +0100 Subject: [PATCH 1/2] sys/chunked_ringbuffer: discard stale chunk when starting a new one --- sys/include/chunked_ringbuffer.h | 37 +++++++++++++++++++------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/sys/include/chunked_ringbuffer.h b/sys/include/chunked_ringbuffer.h index 9f1ac2fa24da..d1727ba02c95 100644 --- a/sys/include/chunked_ringbuffer.h +++ b/sys/include/chunked_ringbuffer.h @@ -72,9 +72,26 @@ typedef void (*crb_foreach_callback_t)(void *ctx, uint8_t *bytes, size_t len); */ void crb_init(chunk_ringbuf_t *rb, void *buffer, size_t len); +/** + * @brief Close the current chunk + * + * @note This function is expected to be called in ISR context / with + * interrupts disabled. + * + * @param[in] rb The Ringbuffer to work on + * @param[in] valid True if the chunk is valid and should be stored + * False if the current chunk should be discarded + * + * @return true If the chunk could be stored in the valid chunk array + * @return false If there is no more space in the valid chunk array + */ +bool crb_end_chunk(chunk_ringbuf_t *rb, bool valid); + /** * @brief Start a new chunk on the ringbuffer * + * If an unfinished chunk already exists, it will be discarded. + * * @note This function is expected to be called in ISR context / with * interrupts disabled. * @@ -85,6 +102,11 @@ void crb_init(chunk_ringbuf_t *rb, void *buffer, size_t len); */ static inline bool crb_start_chunk(chunk_ringbuf_t *rb) { + /* discard stale chunk */ + if (rb->cur_start) { + crb_end_chunk(rb, false); + } + /* pointing to the start of the first chunk */ if (rb->cur == rb->protect) { return false; @@ -150,21 +172,6 @@ static inline bool crb_add_byte(chunk_ringbuf_t *rb, uint8_t b) */ bool crb_add_bytes(chunk_ringbuf_t *rb, const void *data, size_t len); -/** - * @brief Close the current chunk - * - * @note This function is expected to be called in ISR context / with - * interrupts disabled. - * - * @param[in] rb The Ringbuffer to work on - * @param[in] valid True if the chunk is valid and should be stored - * False if the current chunk should be discarded - * - * @return true If the chunk could be stored in the valid chunk array - * @return false If there is no more space in the valid chunk array - */ -bool crb_end_chunk(chunk_ringbuf_t *rb, bool valid); - /** * @brief Add a complete chunk to the Ringbuffer * From 532f018b3a449c9ae4636a191937ff01da835a7f Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Wed, 11 Dec 2024 14:44:28 +0100 Subject: [PATCH 2/2] tests/unittests: chunked_ringbuffer: add test for half-written chunk --- .../tests-chunked_ringbuffer/tests-chunked_ringbuffer.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/unittests/tests-chunked_ringbuffer/tests-chunked_ringbuffer.c b/tests/unittests/tests-chunked_ringbuffer/tests-chunked_ringbuffer.c index d2020ebf322a..238bbd44313e 100644 --- a/tests/unittests/tests-chunked_ringbuffer/tests-chunked_ringbuffer.c +++ b/tests/unittests/tests-chunked_ringbuffer/tests-chunked_ringbuffer.c @@ -25,6 +25,13 @@ static void test_crb_add_and_consume(void) crb_init(&cb, buffer, sizeof(buffer)); + /* add a chunk but don't finish it */ + crb_start_chunk(&cb); + crb_add_byte(&cb, 1); + crb_add_byte(&cb, 2); + crb_add_byte(&cb, 3); + + /* unfinished chunk should be silently discarded */ TEST_ASSERT(crb_add_chunk(&cb, "one", 4)); TEST_ASSERT(crb_add_chunk(&cb, "two", 4)); TEST_ASSERT(crb_add_chunk(&cb, "three", 6));