From b056597e8683c3891297b25a370c183f902d8e70 Mon Sep 17 00:00:00 2001 From: Tilen Majerle Date: Wed, 4 Jan 2023 22:20:11 +0100 Subject: [PATCH] Fix obvious issue --- .vscode/settings.json | 3 +- CMakeLists.txt | 1 + lwrb/CMakeLists.txt | 3 ++ lwrb/src/lwrb/lwrb_ex.c | 100 +++++++++++++++++++++++----------------- 4 files changed, 64 insertions(+), 43 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 8c24f42..a7d4428 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,7 +6,8 @@ "string.h": "c", "lwevt_opt.h": "c", "stdatomic.h": "c", - "lwrb.h": "c" + "lwrb.h": "c", + "*.tcc": "c" }, "esbonio.sphinx.confDir": "" } \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index e238db4..e3e8048 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,4 +37,5 @@ else() # Add subdir with lwrb and link to project add_subdirectory(lwrb) target_link_libraries(${PROJECT_NAME} lwrb) + target_link_libraries(${PROJECT_NAME} lwrb_ex) endif() \ No newline at end of file diff --git a/lwrb/CMakeLists.txt b/lwrb/CMakeLists.txt index bd9f4f1..fa8bfa9 100644 --- a/lwrb/CMakeLists.txt +++ b/lwrb/CMakeLists.txt @@ -7,6 +7,9 @@ message("Entering ${CMAKE_CURRENT_LIST_DIR}/CMakeLists.txt") add_library(lwrb INTERFACE) target_sources(lwrb PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src/lwrb/lwrb.c) target_include_directories(lwrb INTERFACE ${CMAKE_CURRENT_LIST_DIR}/src/include) +add_library(lwrb_ex INTERFACE) +target_sources(lwrb_ex PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src/lwrb/lwrb_ex.c) +target_include_directories(lwrb_ex INTERFACE ${CMAKE_CURRENT_LIST_DIR}/src/include) # Register other modules diff --git a/lwrb/src/lwrb/lwrb_ex.c b/lwrb/src/lwrb/lwrb_ex.c index fcd11f5..ce08dd4 100644 --- a/lwrb/src/lwrb/lwrb_ex.c +++ b/lwrb/src/lwrb/lwrb_ex.c @@ -1,15 +1,44 @@ /** * \file lwrb_ex.c - * \brief Lightweight ring buffer extended functions + * \brief Lightweight ring buffer - extended functions */ - -#include "lwrb.h" - +/* + * Copyright (c) 2022 Tilen MAJERLE + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * This file is part of LwRB - Lightweight ring buffer library. + * + * Author: Tilen MAJERLE + * Version: v3.0.0-rc1 + */ +#include "lwrb/lwrb.h" #define BUF_IS_VALID(b) ((b) != NULL && (b)->buff != NULL && (b)->size > 0) #define BUF_MIN(x, y) ((x) < (y) ? (x) : (y)) +#ifndef LWRB_DEV +#error "This file needs development & extensive tests - not to be used!" +#endif /** * \brief Similar to write(), writes data to buffer, will overwrite existing values. @@ -22,47 +51,42 @@ * it. This operation is a read op as well as a write op. For thread-safety mutexes may be desired, * see documentation. */ -size_t lwrb_overwrite(lwrb_t* buff, const void* data, size_t btw) -{ +size_t +lwrb_overwrite(lwrb_t* buff, const void* data, size_t btw) { size_t w, r, linear, wrap; - size_t size = buff->size; + size_t size = buff->size; size_t offset = 0; - if (!BUF_IS_VALID(buff) || data == NULL || btw == 0) - { + if (!BUF_IS_VALID(buff) || data == NULL || btw == 0) { return 0; } w = atomic_load_explicit(&buff->w, memory_order_relaxed); r = atomic_load_explicit(&buff->r, memory_order_relaxed); - - /* Step 1: Special handling if asked to write more bytes than size. */ - if (btw >= size) - { + if (btw >= size) { offset = (btw - size) + 1; - btw = size - 1; + btw = size - 1; } - - /* Step 2: Always write the linear region. There will be at least one byte written here. */ - /* Handle special case of linear being off by one when zero */ // TODO: Test this - if (w == 0) + /* Handle special case of linear being off by one when zero */ // TODO: Test this + if (w == 0) { linear = size - 1; - else + } else { linear = size - w; + } /* We might not need the whole linear length available, depends on amount to write*/ - if (btw < linear) + if (btw < linear) { linear = btw; + } /* If linear write will exceed r it must be updated, this may also happen in wrap region later */ - if ((w < r) && (w + linear) > r) - { + if ((w < r) && (w + linear) > r) { r = w + btw + 1; r %= size; } @@ -73,15 +97,11 @@ size_t lwrb_overwrite(lwrb_t* buff, const void* data, size_t btw) w %= size; wrap = btw - linear; - - /* Step 3: Wrap region are the bytes that rolled back to the start of the storage array */ - if (wrap) - { + if (wrap) { /* If r will be overrun by new write data, skip r ahead */ - if ((w <= r) && (w + wrap) >= r) - { + if ((w <= r) && (w + wrap) >= r) { r = w + wrap + 1; // r %= size; // TODO: Can this happen now? } @@ -92,8 +112,6 @@ size_t lwrb_overwrite(lwrb_t* buff, const void* data, size_t btw) w %= size; } - - /* Step 4: The ring buffer is complete, this is a write op as well as possibly a read op */ atomic_store_explicit(&buff->w, w, memory_order_release); atomic_store_explicit(&buff->r, r, memory_order_release); @@ -105,8 +123,6 @@ size_t lwrb_overwrite(lwrb_t* buff, const void* data, size_t btw) return (btw); } - - /** * \brief Copy one ring buffer to another, upto the amount of data in the source, or amount * of data free in the destination. @@ -117,33 +133,33 @@ size_t lwrb_overwrite(lwrb_t* buff, const void* data, size_t btw) * As well as a write op to the destination, and may update the w index. For thread-safety mutexes may * be desired, see documentation. */ -size_t lwrb_copy(lwrb_t* dest, lwrb_t* src) -{ +size_t +lwrb_copy(lwrb_t* dest, lwrb_t* src) { size_t dest_w, src_r; size_t len_to_copy = BUF_MIN(lwrb_get_full(src), lwrb_get_free(dest)); size_t i; - if (!BUF_IS_VALID(dest) || !BUF_IS_VALID(src)) - { + if (!BUF_IS_VALID(dest) || !BUF_IS_VALID(src)) { return 0; } dest_w = atomic_load_explicit(&dest->w, memory_order_relaxed); - src_r = atomic_load_explicit(&src->r, memory_order_relaxed); + src_r = atomic_load_explicit(&src->r, memory_order_relaxed); /* For the lesser amount in source or free in destination, copy byte by byte */ - for (i = 0; i < len_to_copy; i++) - { + for (i = 0; i < len_to_copy; i++) { /* Handle roll-over / wrap for both source and destination indexes */ - if (dest_w >= dest->size) + if (dest_w >= dest->size) { dest_w = 0; + } - if (src_r >= src->size) + if (src_r >= src->size) { src_r = 0; + } dest->buff[dest_w++] = src->buff[src_r++]; - } + } atomic_store_explicit(&dest->w, dest_w, memory_order_release); atomic_store_explicit(&src->r, src_r, memory_order_release);