From 052d3773dea155c962e669ffbc062d133fd68cde Mon Sep 17 00:00:00 2001 From: Tilen Majerle Date: Thu, 4 Jan 2024 21:39:28 +0100 Subject: [PATCH 01/13] Update copyright to 2024 & AUTHORS file --- lwrb/src/include/lwrb/lwrb.h | 2 +- lwrb/src/lwrb/lwrb.c | 2 +- lwrb/src/lwrb/lwrb_ex.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lwrb/src/include/lwrb/lwrb.h b/lwrb/src/include/lwrb/lwrb.h index 6da7a20..f579773 100644 --- a/lwrb/src/include/lwrb/lwrb.h +++ b/lwrb/src/include/lwrb/lwrb.h @@ -4,7 +4,7 @@ */ /* - * Copyright (c) 2023 Tilen MAJERLE + * Copyright (c) 2024 Tilen MAJERLE * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/lwrb/src/lwrb/lwrb.c b/lwrb/src/lwrb/lwrb.c index 5e13468..36708da 100644 --- a/lwrb/src/lwrb/lwrb.c +++ b/lwrb/src/lwrb/lwrb.c @@ -4,7 +4,7 @@ */ /* - * Copyright (c) 2023 Tilen MAJERLE + * Copyright (c) 2024 Tilen MAJERLE * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation diff --git a/lwrb/src/lwrb/lwrb_ex.c b/lwrb/src/lwrb/lwrb_ex.c index 9893759..21e3fe4 100644 --- a/lwrb/src/lwrb/lwrb_ex.c +++ b/lwrb/src/lwrb/lwrb_ex.c @@ -4,7 +4,7 @@ */ /* - * Copyright (c) 2022 Tilen MAJERLE + * Copyright (c) 2024 Tilen MAJERLE * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation From fa3debda4536b0d959cab77882e27dff8f5a8494 Mon Sep 17 00:00:00 2001 From: Tilen Majerle Date: Wed, 7 Feb 2024 15:47:24 +0100 Subject: [PATCH 02/13] add improvements --- lwrb/src/lwrb/lwrb.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/lwrb/src/lwrb/lwrb.c b/lwrb/src/lwrb/lwrb.c index 36708da..5776730 100644 --- a/lwrb/src/lwrb/lwrb.c +++ b/lwrb/src/lwrb/lwrb.c @@ -347,7 +347,7 @@ lwrb_get_free(const lwrb_t* buff) { * even if buff->w or buff->r get changed during interrupt processing. * * They may change during load operation, important is that - * they do not change during if-elseif-else operations following these assignments. + * they do not change during if-else operations following these assignments. * * lwrb_get_free is only called for write purpose, and when in FIFO mode, then: * - buff->w pointer will not change by another process/interrupt because we are in write mode just now @@ -358,12 +358,10 @@ lwrb_get_free(const lwrb_t* buff) { w = LWRB_LOAD(buff->w, memory_order_relaxed); r = LWRB_LOAD(buff->r, memory_order_relaxed); - if (w == r) { - size = buff->size; - } else if (r > w) { - size = r - w; - } else { + if (w >= r) { size = buff->size - (w - r); + } else { + size = r - w; } /* Buffer free size is always 1 less than actual size */ @@ -393,7 +391,7 @@ lwrb_get_full(const lwrb_t* buff) { * even if buff->w or buff->r get changed during interrupt processing. * * They may change during load operation, important is that - * they do not change during if-elseif-else operations following these assignments. + * they do not change during if-else operations following these assignments. * * lwrb_get_full is only called for read purpose, and when in FIFO mode, then: * - buff->r pointer will not change by another process/interrupt because we are in read mode just now @@ -404,9 +402,7 @@ lwrb_get_full(const lwrb_t* buff) { w = LWRB_LOAD(buff->w, memory_order_relaxed); r = LWRB_LOAD(buff->r, memory_order_relaxed); - if (w == r) { - size = 0; - } else if (w > r) { + if (w >= r) { size = w - r; } else { size = buff->size - (r - w); From 775d180cc4d815ddf58e20487cb14be9b96ade5a Mon Sep 17 00:00:00 2001 From: Tilen Majerle Date: Wed, 7 Feb 2024 18:37:50 +0100 Subject: [PATCH 03/13] Add user argument --- CHANGELOG.md | 2 ++ lwrb/src/include/lwrb/lwrb.h | 3 +++ lwrb/src/lwrb/lwrb.c | 22 ++++++++++++++++++++++ 3 files changed, 27 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc668b8..9e0f4de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Develop +- Add user argument option + ## v3.1.0 - Preparation for `v3.1` diff --git a/lwrb/src/include/lwrb/lwrb.h b/lwrb/src/include/lwrb/lwrb.h index f579773..014b78a 100644 --- a/lwrb/src/include/lwrb/lwrb.h +++ b/lwrb/src/include/lwrb/lwrb.h @@ -102,6 +102,7 @@ typedef struct lwrb { lwrb_sz_atomic_t r; /*!< Next read pointer. Buffer is considered empty when `r == w` and full when `w == r - 1` */ lwrb_sz_atomic_t w; /*!< Next write pointer. Buffer is considered empty when `r == w` and full when `w == r - 1` */ lwrb_evt_fn evt_fn; /*!< Pointer to event callback function */ + void* arg; /*!< Event custom user argument */ } lwrb_t; uint8_t lwrb_init(lwrb_t* buff, void* buffdata, lwrb_sz_t size); @@ -109,6 +110,8 @@ uint8_t lwrb_is_ready(lwrb_t* buff); void lwrb_free(lwrb_t* buff); void lwrb_reset(lwrb_t* buff); void lwrb_set_evt_fn(lwrb_t* buff, lwrb_evt_fn fn); +void lwrb_set_arg(lwrb_t* buff, void* arg); +void* lwrb_get_arg(lwrb_t* buff); /* Read/Write functions */ lwrb_sz_t lwrb_write(lwrb_t* buff, const void* data, lwrb_sz_t btw); diff --git a/lwrb/src/lwrb/lwrb.c b/lwrb/src/lwrb/lwrb.c index 36708da..c0ff274 100644 --- a/lwrb/src/lwrb/lwrb.c +++ b/lwrb/src/lwrb/lwrb.c @@ -115,6 +115,28 @@ lwrb_set_evt_fn(lwrb_t* buff, lwrb_evt_fn evt_fn) { } } +/** + * \brief Set custom buffer argument, that can be retrieved in the event function + * \param[in] buff: Ring buffer instance + * \param[in] arg: Custom user argument + */ +void +lwrb_set_arg(lwrb_t* buff, void* arg) { + if (BUF_IS_VALID(buff)) { + buff->arg = arg; + } +} + +/** + * \brief Get custom buffer argument, previously set with \ref lwrb_set_arg + * \param[in] buff: Ring buffer instance + * \return User argument, previously set with \ref lwrb_set_arg + */ +void* +lwrb_get_arg(lwrb_t* buff) { + return buff != NULL ? buff->arg : NULL; +} + /** * \brief Write data to buffer. * Copies data from `data` array to buffer and marks buffer as full for maximum `btw` number of bytes From 318b49338d9c88b3b6ec86d14b0ff9b8740b3706 Mon Sep 17 00:00:00 2001 From: Tilen Majerle Date: Tue, 27 Feb 2024 21:20:23 +0100 Subject: [PATCH 04/13] Update license --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 3702ca4..42c1b5c 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2023 Tilen MAJERLE +Copyright (c) 2024 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 From b0adb9d5d31caf514a215af99a54485b0cfe79f5 Mon Sep 17 00:00:00 2001 From: Tilen Majerle Date: Tue, 19 Mar 2024 21:34:25 +0100 Subject: [PATCH 05/13] Update library CMake system, to support automatic creation of options file, if user doesn't provide one --- lwrb/library.cmake | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lwrb/library.cmake b/lwrb/library.cmake index 3e14f7a..ee74a16 100644 --- a/lwrb/library.cmake +++ b/lwrb/library.cmake @@ -1,4 +1,6 @@ # +# LIB_PREFIX: LWRB +# # This file provides set of variables for end user # and also generates one (or more) libraries, that can be added to the project using target_link_libraries(...) # @@ -8,6 +10,9 @@ # LWRB_COMPILE_DEFINITIONS: If defined, it provides "-D" definitions to the library build # +# Custom include directory +set(LWRB_CUSTOM_INC_DIR ${CMAKE_CURRENT_BINARY_DIR}/lib_inc) + # Library core sources set(lwrb_core_SRCS ${CMAKE_CURRENT_LIST_DIR}/src/lwrb/lwrb.c @@ -21,6 +26,7 @@ set(lwrb_ex_SRCS # Setup include directories set(lwrb_include_DIRS ${CMAKE_CURRENT_LIST_DIR}/src/include + ${LWPKT_CUSTOM_INC_DIR} ) # Register library to the system From b32c6451be9a3995b2622c1538881a49ed3575b0 Mon Sep 17 00:00:00 2001 From: Tilen Majerle Date: Sat, 23 Mar 2024 12:28:12 +0100 Subject: [PATCH 06/13] Update authors --- AUTHORS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index f4df17b..f0d5418 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,5 +1,5 @@ -Tilen Majerle Tilen Majerle +Tilen Majerle Jaedeok Kim Thomas Devoogdt LinJieqiang <517503838@qq.com> From 2f9b8f43a1c765854ab75c80dd549d149502d290 Mon Sep 17 00:00:00 2001 From: Tilen Majerle Date: Fri, 7 Jun 2024 08:46:21 +0200 Subject: [PATCH 07/13] Add parenthesis for bit check --- lwrb/src/lwrb/lwrb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lwrb/src/lwrb/lwrb.c b/lwrb/src/lwrb/lwrb.c index 6304330..ad37367 100644 --- a/lwrb/src/lwrb/lwrb.c +++ b/lwrb/src/lwrb/lwrb.c @@ -182,7 +182,7 @@ lwrb_write_ex(lwrb_t* buff, const void* data, lwrb_sz_t btw, lwrb_sz_t* bw, uint /* Calculate maximum number of bytes available to write */ free = lwrb_get_free(buff); /* If no memory, or if user wants to write ALL data but no enough space, exit early */ - if (free == 0 || (free < btw && flags & LWRB_FLAG_WRITE_ALL)) { + if (free == 0 || (free < btw && (flags & LWRB_FLAG_WRITE_ALL))) { return 0; } btw = BUF_MIN(free, btw); From 5b4367a1cee447877451c810947d7938e92c2224 Mon Sep 17 00:00:00 2001 From: Tilen Majerle Date: Sat, 22 Jun 2024 15:13:34 +0200 Subject: [PATCH 08/13] Improve the getting started documentation - how to add library to project with CMake config --- docs/get-started/index.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/get-started/index.rst b/docs/get-started/index.rst index fb6293d..b54a2a0 100644 --- a/docs/get-started/index.rst +++ b/docs/get-started/index.rst @@ -57,22 +57,22 @@ Update cloned to latest version Add library to project ^^^^^^^^^^^^^^^^^^^^^^ -At this point it is assumed that you have successfully download library, either cloned it or from releases page. +At this point it is assumed that you have successfully download library, either with ``git clone`` command or with manual download from the library releases page. Next step is to add the library to the project, by means of source files to compiler inputs and header files in search path. *CMake* is the main supported build system. Package comes with the ``CMakeLists.txt`` and ``library.cmake`` files, both located in the ``lwrb`` directory: -* ``CMakeLists.txt``: Is a wrapper and only includes ``library.cmake`` file. It is used if target application uses ``add_subdirectory`` and then uses ``target_link_libraries`` to include the library in the project -* ``library.cmake``: It is a fully configured set of variables. User must use ``include(path/to/library.cmake)`` to include the library and must manually add files/includes to the final target +* ``library.cmake``: It is a fully configured set of variables and with library definition. User can include this file to the project file with ``include(path/to/library.cmake)`` and then manually use the variables provided by the file, such as list of source files, include paths or necessary compiler definitions. It is up to the user to properly use the this file on its own. +* ``CMakeLists.txt``: It is a wrapper-only file and includes ``library.cmake`` file. It is used for when user wants to include the library to the main project by simply calling ``add_subdirectory`` **CMake** command, followed by ``target_link_libraries`` to add library as an external library. .. tip:: - Open ``library.cmake`` file and manually analyze all the possible variables you can set for full functionality. + Open ``library.cmake`` and analyze the provided information. Among variables, you can also find list of all possible exposed libraries for the user. If you do not use the *CMake*, you can do the following: * Copy ``lwrb`` folder to your project, it contains library files * Add ``lwrb/src/include`` folder to `include path` of your toolchain. This is where `C/C++` compiler can find the files during compilation process. Usually using ``-I`` flag -* Add source files from ``lwrb/src/`` folder to toolchain build. These files are built by `C/C++` compiler. CMake configuration comes with the library, allows users to include library in the project as **subdirectory** and **library**.y +* Add source files from ``lwrb/src/`` folder to toolchain build. These files are built by `C/C++` compilery * Build the project Minimal example code From 1d1f39da6fa18697e9669350fb1ad4f8918096ac Mon Sep 17 00:00:00 2001 From: Tilen Majerle Date: Sat, 22 Jun 2024 15:17:22 +0200 Subject: [PATCH 09/13] Update authors --- AUTHORS | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/AUTHORS b/AUTHORS index f0d5418..77bc3df 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,9 +1,9 @@ -Tilen Majerle Tilen Majerle -Jaedeok Kim -Thomas Devoogdt -LinJieqiang <517503838@qq.com> -jnz86 -Junde Yhi +Tofik Sonono Jackistang -Tofik Sonono \ No newline at end of file +Tilen Majerle +Junde Yhi +jnz86 +LinJieqiang <517503838@qq.com> +Thomas Devoogdt +Jaedeok Kim \ No newline at end of file From 1f0333bc039253f361c3566f2aa240b674845849 Mon Sep 17 00:00:00 2001 From: Tilen Majerle Date: Sat, 22 Jun 2024 18:59:06 +0200 Subject: [PATCH 10/13] Fx the docs --- lwrb/src/lwrb/lwrb.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/lwrb/src/lwrb/lwrb.c b/lwrb/src/lwrb/lwrb.c index ad37367..1c21007 100644 --- a/lwrb/src/lwrb/lwrb.c +++ b/lwrb/src/lwrb/lwrb.c @@ -139,7 +139,13 @@ lwrb_get_arg(lwrb_t* buff) { /** * \brief Write data to buffer. - * Copies data from `data` array to buffer and marks buffer as full for maximum `btw` number of bytes + * Copies data from `data` array to buffer and advances the write pointer for a maximum of `btw` number of bytes. + * + * It copies less if there is less memory available in the buffer. + * User must check the return value of the function and compare it to + * the requested write length, to determine if everything has been written + * + * \note Use \ref lwrb_write_ex for more advanced usage * * \param[in] buff: Ring buffer instance * \param[in] data: Pointer to data to write into buffer @@ -220,7 +226,11 @@ lwrb_write_ex(lwrb_t* buff, const void* data, lwrb_sz_t btw, lwrb_sz_t* bw, uint /** * \brief Read data from buffer. - * Copies data from buffer to `data` array and marks buffer as free for maximum `btr` number of bytes + * Copies data from `data` array to buffer and advances the read pointer for a maximum of `btr` number of bytes. + * + * It copies less if there is less data available in the buffer. + * + * \note Use \ref lwrb_read_ex for more advanced usage * * \param[in] buff: Ring buffer instance * \param[out] data: Pointer to output memory to copy buffer data to @@ -238,7 +248,7 @@ lwrb_read(lwrb_t* buff, void* data, lwrb_sz_t btr) { } /** - * \brief Write extended functionality + * \brief Read extended functionality * * \param buff: Ring buffer instance * \param data: Pointer to memory to write read data from buffer From 8f8028cb89fcafd45dadac96de574fbdc380d507 Mon Sep 17 00:00:00 2001 From: Tilen Majerle Date: Sat, 22 Jun 2024 19:17:08 +0200 Subject: [PATCH 11/13] Variable name updates to match the llvm coding rules (min 3 characters) --- .clang-format | 4 +- dev/main.c | 18 ++-- lwrb/src/include/lwrb/lwrb.h | 10 +- lwrb/src/lwrb/lwrb.c | 178 +++++++++++++++++++---------------- 4 files changed, 112 insertions(+), 98 deletions(-) diff --git a/.clang-format b/.clang-format index 0227352..33bb7d7 100644 --- a/.clang-format +++ b/.clang-format @@ -122,8 +122,8 @@ ObjCBlockIndentWidth: 2 ObjCBreakBeforeNestedBlockParam: true ObjCSpaceAfterProperty: false ObjCSpaceBeforeProtocolList: true -PenaltyBreakAssignment: 2 -PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakAssignment: 50 +PenaltyBreakBeforeFirstCallParameter: 9 PenaltyBreakComment: 300 PenaltyBreakFirstLessLess: 120 PenaltyBreakOpenParenthesis: 0 diff --git a/dev/main.c b/dev/main.c index 51de1b7..7eb798f 100644 --- a/dev/main.c +++ b/dev/main.c @@ -36,9 +36,9 @@ main() { #define RW_TEST(_w_exp_, _r_exp_, _rw_len_, _rw_exp_len_) \ do { \ - printf("W ptr: %u, R ptr: %u, R/W len: %u, as_expected: %u\r\n", (unsigned)buff.w, (unsigned)buff.r, \ + printf("W ptr: %u, R ptr: %u, R/W len: %u, as_expected: %u\r\n", (unsigned)buff.w_ptr, (unsigned)buff.r_ptr, \ (unsigned)(_rw_len_), \ - (unsigned)(buff.w == (_w_exp_) && buff.r == (_r_exp_) && (_rw_len_) == (_rw_exp_len_))); \ + (unsigned)(buff.w_ptr == (_w_exp_) && buff.r_ptr == (_r_exp_) && (_rw_len_) == (_rw_exp_len_))); \ } while (0) lwrb_reset(&buff); @@ -65,9 +65,9 @@ main() { #define RW_TEST(_w_exp_, _r_exp_, _success_, _rw_len_, _rw_exp_len_) \ do { \ - printf("W ptr: %u, R ptr: %u, R/W success: %u, R/W len: %u, as_expected: %u\r\n", (unsigned)buff.w, \ - (unsigned)buff.r, (unsigned)(_success_), (unsigned)(_rw_len_), \ - (unsigned)(buff.w == (_w_exp_) && buff.r == (_r_exp_) && (_rw_len_) == (_rw_exp_len_))); \ + printf("W ptr: %u, R ptr: %u, R/W success: %u, R/W len: %u, as_expected: %u\r\n", (unsigned)buff.w_ptr, \ + (unsigned)buff.r_ptr, (unsigned)(_success_), (unsigned)(_rw_len_), \ + (unsigned)(buff.w_ptr == (_w_exp_) && buff.r_ptr == (_r_exp_) && (_rw_len_) == (_rw_exp_len_))); \ } while (0) lwrb_reset(&buff); @@ -190,8 +190,8 @@ main() { FIND_TEST("678", 3, 0, 1); /* Restart by setting write and read as empty with offset */ - buff.w = 6; - buff.r = 6; + buff.w_ptr = 6; + buff.r_ptr = 6; lwrb_write(&buff, "12345678", 8); FIND_TEST("123", 3, 0, 1); /* Must find it */ @@ -200,8 +200,8 @@ main() { /* Restart by setting write and read as empty with offset */ /* This should generate data for search in overflow mode */ - buff.w = 8; - buff.r = 8; + buff.w_ptr = 8; + buff.r_ptr = 8; lwrb_write(&buff, "12345678", 8); FIND_TEST("1234", 3, 0, 1); /* Must find it */ diff --git a/lwrb/src/include/lwrb/lwrb.h b/lwrb/src/include/lwrb/lwrb.h index 014b78a..df5b7c4 100644 --- a/lwrb/src/include/lwrb/lwrb.h +++ b/lwrb/src/include/lwrb/lwrb.h @@ -99,10 +99,12 @@ typedef void (*lwrb_evt_fn)(struct lwrb* buff, lwrb_evt_type_t evt, lwrb_sz_t bp typedef struct lwrb { uint8_t* buff; /*!< Pointer to buffer data. Buffer is considered initialized when `buff != NULL` and `size > 0` */ lwrb_sz_t size; /*!< Size of buffer data. Size of actual buffer is `1` byte less than value holds */ - lwrb_sz_atomic_t r; /*!< Next read pointer. Buffer is considered empty when `r == w` and full when `w == r - 1` */ - lwrb_sz_atomic_t w; /*!< Next write pointer. Buffer is considered empty when `r == w` and full when `w == r - 1` */ - lwrb_evt_fn evt_fn; /*!< Pointer to event callback function */ - void* arg; /*!< Event custom user argument */ + lwrb_sz_atomic_t r_ptr; /*!< Next read pointer. + Buffer is considered empty when `r == w` and full when `w == r - 1` */ + lwrb_sz_atomic_t w_ptr; /*!< Next write pointer. + Buffer is considered empty when `r == w` and full when `w == r - 1` */ + lwrb_evt_fn evt_fn; /*!< Pointer to event callback function */ + void* arg; /*!< Event custom user argument */ } lwrb_t; uint8_t lwrb_init(lwrb_t* buff, void* buffdata, lwrb_sz_t size); diff --git a/lwrb/src/lwrb/lwrb.c b/lwrb/src/lwrb/lwrb.c index 1c21007..d247f44 100644 --- a/lwrb/src/lwrb/lwrb.c +++ b/lwrb/src/lwrb/lwrb.c @@ -75,8 +75,8 @@ lwrb_init(lwrb_t* buff, void* buffdata, lwrb_sz_t size) { buff->evt_fn = NULL; buff->size = size; buff->buff = buffdata; - LWRB_INIT(buff->w, 0); - LWRB_INIT(buff->r, 0); + LWRB_INIT(buff->w_ptr, 0); + LWRB_INIT(buff->r_ptr, 0); return 1; } @@ -178,8 +178,8 @@ lwrb_write(lwrb_t* buff, const void* data, lwrb_sz_t btw) { */ uint8_t lwrb_write_ex(lwrb_t* buff, const void* data, lwrb_sz_t btw, lwrb_sz_t* bw, uint16_t flags) { - lwrb_sz_t tocopy, free, buff_w_ptr; - const uint8_t* d = data; + lwrb_sz_t tocopy = 0, free = 0, w_ptr = 0; + const uint8_t* d_ptr = data; if (!BUF_IS_VALID(buff) || data == NULL || btw == 0) { return 0; @@ -192,30 +192,31 @@ lwrb_write_ex(lwrb_t* buff, const void* data, lwrb_sz_t btw, lwrb_sz_t* bw, uint return 0; } btw = BUF_MIN(free, btw); - buff_w_ptr = LWRB_LOAD(buff->w, memory_order_acquire); + w_ptr = LWRB_LOAD(buff->w_ptr, memory_order_acquire); /* Step 1: Write data to linear part of buffer */ - tocopy = BUF_MIN(buff->size - buff_w_ptr, btw); - BUF_MEMCPY(&buff->buff[buff_w_ptr], d, tocopy); - buff_w_ptr += tocopy; + tocopy = BUF_MIN(buff->size - w_ptr, btw); + BUF_MEMCPY(&buff->buff[w_ptr], d_ptr, tocopy); + d_ptr += tocopy; + w_ptr += tocopy; btw -= tocopy; /* Step 2: Write data to beginning of buffer (overflow part) */ if (btw > 0) { - BUF_MEMCPY(buff->buff, &d[tocopy], btw); - buff_w_ptr = btw; + BUF_MEMCPY(buff->buff, d_ptr, btw); + w_ptr = btw; } /* Step 3: Check end of buffer */ - if (buff_w_ptr >= buff->size) { - buff_w_ptr = 0; + if (w_ptr >= buff->size) { + w_ptr = 0; } /* * Write final value to the actual running variable. * This is to ensure no read operation can access intermediate data */ - LWRB_STORE(buff->w, buff_w_ptr, memory_order_release); + LWRB_STORE(buff->w_ptr, w_ptr, memory_order_release); BUF_SEND_EVT(buff, LWRB_EVT_WRITE, tocopy + btw); if (bw != NULL) { @@ -261,8 +262,8 @@ lwrb_read(lwrb_t* buff, void* data, lwrb_sz_t btr) { */ uint8_t lwrb_read_ex(lwrb_t* buff, void* data, lwrb_sz_t btr, lwrb_sz_t* br, uint16_t flags) { - lwrb_sz_t tocopy, full, buff_r_ptr; - uint8_t* d = data; + lwrb_sz_t tocopy = 0, full = 0, r_ptr = 0; + uint8_t* d_ptr = data; if (!BUF_IS_VALID(buff) || data == NULL || btr == 0) { return 0; @@ -274,30 +275,31 @@ lwrb_read_ex(lwrb_t* buff, void* data, lwrb_sz_t btr, lwrb_sz_t* br, uint16_t fl return 0; } btr = BUF_MIN(full, btr); - buff_r_ptr = LWRB_LOAD(buff->r, memory_order_acquire); + r_ptr = LWRB_LOAD(buff->r_ptr, memory_order_acquire); /* Step 1: Read data from linear part of buffer */ - tocopy = BUF_MIN(buff->size - buff_r_ptr, btr); - BUF_MEMCPY(d, &buff->buff[buff_r_ptr], tocopy); - buff_r_ptr += tocopy; + tocopy = BUF_MIN(buff->size - r_ptr, btr); + BUF_MEMCPY(d_ptr, &buff->buff[r_ptr], tocopy); + d_ptr += tocopy; + r_ptr += tocopy; btr -= tocopy; /* Step 2: Read data from beginning of buffer (overflow part) */ if (btr > 0) { - BUF_MEMCPY(&d[tocopy], buff->buff, btr); - buff_r_ptr = btr; + BUF_MEMCPY(d_ptr, buff->buff, btr); + r_ptr = btr; } /* Step 3: Check end of buffer */ - if (buff_r_ptr >= buff->size) { - buff_r_ptr = 0; + if (r_ptr >= buff->size) { + r_ptr = 0; } /* * Write final value to the actual running variable. * This is to ensure no write operation can access intermediate data */ - LWRB_STORE(buff->r, buff_r_ptr, memory_order_release); + LWRB_STORE(buff->r_ptr, r_ptr, memory_order_release); BUF_SEND_EVT(buff, LWRB_EVT_READ, tocopy + btr); if (br != NULL) { @@ -316,8 +318,8 @@ lwrb_read_ex(lwrb_t* buff, void* data, lwrb_sz_t btr, lwrb_sz_t* br, uint16_t fl */ lwrb_sz_t lwrb_peek(const lwrb_t* buff, lwrb_sz_t skip_count, void* data, lwrb_sz_t btp) { - lwrb_sz_t full, tocopy, r; - uint8_t* d = data; + lwrb_sz_t full = 0, tocopy = 0, r_ptr = 0; + uint8_t* d_ptr = data; if (!BUF_IS_VALID(buff) || data == NULL || btp == 0) { return 0; @@ -331,11 +333,11 @@ lwrb_peek(const lwrb_t* buff, lwrb_sz_t skip_count, void* data, lwrb_sz_t btp) { if (skip_count >= full) { return 0; } - r = LWRB_LOAD(buff->r, memory_order_relaxed); - r += skip_count; + r_ptr = LWRB_LOAD(buff->r_ptr, memory_order_relaxed); + r_ptr += skip_count; full -= skip_count; - if (r >= buff->size) { - r -= buff->size; + if (r_ptr >= buff->size) { + r_ptr -= buff->size; } /* Check maximum number of bytes available to read after skip */ @@ -345,13 +347,14 @@ lwrb_peek(const lwrb_t* buff, lwrb_sz_t skip_count, void* data, lwrb_sz_t btp) { } /* Step 1: Read data from linear part of buffer */ - tocopy = BUF_MIN(buff->size - r, btp); - BUF_MEMCPY(d, &buff->buff[r], tocopy); + tocopy = BUF_MIN(buff->size - r_ptr, btp); + BUF_MEMCPY(d_ptr, &buff->buff[r_ptr], tocopy); + d_ptr += tocopy; btp -= tocopy; /* Step 2: Read data from beginning of buffer (overflow part) */ if (btp > 0) { - BUF_MEMCPY(&d[tocopy], buff->buff, btp); + BUF_MEMCPY(d_ptr, buff->buff, btp); } return tocopy + btp; } @@ -363,7 +366,7 @@ lwrb_peek(const lwrb_t* buff, lwrb_sz_t skip_count, void* data, lwrb_sz_t btp) { */ lwrb_sz_t lwrb_get_free(const lwrb_t* buff) { - lwrb_sz_t size, w, r; + lwrb_sz_t size = 0, w_ptr = 0, r_ptr = 0; if (!BUF_IS_VALID(buff)) { return 0; @@ -387,13 +390,13 @@ lwrb_get_free(const lwrb_t* buff) { * buffer will see "free size" less than it actually is. This is not a problem, application can * always try again to write more data to remaining free memory that was read just during copy operation */ - w = LWRB_LOAD(buff->w, memory_order_relaxed); - r = LWRB_LOAD(buff->r, memory_order_relaxed); + w_ptr = LWRB_LOAD(buff->w_ptr, memory_order_relaxed); + r_ptr = LWRB_LOAD(buff->r_ptr, memory_order_relaxed); - if (w >= r) { - size = buff->size - (w - r); + if (w_ptr >= r_ptr) { + size = buff->size - (w_ptr - r_ptr); } else { - size = r - w; + size = r_ptr - w_ptr; } /* Buffer free size is always 1 less than actual size */ @@ -407,7 +410,7 @@ lwrb_get_free(const lwrb_t* buff) { */ lwrb_sz_t lwrb_get_full(const lwrb_t* buff) { - lwrb_sz_t size, w, r; + lwrb_sz_t size = 0, w_ptr = 0, r_ptr = 0; if (!BUF_IS_VALID(buff)) { return 0; @@ -431,13 +434,13 @@ lwrb_get_full(const lwrb_t* buff) { * buffer will see "full size" less than it really is. This is not a problem, application can * always try again to read more data from remaining full memory that was written just during copy operation */ - w = LWRB_LOAD(buff->w, memory_order_relaxed); - r = LWRB_LOAD(buff->r, memory_order_relaxed); + w_ptr = LWRB_LOAD(buff->w_ptr, memory_order_relaxed); + r_ptr = LWRB_LOAD(buff->r_ptr, memory_order_relaxed); - if (w >= r) { - size = w - r; + if (w_ptr >= r_ptr) { + size = w_ptr - r_ptr; } else { - size = buff->size - (r - w); + size = buff->size - (r_ptr - w_ptr); } return size; } @@ -451,8 +454,8 @@ lwrb_get_full(const lwrb_t* buff) { void lwrb_reset(lwrb_t* buff) { if (BUF_IS_VALID(buff)) { - LWRB_STORE(buff->w, 0, memory_order_release); - LWRB_STORE(buff->r, 0, memory_order_release); + LWRB_STORE(buff->w_ptr, 0, memory_order_release); + LWRB_STORE(buff->r_ptr, 0, memory_order_release); BUF_SEND_EVT(buff, LWRB_EVT_RESET, 0); } } @@ -464,10 +467,13 @@ lwrb_reset(lwrb_t* buff) { */ void* lwrb_get_linear_block_read_address(const lwrb_t* buff) { + lwrb_sz_t ptr = 0; + if (!BUF_IS_VALID(buff)) { return NULL; } - return &buff->buff[buff->r]; + ptr = LWRB_LOAD(buff->r_ptr, memory_order_relaxed); + return &buff->buff[ptr]; } /** @@ -477,7 +483,7 @@ lwrb_get_linear_block_read_address(const lwrb_t* buff) { */ lwrb_sz_t lwrb_get_linear_block_read_length(const lwrb_t* buff) { - lwrb_sz_t len, w, r; + lwrb_sz_t len = 0, w_ptr = 0, r_ptr = 0; if (!BUF_IS_VALID(buff)) { return 0; @@ -487,13 +493,13 @@ lwrb_get_linear_block_read_length(const lwrb_t* buff) { * Use temporary values in case they are changed during operations. * See lwrb_buff_free or lwrb_buff_full functions for more information why this is OK. */ - w = LWRB_LOAD(buff->w, memory_order_relaxed); - r = LWRB_LOAD(buff->r, memory_order_relaxed); + w_ptr = LWRB_LOAD(buff->w_ptr, memory_order_relaxed); + r_ptr = LWRB_LOAD(buff->r_ptr, memory_order_relaxed); - if (w > r) { - len = w - r; - } else if (r > w) { - len = buff->size - r; + if (w_ptr > r_ptr) { + len = w_ptr - r_ptr; + } else if (r_ptr > w_ptr) { + len = buff->size - r_ptr; } else { len = 0; } @@ -511,7 +517,7 @@ lwrb_get_linear_block_read_length(const lwrb_t* buff) { */ lwrb_sz_t lwrb_skip(lwrb_t* buff, lwrb_sz_t len) { - lwrb_sz_t full, r; + lwrb_sz_t full = 0, r_ptr = 0; if (!BUF_IS_VALID(buff) || len == 0) { return 0; @@ -519,12 +525,12 @@ lwrb_skip(lwrb_t* buff, lwrb_sz_t len) { full = lwrb_get_full(buff); len = BUF_MIN(len, full); - r = LWRB_LOAD(buff->r, memory_order_acquire); - r += len; - if (r >= buff->size) { - r -= buff->size; + r_ptr = LWRB_LOAD(buff->r_ptr, memory_order_acquire); + r_ptr += len; + if (r_ptr >= buff->size) { + r_ptr -= buff->size; } - LWRB_STORE(buff->r, r, memory_order_release); + LWRB_STORE(buff->r_ptr, r_ptr, memory_order_release); BUF_SEND_EVT(buff, LWRB_EVT_READ, len); return len; } @@ -536,10 +542,13 @@ lwrb_skip(lwrb_t* buff, lwrb_sz_t len) { */ void* lwrb_get_linear_block_write_address(const lwrb_t* buff) { + lwrb_sz_t ptr = 0; + if (!BUF_IS_VALID(buff)) { return NULL; } - return &buff->buff[buff->w]; + ptr = LWRB_LOAD(buff->w_ptr, memory_order_relaxed); + return &buff->buff[ptr]; } /** @@ -549,7 +558,7 @@ lwrb_get_linear_block_write_address(const lwrb_t* buff) { */ lwrb_sz_t lwrb_get_linear_block_write_length(const lwrb_t* buff) { - lwrb_sz_t len, w, r; + lwrb_sz_t len = 0, w_ptr = 0, r_ptr = 0; if (!BUF_IS_VALID(buff)) { return 0; @@ -559,17 +568,17 @@ lwrb_get_linear_block_write_length(const lwrb_t* buff) { * Use temporary values in case they are changed during operations. * See lwrb_buff_free or lwrb_buff_full functions for more information why this is OK. */ - w = LWRB_LOAD(buff->w, memory_order_relaxed); - r = LWRB_LOAD(buff->r, memory_order_relaxed); + w_ptr = LWRB_LOAD(buff->w_ptr, memory_order_relaxed); + r_ptr = LWRB_LOAD(buff->r_ptr, memory_order_relaxed); - if (w >= r) { - len = buff->size - w; + if (w_ptr >= r_ptr) { + len = buff->size - w_ptr; /* * When read pointer is 0, * maximal length is one less as if too many bytes * are written, buffer would be considered empty again (r == w) */ - if (r == 0) { + if (r_ptr == 0) { /* * Cannot overflow: * - If r is not 0, statement does not get called @@ -578,7 +587,7 @@ lwrb_get_linear_block_write_length(const lwrb_t* buff) { --len; } } else { - len = r - w - 1; + len = r_ptr - w_ptr - 1; } return len; } @@ -595,7 +604,7 @@ lwrb_get_linear_block_write_length(const lwrb_t* buff) { */ lwrb_sz_t lwrb_advance(lwrb_t* buff, lwrb_sz_t len) { - lwrb_sz_t free, w; + lwrb_sz_t free = 0, w_ptr = 0; if (!BUF_IS_VALID(buff) || len == 0) { return 0; @@ -604,12 +613,12 @@ lwrb_advance(lwrb_t* buff, lwrb_sz_t len) { /* Use local variables before writing back to main structure */ free = lwrb_get_free(buff); len = BUF_MIN(len, free); - w = LWRB_LOAD(buff->w, memory_order_acquire); - w += len; - if (w >= buff->size) { - w -= buff->size; + w_ptr = LWRB_LOAD(buff->w_ptr, memory_order_acquire); + w_ptr += len; + if (w_ptr >= buff->size) { + w_ptr -= buff->size; } - LWRB_STORE(buff->w, w, memory_order_release); + LWRB_STORE(buff->w_ptr, w_ptr, memory_order_release); BUF_SEND_EVT(buff, LWRB_EVT_WRITE, len); return len; } @@ -629,7 +638,7 @@ lwrb_advance(lwrb_t* buff, lwrb_sz_t len) { */ uint8_t lwrb_find(const lwrb_t* buff, const void* bts, lwrb_sz_t len, lwrb_sz_t start_offset, lwrb_sz_t* found_idx) { - lwrb_sz_t full, r, max_x; + lwrb_sz_t full = 0, r_ptr = 0, buff_r_ptr = 0, max_x = 0; uint8_t found = 0; const uint8_t* needle = bts; @@ -644,25 +653,28 @@ lwrb_find(const lwrb_t* buff, const void* bts, lwrb_sz_t len, lwrb_sz_t start_of return 0; } + /* Get actual buffer read pointer for this search */ + buff_r_ptr = LWRB_LOAD(buff->r_ptr, memory_order_relaxed); + /* Max number of for loops is buff_full - input_len - start_offset of buffer length */ max_x = full - len; for (lwrb_sz_t skip_x = start_offset; !found && skip_x <= max_x; ++skip_x) { found = 1; /* Found by default */ /* Prepare the starting point for reading */ - r = buff->r + skip_x; - if (r >= buff->size) { - r -= buff->size; + r_ptr = buff_r_ptr + skip_x; + if (r_ptr >= buff->size) { + r_ptr -= buff->size; } /* Search in the buffer */ - for (lwrb_sz_t i = 0; i < len; ++i) { - if (buff->buff[r] != needle[i]) { + for (lwrb_sz_t idx = 0; idx < len; ++idx) { + if (buff->buff[r_ptr] != needle[idx]) { found = 0; break; } - if (++r >= buff->size) { - r = 0; + if (++r_ptr >= buff->size) { + r_ptr = 0; } } if (found) { From 9baa7070c4ada4e8eae04ef3d83d0d742fc9ebe0 Mon Sep 17 00:00:00 2001 From: Tilen Majerle Date: Sat, 22 Jun 2024 19:19:33 +0200 Subject: [PATCH 12/13] read/write: Fix the parameters name --- lwrb/src/include/lwrb/lwrb.h | 4 ++-- lwrb/src/lwrb/lwrb.c | 17 +++++++++-------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/lwrb/src/include/lwrb/lwrb.h b/lwrb/src/include/lwrb/lwrb.h index df5b7c4..d8126ce 100644 --- a/lwrb/src/include/lwrb/lwrb.h +++ b/lwrb/src/include/lwrb/lwrb.h @@ -121,8 +121,8 @@ lwrb_sz_t lwrb_read(lwrb_t* buff, void* data, lwrb_sz_t btr); lwrb_sz_t lwrb_peek(const lwrb_t* buff, lwrb_sz_t skip_count, void* data, lwrb_sz_t btp); /* Extended read/write functions */ -uint8_t lwrb_write_ex(lwrb_t* buff, const void* data, lwrb_sz_t btw, lwrb_sz_t* bw, uint16_t flags); -uint8_t lwrb_read_ex(lwrb_t* buff, void* data, lwrb_sz_t btr, lwrb_sz_t* br, uint16_t flags); +uint8_t lwrb_write_ex(lwrb_t* buff, const void* data, lwrb_sz_t btw, lwrb_sz_t* bwritten, uint16_t flags); +uint8_t lwrb_read_ex(lwrb_t* buff, void* data, lwrb_sz_t btr, lwrb_sz_t* bread, uint16_t flags); /* Buffer size information */ lwrb_sz_t lwrb_get_free(const lwrb_t* buff); diff --git a/lwrb/src/lwrb/lwrb.c b/lwrb/src/lwrb/lwrb.c index d247f44..aa1e413 100644 --- a/lwrb/src/lwrb/lwrb.c +++ b/lwrb/src/lwrb/lwrb.c @@ -170,14 +170,14 @@ lwrb_write(lwrb_t* buff, const void* data, lwrb_sz_t btw) { * \param buff: Ring buffer instance * \param data: Pointer to data to write into buffer * \param btw: Number of bytes to write - * \param bw: Output pointer to write number of bytes written + * \param bwritten: Output pointer to write number of bytes written into the buffer * \param flags: Optional flags. * \ref LWRB_FLAG_WRITE_ALL: Request to write all data (up to btw). * Will early return if no memory available * \return `1` if write operation OK, `0` otherwise */ uint8_t -lwrb_write_ex(lwrb_t* buff, const void* data, lwrb_sz_t btw, lwrb_sz_t* bw, uint16_t flags) { +lwrb_write_ex(lwrb_t* buff, const void* data, lwrb_sz_t btw, lwrb_sz_t* bwritten, uint16_t flags) { lwrb_sz_t tocopy = 0, free = 0, w_ptr = 0; const uint8_t* d_ptr = data; @@ -219,8 +219,8 @@ lwrb_write_ex(lwrb_t* buff, const void* data, lwrb_sz_t btw, lwrb_sz_t* bw, uint LWRB_STORE(buff->w_ptr, w_ptr, memory_order_release); BUF_SEND_EVT(buff, LWRB_EVT_WRITE, tocopy + btw); - if (bw != NULL) { - *bw = tocopy + btw; + if (bwritten != NULL) { + *bwritten = tocopy + btw; } return 1; } @@ -254,14 +254,15 @@ lwrb_read(lwrb_t* buff, void* data, lwrb_sz_t btr) { * \param buff: Ring buffer instance * \param data: Pointer to memory to write read data from buffer * \param btr: Number of bytes to read - * \param br: Output pointer to write number of bytes read + * \param bread: Output pointer to write number of bytes read from buffer and written to the + * output `data` variable * \param flags: Optional flags * \ref LWRB_FLAG_READ_ALL: Request to read all data (up to btr). * Will early return if no enough bytes in the buffer * \return `1` if read operation OK, `0` otherwise */ uint8_t -lwrb_read_ex(lwrb_t* buff, void* data, lwrb_sz_t btr, lwrb_sz_t* br, uint16_t flags) { +lwrb_read_ex(lwrb_t* buff, void* data, lwrb_sz_t btr, lwrb_sz_t* bread, uint16_t flags) { lwrb_sz_t tocopy = 0, full = 0, r_ptr = 0; uint8_t* d_ptr = data; @@ -302,8 +303,8 @@ lwrb_read_ex(lwrb_t* buff, void* data, lwrb_sz_t btr, lwrb_sz_t* br, uint16_t fl LWRB_STORE(buff->r_ptr, r_ptr, memory_order_release); BUF_SEND_EVT(buff, LWRB_EVT_READ, tocopy + btr); - if (br != NULL) { - *br = tocopy + btr; + if (bread != NULL) { + *bread = tocopy + btr; } return 1; } From 2b53a8331a1bd539678b95bd12088a20a7e5a04c Mon Sep 17 00:00:00 2001 From: Tilen Majerle Date: Sat, 22 Jun 2024 19:21:58 +0200 Subject: [PATCH 13/13] Start 3.2.0 release --- CHANGELOG.md | 5 ++++- library.json | 2 +- lwrb/src/include/lwrb/lwrb.h | 2 +- lwrb/src/lwrb/lwrb.c | 2 +- lwrb/src/lwrb/lwrb_ex.c | 2 +- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e0f4de..328a06c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,10 @@ ## Develop +## v3.2.0 + - Add user argument option +- Improve the variable names to better conform *LLVM* tidy config ## v3.1.0 @@ -19,7 +22,7 @@ - Add `lwrb_move` and `lwrb_overwrite` - Fix `lwrb_find` which failed to properly search for tokens at corner cases -## v3.1.0-RC1 +## v3.0.0-RC1 - Split CMakeLists.txt files between library and executable - Change license year to 2022 diff --git a/library.json b/library.json index a89971a..440fc06 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "LwRB", - "version": "3.1.0", + "version": "3.2.0", "description": "Lightweight general purpose ring buffer with optimizations for embedded systems", "keywords": "buffer, ring buffer, library, rb, cyclic", "repository": { diff --git a/lwrb/src/include/lwrb/lwrb.h b/lwrb/src/include/lwrb/lwrb.h index d8126ce..524fa50 100644 --- a/lwrb/src/include/lwrb/lwrb.h +++ b/lwrb/src/include/lwrb/lwrb.h @@ -29,7 +29,7 @@ * This file is part of LwRB - Lightweight ring buffer library. * * Author: Tilen MAJERLE - * Version: v3.1.0 + * Version: v3.2.0 */ #ifndef LWRB_HDR_H #define LWRB_HDR_H diff --git a/lwrb/src/lwrb/lwrb.c b/lwrb/src/lwrb/lwrb.c index aa1e413..6e724c8 100644 --- a/lwrb/src/lwrb/lwrb.c +++ b/lwrb/src/lwrb/lwrb.c @@ -29,7 +29,7 @@ * This file is part of LwRB - Lightweight ring buffer library. * * Author: Tilen MAJERLE - * Version: v3.1.0 + * Version: v3.2.0 */ #include "lwrb/lwrb.h" diff --git a/lwrb/src/lwrb/lwrb_ex.c b/lwrb/src/lwrb/lwrb_ex.c index 21e3fe4..4d67017 100644 --- a/lwrb/src/lwrb/lwrb_ex.c +++ b/lwrb/src/lwrb/lwrb_ex.c @@ -29,7 +29,7 @@ * This file is part of LwRB - Lightweight ring buffer library. * * Author: Tilen MAJERLE - * Version: v3.1.0 + * Version: v3.2.0 */ #include "lwrb/lwrb.h"