From 2cb358908a4f660b37544afa3c044222df174e61 Mon Sep 17 00:00:00 2001 From: John Sanpe Date: Wed, 27 Mar 2024 17:25:36 +0800 Subject: [PATCH 01/31] feat testsuite: added initial functions Signed-off-by: John Sanpe --- CMakeLists.txt | 6 + examples/time.h | 6 +- testsuite/CMakeLists.txt | 9 ++ testsuite/array/CMakeLists.txt | 11 ++ testsuite/array/fuzzy.c | 49 +++++++ testsuite/build.cmake | 12 ++ testsuite/testsuite.c | 254 +++++++++++++++++++++++++++++++++ testsuite/testsuite.cmake | 17 +++ testsuite/testsuite.h | 76 ++++++++++ 9 files changed, 437 insertions(+), 3 deletions(-) create mode 100644 testsuite/CMakeLists.txt create mode 100644 testsuite/array/CMakeLists.txt create mode 100644 testsuite/array/fuzzy.c create mode 100644 testsuite/build.cmake create mode 100644 testsuite/testsuite.c create mode 100644 testsuite/testsuite.cmake create mode 100644 testsuite/testsuite.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 5dddbf6c..80976ac0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,6 +41,7 @@ commit_branch(BFDEV_BRANCH) option(BFDEV_DEVEL "Enable development mode" OFF) option(BFDEV_STRICT "Enable strict compilation" ON) option(BFDEV_EXAMPLES "Build examples" OFF) +option(BFDEV_TESTSUITE "Build testsuite" ON) option(BFDEV_ASAN "Enable Address Sanitizer" OFF) option(BFDEV_UBSAN "Enable Undefined Behaviour Sanitizer" OFF) @@ -101,6 +102,11 @@ if(BFDEV_EXAMPLES) add_subdirectory(examples) endif() +if(BFDEV_TESTSUITE) + enable_testing() + add_subdirectory(testsuite) +endif() + if(${CMAKE_PROJECT_NAME} STREQUAL "bfdev") add_library(bfdev_static STATIC ${BFDEV_LIBRARY}) add_library(bfdev_shared SHARED ${BFDEV_LIBRARY}) diff --git a/examples/time.h b/examples/time.h index 2bd02f21..1993ffcb 100644 --- a/examples/time.h +++ b/examples/time.h @@ -17,17 +17,17 @@ static inline void time_dump(double ticks, clock_t start, clock_t end, struct tms *stms, struct tms *etms) { - bfdev_log_info( + bfdev_log_debug( "\treal time: %lf\n", (end - start) / ticks ); - bfdev_log_info( + bfdev_log_debug( "\tuser time: %lf\n", (etms->tms_utime - stms->tms_utime) / ticks ); - bfdev_log_info( + bfdev_log_debug( "\tkern time: %lf\n", (etms->tms_stime - stms->tms_stime) / ticks ); diff --git a/testsuite/CMakeLists.txt b/testsuite/CMakeLists.txt new file mode 100644 index 00000000..5a98ac48 --- /dev/null +++ b/testsuite/CMakeLists.txt @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright(c) 2024 John Sanpe +# + +include(build.cmake) +include(testsuite.cmake) + +add_subdirectory(array) diff --git a/testsuite/array/CMakeLists.txt b/testsuite/array/CMakeLists.txt new file mode 100644 index 00000000..7f24943d --- /dev/null +++ b/testsuite/array/CMakeLists.txt @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright(c) 2024 John Sanpe +# + +testsuite_target(array-fuzzy + ${CMAKE_CURRENT_LIST_DIR}/fuzzy.c + ${PROJECT_SOURCE_DIR}/src/array.c +) + +add_test(array-fuzzy array-fuzzy) diff --git a/testsuite/array/fuzzy.c b/testsuite/array/fuzzy.c new file mode 100644 index 00000000..3ae4e63f --- /dev/null +++ b/testsuite/array/fuzzy.c @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright(c) 2024 John Sanpe + */ + +#include + +#define TEST_LOOP 4096 +#define TEST_SIZE 65536 + +TESTSUITE( + "array:resize", NULL, NULL, + "array resize fuzzy test" +) { + BFDEV_DEFINE_ARRAY(array, NULL, 1); + unsigned int count; + int retval; + + retval = 0; + for (count = 0; count < TEST_LOOP; ++count) { + retval = array_resize(&array, rand() % TEST_SIZE); + if (retval) + break; + } + + bfdev_array_release(&array); + + return retval; +} + +TESTSUITE( + "array:apply", NULL, NULL, + "array apply fuzzy test" +) { + BFDEV_DEFINE_ARRAY(array, NULL, 1); + unsigned int count; + int retval; + + retval = 0; + for (count = 0; count < TEST_LOOP; ++count) { + retval = array_apply(&array, rand() % TEST_SIZE); + if (retval) + break; + } + + bfdev_array_release(&array); + + return retval; +} diff --git a/testsuite/build.cmake b/testsuite/build.cmake new file mode 100644 index 00000000..54b44375 --- /dev/null +++ b/testsuite/build.cmake @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright(c) 2024 John Sanpe +# + +set(TESTSUITE_SOURCE + ${CMAKE_CURRENT_LIST_DIR}/testsuite.c + ${CMAKE_CURRENT_LIST_DIR}/testsuite.h +) + +include_directories(${CMAKE_CURRENT_LIST_DIR}) +add_library(testsuite OBJECT ${TESTSUITE_SOURCE}) diff --git a/testsuite/testsuite.c b/testsuite/testsuite.c new file mode 100644 index 00000000..1baac51e --- /dev/null +++ b/testsuite/testsuite.c @@ -0,0 +1,254 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright(c) 2024 John Sanpe + */ + +#define MODULE_NAME "bfdev-testsuite" +#define bfdev_log_fmt(fmt) MODULE_NAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include + +#include +#include "../examples/time.h" + +#define MESSAGE_PASS "\e[0m[\e[32mPASS\e[0m]" +#define MESSAGE_FAIL "\e[0m[\e[31mFAIL\e[0m]" +#define DEFAULT_LOOPS 3 + +static BFDEV_LIST_HEAD(tests); + +#define list_to_testsuite(ptr) \ + bfdev_container_of(ptr, struct testsuite, list) + +static long +testsuite_cmp(const bfdev_list_head_t *node1, + const bfdev_list_head_t *node2, void *pdata) +{ + struct testsuite *test1, *test2; + int retval; + + test1 = list_to_testsuite(node1); + test2 = list_to_testsuite(node2); + + retval = strcmp(test1->name, test2->name); + if (retval) + return retval; + + return 0; +} + +static struct testsuite * +testsuite_find(const char *name) +{ + struct testsuite *walk; + + bfdev_list_for_each_entry(walk, &tests, list) { + if (!strcmp(name, walk->name)) + return walk; + } + + return NULL; +} + +static bool +testsuite_exist(struct testsuite *test) +{ + struct testsuite *walk; + + bfdev_list_for_each_entry(walk, &tests, list) { + if (test == walk) + return true; + } + + return false; +} + +int +testsuite_register(struct testsuite *test) +{ + if (!test->testing || !test->name) + return -BFDEV_EINVAL; + + if (testsuite_find(test->name)) + return -BFDEV_EALREADY; + + bfdev_log_info("register '%s'\n", test->name); + bfdev_list_add(&tests, &test->list); + + return -BFDEV_ENOERR; +} + +void +testsuite_unregister(struct testsuite *test) +{ + if (!testsuite_exist(test)) + return; + + bfdev_log_debug("unregister '%s'\n", test->name); + bfdev_list_del(&test->list); +} + +static struct testsuite * +testsuite_iter(const char *name, struct testsuite *iter) +{ + int retval; + + bfdev_list_for_each_entry_continue(iter, &tests, list) { + retval = strcmp(iter->name, name); + if (!retval || retval == ':') + return iter; + } + + return NULL; +} + +static int +trigger_testsuite(struct testsuite *test, unsigned int loops, + int argc, const char *argv[]) +{ + unsigned int count; + const char *ename, *einfo; + void *data; + int retval; + + bfdev_log_notice("================================\n"); + bfdev_log_notice("Trigger object {%s}\n", test->name); + + data = NULL; + if (test->prepare) { + bfdev_log_debug("Preparing...\n"); + EXAMPLE_TIME_STATISTICAL( + data = test->prepare(argc, argv); + 0; + ); + + retval = BFDEV_PTR_INVAL_ZERO(data); + bfdev_log_debug("Prepared: (%d) %s\n", retval, + retval ? MESSAGE_FAIL : MESSAGE_PASS); + if (bfdev_unlikely(retval)) + return retval; + } + + for (count = 1; count <= loops; ++count) { + bfdev_log_debug("Testing loop%u...\n", count); + EXAMPLE_TIME_STATISTICAL( + retval = test->testing(argc, argv, data); + 0; + ); + + bfdev_log_notice("Tested (%d) %s\n", retval, + retval ? MESSAGE_FAIL : MESSAGE_PASS); + if (bfdev_unlikely(retval)) { + ename = bfdev_errname(retval, &einfo); + bfdev_log_err("Return status (%s) %s\n", ename, einfo); + break; + } + } + + if (test->release) { + bfdev_log_notice("Releasing...\n"); + test->release(data); + bfdev_log_notice("Released.\n"); + } + + return -BFDEV_ENOERR; +} + +static int +trigger_overall(unsigned int loops) +{ + struct testsuite *walk; + int retval; + + bfdev_list_for_each_entry(walk, &tests, list) { + retval = trigger_testsuite(walk, loops, 0, NULL); + if (bfdev_unlikely(retval)) + return retval; + } + + return -BFDEV_ENOERR; +} + +static void +usage(void) +{ + struct testsuite *walk; + unsigned int align; + + bfdev_log_print("usage: testsuite [option] [group[:name]] ...\n"); + bfdev_log_print("\t-c number of repetitions for each test\n"); + bfdev_log_print("\t-d do not print debugging information\n"); + bfdev_log_print("\t-h show this help\n\n"); + + align = 0; + bfdev_list_for_each_entry(walk, &tests, list) + bfdev_max_adj(align, strlen(walk->name)); + + bfdev_log_print("Supported tests:\n"); + bfdev_list_for_each_entry(walk, &tests, list) + bfdev_log_print("\t%-*s - %s\n", align + 1, walk->name, walk->desc); +} + +int +main(int argc, char *const argv[]) +{ + unsigned int loops, count; + char arg; + int retval; + + setbuf(stdout, NULL); + setbuf(stderr, NULL); + + loops = DEFAULT_LOOPS; + bfdev_list_sort(&tests, testsuite_cmp, NULL); + + for (;;) { + arg = getopt(argc, argv, "c:dh"); + if (arg == -1) + break; + + switch (arg) { + case 'c': + loops = atoi(optarg); + if (!loops) + goto usage; + break; + + case 'd': + bfdev_log_default.record_level = BFDEV_LEVEL_INFO; + break; + + case 'h': default: + goto usage; + } + } + + if (optind == argc) + return trigger_overall(loops); + + for (count = optind; count < argc; ++count) { + struct testsuite *test; + char *target; + + target = argv[count]; + test = list_to_testsuite(&tests); + + while ((test = testsuite_iter(target, test))) { + retval = trigger_testsuite(test, loops, 0, NULL); + if (retval) + return retval; + } + } + + return -BFDEV_ENOERR; + +usage: + usage(); + return -BFDEV_EINVAL; +} diff --git a/testsuite/testsuite.cmake b/testsuite/testsuite.cmake new file mode 100644 index 00000000..bb84f082 --- /dev/null +++ b/testsuite/testsuite.cmake @@ -0,0 +1,17 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright(c) 2024 John Sanpe +# + +function(testsuite_target name src replace) + string( + REGEX REPLACE ${replace} "" + TESTSUIT_OBJECT "${BFDEV_LIBRARY}" + ) + + add_library(target OBJECT ${src}) + target_compile_options(target PRIVATE -include ${replace}) + + add_executable("${name}" ${TESTSUIT_OBJECT}) + target_link_libraries("${name}" testsuite target) +endfunction() diff --git a/testsuite/testsuite.h b/testsuite/testsuite.h new file mode 100644 index 00000000..ed2152ac --- /dev/null +++ b/testsuite/testsuite.h @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright(c) 2024 John Sanpe + */ + +#ifndef _BFDEV_TESTSUITE_H_ +#define _BFDEV_TESTSUITE_H_ + +#include +#include +#include +#include +#include +#include + +BFDEV_BEGIN_DECLS + +typedef int +(testsuite_testing)(int argc, const char *argv[], void *data); + +typedef void * +(testsuite_prepare)(int argc, const char *argv[]); + +typedef void +(testsuite_release)(void *data); + +struct testsuite { + bfdev_list_head_t list; + const char *name; + const char *desc; + + testsuite_testing *testing; + testsuite_prepare *prepare; + testsuite_release *release; +}; + +extern int +testsuite_register(struct testsuite *test); + +extern void +testsuite_unregister(struct testsuite *test); + +#define TESTSUITE(NAME, PREPARE, RELEASE, DESC) \ +static testsuite_testing \ +__BFDEV_UNIQUE_ID(testing); \ + \ +static struct testsuite \ +__BFDEV_UNIQUE_ID(testsuite) = { \ + .name = (NAME), .desc = (DESC), \ + .testing = __BFDEV_UNIQUE_ID(testing), \ + .prepare = (PREPARE), \ + .release = (RELEASE), \ +}; \ + \ +static __bfdev_ctor int \ +__BFDEV_UNIQUE_ID(initcall)(void) \ +{ \ + return testsuite_register( \ + &__BFDEV_UNIQUE_ID(testsuite) \ + ); \ +} \ + \ +static __bfdev_dtor void \ +__BFDEV_UNIQUE_ID(exitcall)(void) \ +{ \ + testsuite_unregister( \ + &__BFDEV_UNIQUE_ID(testsuite) \ + ); \ +} \ + \ +static int __BFDEV_UNIQUE_ID(testing) \ +(int argc, const char *argv[], void *data) + +BFDEV_END_DECLS + +#endif /* _BFDEV_TESTSUITE_H_ */ From 951f6b325f755fed8c69ab468139eb158464be62 Mon Sep 17 00:00:00 2001 From: John Sanpe Date: Sat, 30 Mar 2024 12:11:27 +0800 Subject: [PATCH 02/31] fixup slist: fixed added check debug function Signed-off-by: John Sanpe --- src/hlist-debug.c | 10 +++++----- src/slist-debug.c | 15 ++++++++++++--- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/hlist-debug.c b/src/hlist-debug.c index 6121d26f..591a68c8 100644 --- a/src/hlist-debug.c +++ b/src/hlist-debug.c @@ -17,7 +17,7 @@ bfdev_hlist_check_head_add(bfdev_hlist_head_t *head, { if (bfdev_unlikely(head->node == newn)) { bfdev_log_err( - "bfdev_hlist_head_add corruption (%p) head->node" + "hlist_head_add corruption (%p) head->node" " should not be new (%p)\n", head, newn ); return false; @@ -32,7 +32,7 @@ bfdev_hlist_check_next_add(bfdev_hlist_node_t *next, { if (bfdev_unlikely(next->next == newn)) { bfdev_log_err( - "bfdev_hlist_next_add corruption (%p) next->next" + "hlist_next_add corruption (%p) next->next" " should not be new (%p)\n", next, newn ); @@ -48,7 +48,7 @@ bfdev_hlist_check_prev_add(bfdev_hlist_node_t *prev, { if (bfdev_unlikely(prev->pprev == &newn->next)) { bfdev_log_err( - "bfdev_hlist_prev_add corruption (%p) prev->pprev" + "hlist_prev_add corruption (%p) prev->pprev" " should not be new (%p)\n", prev, newn ); @@ -63,7 +63,7 @@ bfdev_hlist_check_del(bfdev_hlist_node_t *node) { if (bfdev_unlikely(node->next == BFDEV_POISON_HLIST1)) { bfdev_log_err( - "bfdev_hlist_del corruption (%p) node->next" + "hlist_del corruption (%p) node->next" " should not be BFDEV_POISON_HLIST1 (%p)\n", node, BFDEV_POISON_HLIST1 ); @@ -72,7 +72,7 @@ bfdev_hlist_check_del(bfdev_hlist_node_t *node) if (bfdev_unlikely(node->pprev == BFDEV_POISON_HLIST2)) { bfdev_log_err( - "bfdev_hlist_del corruption (%p) node->pprev" + "hlist_del corruption (%p) node->pprev" " should not be BFDEV_POISON_HLIST2 (%p)\n", node, BFDEV_POISON_HLIST2 ); diff --git a/src/slist-debug.c b/src/slist-debug.c index 5ff66d04..10bf955e 100644 --- a/src/slist-debug.c +++ b/src/slist-debug.c @@ -14,10 +14,19 @@ export bool bfdev_slist_check_add(bfdev_slist_head_t *node, bfdev_slist_head_t *newn) { - if (bfdev_unlikely(newn->next && newn->next == node->next)) { + if (bfdev_unlikely(node->next == newn)) { bfdev_log_err( - "bfdev_slist_add corruption (%p) newn->next" - " should not be next (%p)\n", + "slist_add corruption (%p) node->next" + " should not be newn (%p)\n", + node, newn + ); + return false; + } + + if (bfdev_unlikely(node == newn)) { + bfdev_log_err( + "slist_add corruption double add:" + " newn=(%p), node=(%p)\n", newn, node ); return false; From 94bda7df15cc54a2495eaeb3609ca9b49f7e1ccd Mon Sep 17 00:00:00 2001 From: John Sanpe Date: Sat, 30 Mar 2024 12:17:31 +0800 Subject: [PATCH 03/31] feat slist: added initial iterator testsuite Signed-off-by: John Sanpe --- examples/slist/CMakeLists.txt | 6 - examples/slist/selftest.c | 129 --------------------- testsuite/CMakeLists.txt | 1 + testsuite/slist/CMakeLists.txt | 8 ++ testsuite/slist/iterator.c | 206 +++++++++++++++++++++++++++++++++ 5 files changed, 215 insertions(+), 135 deletions(-) delete mode 100644 examples/slist/selftest.c create mode 100644 testsuite/slist/CMakeLists.txt create mode 100644 testsuite/slist/iterator.c diff --git a/examples/slist/CMakeLists.txt b/examples/slist/CMakeLists.txt index fd2282d9..79e796cd 100644 --- a/examples/slist/CMakeLists.txt +++ b/examples/slist/CMakeLists.txt @@ -3,24 +3,18 @@ # Copyright(c) 2023 ffashion # -add_executable(slist-selftest selftest.c) -target_link_libraries(slist-selftest bfdev) -add_test(slist-selftest slist-selftest) - add_executable(slist-simple simple.c) target_link_libraries(slist-simple bfdev) add_test(slist-simple slist-simple) if(${CMAKE_PROJECT_NAME} STREQUAL "bfdev") install(FILES - selftest.c simple.c DESTINATION ${CMAKE_INSTALL_DOCDIR}/examples/slist ) install(TARGETS - slist-selftest slist-simple DESTINATION ${CMAKE_INSTALL_DOCDIR}/bin diff --git a/examples/slist/selftest.c b/examples/slist/selftest.c deleted file mode 100644 index 218a8ea9..00000000 --- a/examples/slist/selftest.c +++ /dev/null @@ -1,129 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright(c) 2023 John Sanpe - */ - -#include -#include -#include -#include - -#define TEST_LOOP 10 - -struct test_node { - bfdev_slist_head_t list; - unsigned long num; -}; - -struct test_pdata { - struct test_node nodes[TEST_LOOP]; -}; - -#define slist_to_test(ptr) \ - bfdev_slist_entry(ptr, struct test_node, list) - -static int bfdev_slist_selftest(struct test_pdata *sdata) -{ - struct test_node *node, *nnode, *tnode; - bfdev_slist_head_t *list, *nlist, *tlist; - unsigned int count; - - BFDEV_SLIST_HEAD(test_head); - - for (count = 0; count < BFDEV_ARRAY_SIZE(sdata->nodes); ++count) { - bfdev_slist_add(&test_head, &sdata->nodes[count].list); - } - - bfdev_slist_for_each(list, &test_head) { - node = slist_to_test(list); - printf("slist 'bfdev_slist_for_each' test: %lu\n", node->num); - if (node->num == TEST_LOOP / 2) - break; - } - - tlist = list; - bfdev_slist_for_each_continue(list) { - node = slist_to_test(list); - printf("slist 'bfdev_slist_for_each_continue' test: %lu\n", node->num); - } - - list = tlist; - bfdev_slist_for_each_from(list) { - node = slist_to_test(list); - printf("slist 'bfdev_slist_for_each_from' test: %lu\n", node->num); - } - - bfdev_slist_for_each_safe(list, nlist, &test_head) { - node = slist_to_test(list); - printf("slist 'bfdev_slist_for_each_safe' test: %lu\n", node->num); - if (node->num == TEST_LOOP / 2) - break; - } - - tlist = list; - bfdev_slist_for_each_continue_safe(list, nlist) { - node = slist_to_test(list); - printf("slist 'bfdev_slist_for_each_continue_safe' test: %lu\n", node->num); - } - - list = tlist; - bfdev_slist_for_each_from_safe(list, nlist) { - node = slist_to_test(list); - printf("slist 'bfdev_slist_for_each_from_safe' test: %lu\n", node->num); - } - - bfdev_slist_for_each_entry(node, &test_head, list) { - printf("slist 'bfdev_slist_for_each_entry' test: %lu\n", node->num); - if (node->num == TEST_LOOP / 2) - break; - } - - tnode = node; - bfdev_slist_for_each_entry_continue(node, list) { - printf("slist 'bfdev_slist_for_each_entry_continue' test: %lu\n", node->num); - } - - node = tnode; - bfdev_slist_for_each_entry_from(node, list) { - printf("slist 'bfdev_slist_for_each_entry_from' test: %lu\n", node->num); - } - - bfdev_slist_for_each_entry_safe(node, nnode, &test_head, list) { - printf("slist 'bfdev_slist_for_each_entry_safe' test: %lu\n", node->num); - if (node->num == TEST_LOOP / 2) - break; - bfdev_slist_del(&test_head, &node->list); - } - - tnode = node; - bfdev_slist_for_each_entry_continue_safe(node, nnode, list) { - printf("slist 'bfdev_slist_for_each_entry_continue_safe' test: %lu\n", node->num); - } - - node = tnode; - bfdev_slist_for_each_entry_from_safe(node, nnode, list) { - printf("slist 'bfdev_slist_for_each_entry_from_safe' test: %lu\n", node->num); - bfdev_slist_del(&test_head, &node->list); - } - - return 0; -} - -int main(int argc, const char *argv[]) -{ - struct test_pdata *sdata; - unsigned int count; - int retval; - - sdata = malloc(sizeof(struct test_pdata)); - if (!sdata) - return -1; - - for (count = 0; count < BFDEV_ARRAY_SIZE(sdata->nodes); ++count) - sdata->nodes[count].num = TEST_LOOP - count - 1; - - retval = bfdev_slist_selftest(sdata); - free(sdata); - - return retval; -} diff --git a/testsuite/CMakeLists.txt b/testsuite/CMakeLists.txt index 5a98ac48..aaab3200 100644 --- a/testsuite/CMakeLists.txt +++ b/testsuite/CMakeLists.txt @@ -7,3 +7,4 @@ include(build.cmake) include(testsuite.cmake) add_subdirectory(array) +add_subdirectory(slist) diff --git a/testsuite/slist/CMakeLists.txt b/testsuite/slist/CMakeLists.txt new file mode 100644 index 00000000..bdcfbf20 --- /dev/null +++ b/testsuite/slist/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright(c) 2024 John Sanpe +# + +add_executable(slist-iterator iterator.c) +target_link_libraries(slist-iterator bfdev testsuite) +add_test(slist-iterator slist-iterator) diff --git a/testsuite/slist/iterator.c b/testsuite/slist/iterator.c new file mode 100644 index 00000000..2c972928 --- /dev/null +++ b/testsuite/slist/iterator.c @@ -0,0 +1,206 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright(c) 2023 John Sanpe + */ + +#define MODULE_NAME "slist-fuzzy" +#define bfdev_log_fmt(fmt) MODULE_NAME ": " fmt + +#include +#include +#include +#include +#include +#include + +#define TEST_LOOP 10 + +struct test_node { + bfdev_slist_head_t list; + unsigned int num; +}; + +struct test_struct { + bfdev_slist_head_t head; + struct test_node nodes[TEST_LOOP]; +}; + +#define slist_to_test(ptr) \ + bfdev_slist_entry(ptr, struct test_node, list) + +static void * +test_prepare(int argc, const char *argv[]) +{ + struct test_struct *test; + unsigned int count; + + test = malloc(sizeof(*test)); + if (!test) + return NULL; + + bfdev_slist_head_init(&test->head); + for (count = 0; count < TEST_LOOP; ++count) { + test->nodes[count].num = TEST_LOOP - count; + bfdev_slist_add(&test->head, &test->nodes[count].list); + } + + return test; +} + +static void +test_release(void *data) +{ + free(data); +} + +TESTSUITE( + "slist:for_each", + test_prepare, test_release, + "slist for each iterator test" +) { + struct test_struct *test; + struct test_node *node; + bfdev_slist_head_t *list, *tlist; + unsigned int count; + + test = data; + count = 0; + + bfdev_slist_for_each(list, &test->head) { + node = slist_to_test(list); + bfdev_log_debug("slist 'for_each' test: %u\n", node->num); + if (count++ == TEST_LOOP / 2) + break; + } + + tlist = list; + bfdev_slist_for_each_continue(list) { + node = slist_to_test(list); + bfdev_log_debug("slist 'for_each_continue' test: %u\n", node->num); + count++; + } + + list = tlist; + bfdev_slist_for_each_from(list) { + node = slist_to_test(list); + bfdev_log_debug("slist 'for_each_from' test: %u\n", node->num); + count++; + } + + if (count != TEST_LOOP + (TEST_LOOP / 2)) + return -BFDEV_EFAULT; + + return -BFDEV_ENOERR; +} + +TESTSUITE( + "slist:for_each_safe", + test_prepare, test_release, + "slist for each safe iterator test" +) { + struct test_struct *test; + struct test_node *node; + bfdev_slist_head_t *list, *nlist, *tlist; + unsigned int count; + + test = data; + count = 0; + + bfdev_slist_for_each_safe(list, nlist, &test->head) { + node = slist_to_test(list); + bfdev_log_debug("slist 'for_each_safe' test: %u\n", node->num); + if (count++ == TEST_LOOP / 2) + break; + } + + tlist = list; + bfdev_slist_for_each_continue_safe(list, nlist) { + node = slist_to_test(list); + bfdev_log_debug("slist 'for_each_continue_safe' test: %u\n", node->num); + count++; + } + + list = tlist; + bfdev_slist_for_each_from_safe(list, nlist) { + node = slist_to_test(list); + bfdev_log_debug("slist 'for_each_from_safe' test: %u\n", node->num); + count++; + } + + if (count != TEST_LOOP + (TEST_LOOP / 2)) + return -BFDEV_EFAULT; + + return -BFDEV_ENOERR; +} + +TESTSUITE( + "slist:for_each_entry", + test_prepare, test_release, + "slist for each entry iterator test" +) { + struct test_struct *test; + struct test_node *node, *tnode; + unsigned int count; + + test = data; + count = 0; + + bfdev_slist_for_each_entry(node, &test->head, list) { + bfdev_log_debug("slist 'for_each_entry' test: %u\n", node->num); + if (count++ == TEST_LOOP / 2) + break; + } + + tnode = node; + bfdev_slist_for_each_entry_continue(node, list) { + bfdev_log_debug("slist 'for_each_entry_continue' test: %u\n", node->num); + count++; + } + + node = tnode; + bfdev_slist_for_each_entry_from(node, list) { + bfdev_log_debug("slist 'for_each_entry_from' test: %u\n", node->num); + count++; + } + + if (count != TEST_LOOP + (TEST_LOOP / 2)) + return -BFDEV_EFAULT; + + return -BFDEV_ENOERR; +} + +TESTSUITE( + "slist:for_each_entry_safe", + test_prepare, test_release, + "slist for each entry safe iterator test" +) { + struct test_struct *test; + struct test_node *node, *nnode, *tnode; + unsigned int count; + + test = data; + count = 0; + + bfdev_slist_for_each_entry_safe(node, nnode, &test->head, list) { + bfdev_log_debug("slist 'for_each_entry_safe' test: %u\n", node->num); + if (count++ == TEST_LOOP / 2) + break; + } + + tnode = node; + bfdev_slist_for_each_entry_continue_safe(node, nnode, list) { + bfdev_log_debug("slist 'for_each_entry_continue_safe' test: %u\n", node->num); + count++; + } + + node = tnode; + bfdev_slist_for_each_entry_from_safe(node, nnode, list) { + bfdev_log_debug("slist 'for_each_entry_from_safe' test: %u\n", node->num); + count++; + } + + if (count != TEST_LOOP + (TEST_LOOP / 2)) + return -BFDEV_EFAULT; + + return -BFDEV_ENOERR; +} From 73d481f36cb601db4397a61c80755430b6e6fac4 Mon Sep 17 00:00:00 2001 From: John Sanpe Date: Sat, 30 Mar 2024 12:23:45 +0800 Subject: [PATCH 04/31] feat testsuite: added installation path Signed-off-by: John Sanpe --- testsuite/array/CMakeLists.txt | 8 ++++++++ testsuite/slist/CMakeLists.txt | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/testsuite/array/CMakeLists.txt b/testsuite/array/CMakeLists.txt index 7f24943d..26d95bce 100644 --- a/testsuite/array/CMakeLists.txt +++ b/testsuite/array/CMakeLists.txt @@ -9,3 +9,11 @@ testsuite_target(array-fuzzy ) add_test(array-fuzzy array-fuzzy) + +if(${CMAKE_PROJECT_NAME} STREQUAL "bfdev") + install(TARGETS + array-fuzzy + DESTINATION + ${CMAKE_INSTALL_DOCDIR}/testsuite + ) +endif() diff --git a/testsuite/slist/CMakeLists.txt b/testsuite/slist/CMakeLists.txt index bdcfbf20..117713b1 100644 --- a/testsuite/slist/CMakeLists.txt +++ b/testsuite/slist/CMakeLists.txt @@ -6,3 +6,11 @@ add_executable(slist-iterator iterator.c) target_link_libraries(slist-iterator bfdev testsuite) add_test(slist-iterator slist-iterator) + +if(${CMAKE_PROJECT_NAME} STREQUAL "bfdev") + install(TARGETS + slist-iterator + DESTINATION + ${CMAKE_INSTALL_DOCDIR}/testsuite + ) +endif() From 6664f62ffe71091271e98a18fc9265a7a14c72c2 Mon Sep 17 00:00:00 2001 From: John Sanpe Date: Sat, 30 Mar 2024 14:38:25 +0800 Subject: [PATCH 05/31] feat list: added initial iterator testsuite Signed-off-by: John Sanpe --- examples/list/.gitignore | 1 - examples/list/CMakeLists.txt | 6 - examples/list/selftest.c | 220 --------------------- testsuite/CMakeLists.txt | 1 + testsuite/list/.gitignore | 2 + testsuite/list/CMakeLists.txt | 16 ++ testsuite/list/iterator.c | 359 ++++++++++++++++++++++++++++++++++ 7 files changed, 378 insertions(+), 227 deletions(-) delete mode 100644 examples/list/selftest.c create mode 100644 testsuite/list/.gitignore create mode 100644 testsuite/list/CMakeLists.txt create mode 100644 testsuite/list/iterator.c diff --git a/examples/list/.gitignore b/examples/list/.gitignore index d938e3d7..132a9829 100644 --- a/examples/list/.gitignore +++ b/examples/list/.gitignore @@ -1,3 +1,2 @@ # SPDX-License-Identifier: GPL-2.0-or-later /list-benchmark -/list-selftest diff --git a/examples/list/CMakeLists.txt b/examples/list/CMakeLists.txt index 479a8522..6a03ee97 100644 --- a/examples/list/CMakeLists.txt +++ b/examples/list/CMakeLists.txt @@ -7,21 +7,15 @@ add_executable(list-benchmark benchmark.c) target_link_libraries(list-benchmark bfdev) add_test(list-benchmark list-benchmark) -add_executable(list-selftest selftest.c) -target_link_libraries(list-selftest bfdev) -add_test(list-selftest list-selftest) - if(${CMAKE_PROJECT_NAME} STREQUAL "bfdev") install(FILES benchmark.c - selftest.c DESTINATION ${CMAKE_INSTALL_DOCDIR}/examples/list ) install(TARGETS list-benchmark - list-selftest DESTINATION ${CMAKE_INSTALL_DOCDIR}/bin ) diff --git a/examples/list/selftest.c b/examples/list/selftest.c deleted file mode 100644 index 55b5fda6..00000000 --- a/examples/list/selftest.c +++ /dev/null @@ -1,220 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright(c) 2021 John Sanpe - */ - -#include -#include -#include -#include - -#define TEST_LOOP 10 - -struct test_node { - bfdev_list_head_t list; - unsigned long num; -}; - -struct test_pdata { - struct test_node nodes[TEST_LOOP]; -}; - -#define list_to_test(ptr) \ - bfdev_list_entry(ptr, struct test_node, list) - -static long -list_test_sort(const bfdev_list_head_t *node1, - const bfdev_list_head_t *node2, void *pdata) -{ - struct test_node *tnode1, *tnode2; - - tnode1 = list_to_test(node1); - tnode2 = list_to_test(node2); - - if (tnode1->num == tnode2->num) - return 0; - - return tnode1->num < tnode2->num ? -1 : 1; -} - -static int -list_selftest(struct test_pdata *ldata) -{ - struct test_node *node, *nnode, *tnode; - bfdev_list_head_t *list, *nlist, *tlist; - unsigned int count; - - BFDEV_LIST_HEAD(test_head); - - for (count = 0; count < BFDEV_ARRAY_SIZE(ldata->nodes); ++count) { - if (count % 1) - bfdev_list_add_prev(&test_head, &ldata->nodes[count].list); - else - bfdev_list_add(&test_head, &ldata->nodes[count].list); - } - - bfdev_list_sort(&test_head, list_test_sort, NULL); - - bfdev_list_for_each(list, &test_head) { - node = list_to_test(list); - printf("list 'list_for_each' test: %lu\n", node->num); - if (node->num == TEST_LOOP / 2) - break; - } - - tlist = list; - bfdev_list_for_each_continue(list, &test_head) { - node = list_to_test(list); - printf("list 'list_for_each_continue' test: %lu\n", node->num); - } - - list = tlist; - bfdev_list_for_each_from(list, &test_head) { - node = list_to_test(list); - printf("list 'list_for_each_from' test: %lu\n", node->num); - } - - bfdev_list_for_each_reverse(list, &test_head) { - node = list_to_test(list); - printf("list 'list_for_each_reverse' test: %lu\n", node->num); - if (node->num == TEST_LOOP / 2) - break; - } - - tlist = list; - bfdev_list_for_each_reverse_continue(list, &test_head) { - node = list_to_test(list); - printf("list 'list_for_each_reverse_continue' test: %lu\n", node->num); - } - - list = tlist; - bfdev_list_for_each_reverse_from(list, &test_head) { - node = list_to_test(list); - printf("list 'list_for_each_reverse_from' test: %lu\n", node->num); - } - - bfdev_list_for_each_safe(list, nlist, &test_head) { - node = list_to_test(list); - printf("list 'list_for_each_safe' test: %lu\n", node->num); - if (node->num == TEST_LOOP / 2) - break; - } - - tlist = list; - bfdev_list_for_each_continue_safe(list, nlist, &test_head) { - node = list_to_test(list); - printf("list 'list_for_each_continue_safe' test: %lu\n", node->num); - } - - list = tlist; - bfdev_list_for_each_from_safe(list, nlist, &test_head) { - node = list_to_test(list); - printf("list 'list_for_each_from_safe' test: %lu\n", node->num); - } - - bfdev_list_for_each_reverse_safe(list, nlist, &test_head) { - node = list_to_test(list); - printf("list 'list_for_each_reverse_safe' test: %lu\n", node->num); - if (node->num == TEST_LOOP / 2) - break; - } - - tlist = list; - bfdev_list_for_each_reverse_continue_safe(list, nlist, &test_head) { - node = list_to_test(list); - printf("list 'list_for_each_reverse_continue_safe' test: %lu\n", node->num); - } - - list = tlist; - bfdev_list_for_each_reverse_from_safe(list, nlist, &test_head) { - node = list_to_test(list); - printf("list 'list_for_each_reverse_from_safe' test: %lu\n", node->num); - } - - bfdev_list_for_each_entry(node, &test_head, list) { - printf("list 'list_for_each_entry' test: %lu\n", node->num); - if (node->num == TEST_LOOP / 2) - break; - } - - tnode = node; - bfdev_list_for_each_entry_continue(node, &test_head, list) { - printf("list 'list_for_each_entry_continue' test: %lu\n", node->num); - } - - node = tnode; - bfdev_list_for_each_entry_from(node, &test_head, list) { - printf("list 'list_for_each_entry_from' test: %lu\n", node->num); - } - - bfdev_list_for_each_entry_reverse(node, &test_head, list) { - printf("list 'list_for_each_entry_reverse' test: %lu\n", node->num); - if (node->num == TEST_LOOP / 2) - break; - } - - tnode = node; - bfdev_list_for_each_entry_reverse_continue(node, &test_head, list) { - printf("list 'list_for_each_entry_reverse_continue' test: %lu\n", node->num); - } - - node = tnode; - bfdev_list_for_each_entry_reverse_from(node, &test_head, list) { - printf("list 'list_for_each_entry_reverse_from' test: %lu\n", node->num); - } - - bfdev_list_for_each_entry_safe(node, nnode, &test_head, list) { - printf("list 'list_for_each_entry_safe' test: %lu\n", node->num); - if (node->num == TEST_LOOP / 2) - break; - } - - tnode = node; - bfdev_list_for_each_entry_continue_safe(node, nnode, &test_head, list) { - printf("list 'list_for_each_entry_continue_safe' test: %lu\n", node->num); - } - - node = tnode; - bfdev_list_for_each_entry_from_safe(node, nnode, &test_head, list) { - printf("list 'list_for_each_entry_form_safe' test: %lu\n", node->num); - } - - bfdev_list_for_each_entry_reverse_safe(node, nnode, &test_head, list) { - printf("list 'list_for_each_entry_reverse_safe' test: %lu\n", node->num); - if (node->num == TEST_LOOP / 2) - break; - bfdev_list_del(&node->list); - } - - tnode = node; - bfdev_list_for_each_entry_reverse_continue_safe(node, nnode, &test_head, list) { - printf("list 'list_for_each_entry_reverse_continue_safe' test: %lu\n", node->num); - } - - node = tnode; - bfdev_list_for_each_entry_reverse_from_safe(node, nnode, &test_head, list) { - printf("list 'list_for_each_entry_reverse_form_safe' test: %lu\n", node->num); - bfdev_list_del(&node->list); - } - - return 0; -} - -int main(int argc, const char *argv[]) -{ - struct test_pdata *ldata; - unsigned int count; - int retval; - - ldata = malloc(sizeof(struct test_pdata)); - if (!ldata) - return -1; - - for (count = 0; count < BFDEV_ARRAY_SIZE(ldata->nodes); ++count) - ldata->nodes[count].num = count; - - retval = list_selftest(ldata); - free(ldata); - - return retval; -} diff --git a/testsuite/CMakeLists.txt b/testsuite/CMakeLists.txt index aaab3200..de5613d4 100644 --- a/testsuite/CMakeLists.txt +++ b/testsuite/CMakeLists.txt @@ -7,4 +7,5 @@ include(build.cmake) include(testsuite.cmake) add_subdirectory(array) +add_subdirectory(list) add_subdirectory(slist) diff --git a/testsuite/list/.gitignore b/testsuite/list/.gitignore new file mode 100644 index 00000000..cf019f2f --- /dev/null +++ b/testsuite/list/.gitignore @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +/list-iterator diff --git a/testsuite/list/CMakeLists.txt b/testsuite/list/CMakeLists.txt new file mode 100644 index 00000000..bf74ae51 --- /dev/null +++ b/testsuite/list/CMakeLists.txt @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright(c) 2024 John Sanpe +# + +add_executable(list-iterator iterator.c) +target_link_libraries(list-iterator bfdev testsuite) +add_test(list-iterator list-iterator) + +if(${CMAKE_PROJECT_NAME} STREQUAL "bfdev") + install(TARGETS + list-iterator + DESTINATION + ${CMAKE_INSTALL_DOCDIR}/testsuite + ) +endif() diff --git a/testsuite/list/iterator.c b/testsuite/list/iterator.c new file mode 100644 index 00000000..7fc43748 --- /dev/null +++ b/testsuite/list/iterator.c @@ -0,0 +1,359 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright(c) 2023 John Sanpe + */ + +#define MODULE_NAME "list-iterator" +#define bfdev_log_fmt(fmt) MODULE_NAME ": " fmt + +#include +#include +#include +#include +#include +#include + +#define TEST_LOOP 10 + +struct test_node { + bfdev_list_head_t list; + unsigned int num; +}; + +struct test_struct { + bfdev_list_head_t head; + struct test_node nodes[TEST_LOOP]; +}; + +#define list_to_test(ptr) \ + bfdev_list_entry(ptr, struct test_node, list) + +static void * +test_prepare(int argc, const char *argv[]) +{ + struct test_struct *test; + unsigned int count; + + test = malloc(sizeof(*test)); + if (!test) + return NULL; + + bfdev_list_head_init(&test->head); + for (count = 0; count < TEST_LOOP; ++count) { + test->nodes[count].num = count; + (count % 1 ? bfdev_list_add_prev : bfdev_list_add) + (&test->head, &test->nodes[count].list); + } + + return test; +} + +static void +test_release(void *data) +{ + free(data); +} + +TESTSUITE( + "list:for_each", + test_prepare, test_release, + "list for each iterator test" +) { + struct test_struct *test; + struct test_node *node; + bfdev_list_head_t *list, *tlist; + unsigned int count; + + test = data; + count = 0; + + bfdev_list_for_each(list, &test->head) { + node = list_to_test(list); + bfdev_log_debug("'list_for_each' test: %u\n", node->num); + if (count++ == TEST_LOOP / 2) + break; + } + + tlist = list; + bfdev_list_for_each_continue(list, &test->head) { + node = list_to_test(list); + bfdev_log_debug("'list_for_each_continue' test: %u\n", node->num); + count++; + } + + list = tlist; + bfdev_list_for_each_from(list, &test->head) { + node = list_to_test(list); + bfdev_log_debug("'list_for_each_from' test: %u\n", node->num); + count++; + } + + if (count != TEST_LOOP + (TEST_LOOP / 2)) + return -BFDEV_EFAULT; + + return -BFDEV_ENOERR; +} + +TESTSUITE( + "list:for_each_reverse", + test_prepare, test_release, + "list for each reverse iterator test" +) { + struct test_struct *test; + struct test_node *node; + bfdev_list_head_t *list, *tlist; + unsigned int count; + + test = data; + count = 0; + + bfdev_list_for_each_reverse(list, &test->head) { + node = list_to_test(list); + bfdev_log_debug("'list_for_each_reverse' test: %u\n", node->num); + if (count++ == TEST_LOOP / 2) + break; + } + + tlist = list; + bfdev_list_for_each_reverse_continue(list, &test->head) { + node = list_to_test(list); + bfdev_log_debug("'list_for_each_reverse_continue' test: %u\n", node->num); + count++; + } + + list = tlist; + bfdev_list_for_each_reverse_from(list, &test->head) { + node = list_to_test(list); + bfdev_log_debug("'list_for_each_reverse_from' test: %u\n", node->num); + count++; + } + + if (count != TEST_LOOP + (TEST_LOOP / 2)) + return -BFDEV_EFAULT; + + return -BFDEV_ENOERR; +} + +TESTSUITE( + "list:for_each_safe", + test_prepare, test_release, + "list for each safe iterator test" +) { + struct test_struct *test; + struct test_node *node; + bfdev_list_head_t *list, *nlist, *tlist; + unsigned int count; + + test = data; + count = 0; + + bfdev_list_for_each_safe(list, nlist, &test->head) { + node = list_to_test(list); + bfdev_log_debug("'list_for_each_safe' test: %u\n", node->num); + if (count++ == TEST_LOOP / 2) + break; + } + + tlist = list; + bfdev_list_for_each_continue_safe(list, nlist, &test->head) { + node = list_to_test(list); + bfdev_log_debug("'list_for_each_continue_safe' test: %u\n", node->num); + count++; + } + + list = tlist; + bfdev_list_for_each_from_safe(list, nlist, &test->head) { + node = list_to_test(list); + bfdev_log_debug("'list_for_each_from_safe' test: %u\n", node->num); + count++; + } + + if (count != TEST_LOOP + (TEST_LOOP / 2)) + return -BFDEV_EFAULT; + + return -BFDEV_ENOERR; +} + +TESTSUITE( + "list:for_each_reverse_safe", + test_prepare, test_release, + "list for each reverse safe iterator test" +) { + struct test_struct *test; + struct test_node *node; + bfdev_list_head_t *list, *nlist, *tlist; + unsigned int count; + + test = data; + count = 0; + + bfdev_list_for_each_reverse_safe(list, nlist, &test->head) { + node = list_to_test(list); + bfdev_log_debug("'list_for_each_reverse_safe' test: %u\n", node->num); + if (count++ == TEST_LOOP / 2) + break; + } + + tlist = list; + bfdev_list_for_each_reverse_continue_safe(list, nlist, &test->head) { + node = list_to_test(list); + bfdev_log_debug("'list_for_each_reverse_continue_safe' test: %u\n", node->num); + count++; + } + + list = tlist; + bfdev_list_for_each_reverse_from_safe(list, nlist, &test->head) { + node = list_to_test(list); + bfdev_log_debug("'list_for_each_reverse_from_safe' test: %u\n", node->num); + count++; + } + + if (count != TEST_LOOP + (TEST_LOOP / 2)) + return -BFDEV_EFAULT; + + return -BFDEV_ENOERR; +} + +TESTSUITE( + "list:for_each_entry", + test_prepare, test_release, + "list for each entry iterator test" +) { + struct test_struct *test; + struct test_node *node, *tnode; + unsigned int count; + + test = data; + count = 0; + + bfdev_list_for_each_entry(node, &test->head, list) { + bfdev_log_debug("'list_for_each_entry' test: %u\n", node->num); + if (count++ == TEST_LOOP / 2) + break; + } + + tnode = node; + bfdev_list_for_each_entry_continue(node, &test->head, list) { + bfdev_log_debug("'list_for_each_entry_continue' test: %u\n", node->num); + count++; + } + + node = tnode; + bfdev_list_for_each_entry_from(node, &test->head, list) { + bfdev_log_debug("'list_for_each_entry_from' test: %u\n", node->num); + count++; + } + + if (count != TEST_LOOP + (TEST_LOOP / 2)) + return -BFDEV_EFAULT; + + return -BFDEV_ENOERR; +} + +TESTSUITE( + "list:for_each_entry_reverse", + test_prepare, test_release, + "list for each entry reverse iterator test" +) { + struct test_struct *test; + struct test_node *node, *tnode; + unsigned int count; + + test = data; + count = 0; + + bfdev_list_for_each_entry_reverse(node, &test->head, list) { + bfdev_log_debug("'list_for_each_entry_reverse' test: %u\n", node->num); + if (count++ == TEST_LOOP / 2) + break; + } + + tnode = node; + bfdev_list_for_each_entry_reverse_continue(node, &test->head, list) { + bfdev_log_debug("'list_for_each_entry_reverse_continue' test: %u\n", node->num); + count++; + } + + node = tnode; + bfdev_list_for_each_entry_reverse_from(node, &test->head, list) { + bfdev_log_debug("'list_for_each_entry_reverse_from' test: %u\n", node->num); + count++; + } + + if (count != TEST_LOOP + (TEST_LOOP / 2)) + return -BFDEV_EFAULT; + + return -BFDEV_ENOERR; +} + +TESTSUITE( + "list:for_each_entry_safe", + test_prepare, test_release, + "list for each entry safe iterator test" +) { + struct test_struct *test; + struct test_node *node, *nnode, *tnode; + unsigned int count; + + test = data; + count = 0; + + bfdev_list_for_each_entry_safe(node, nnode, &test->head, list) { + bfdev_log_debug("'list_for_each_entry_safe' test: %u\n", node->num); + if (count++ == TEST_LOOP / 2) + break; + } + + tnode = node; + bfdev_list_for_each_entry_continue_safe(node, nnode, &test->head, list) { + bfdev_log_debug("'list_for_each_entry_continue_safe' test: %u\n", node->num); + count++; + } + + node = tnode; + bfdev_list_for_each_entry_from_safe(node, nnode, &test->head, list) { + bfdev_log_debug("'list_for_each_entry_form_safe' test: %u\n", node->num); + count++; + } + + if (count != TEST_LOOP + (TEST_LOOP / 2)) + return -BFDEV_EFAULT; + + return -BFDEV_ENOERR; +} + +TESTSUITE( + "list:for_each_entry_reverse_safe", + test_prepare, test_release, + "list for each entry reverse safe iterator test" +) { + struct test_struct *test; + struct test_node *node, *nnode, *tnode; + unsigned int count; + + test = data; + count = 0; + + bfdev_list_for_each_entry_reverse_safe(node, nnode, &test->head, list) { + bfdev_log_debug("'list_for_each_entry_reverse_safe' test: %u\n", node->num); + if (count++ == TEST_LOOP / 2) + break; + } + + tnode = node; + bfdev_list_for_each_entry_reverse_continue_safe(node, nnode, &test->head, list) { + bfdev_log_debug("'list_for_each_entry_reverse_continue_safe' test: %u\n", node->num); + count++; + } + + node = tnode; + bfdev_list_for_each_entry_reverse_from_safe(node, nnode, &test->head, list) { + bfdev_log_debug("'list_for_each_entry_reverse_form_safe' test: %u\n", node->num); + count++; + } + + if (count != TEST_LOOP + (TEST_LOOP / 2)) + return -BFDEV_EFAULT; + + return -BFDEV_ENOERR; +} From 75aae12615cbb50961311dde31c98ec52a4413bd Mon Sep 17 00:00:00 2001 From: John Sanpe Date: Sat, 30 Mar 2024 14:55:44 +0800 Subject: [PATCH 06/31] fixup testsuite: delete sorting of test cases Signed-off-by: John Sanpe --- testsuite/testsuite.c | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/testsuite/testsuite.c b/testsuite/testsuite.c index 1baac51e..31f85665 100644 --- a/testsuite/testsuite.c +++ b/testsuite/testsuite.c @@ -26,23 +26,6 @@ static BFDEV_LIST_HEAD(tests); #define list_to_testsuite(ptr) \ bfdev_container_of(ptr, struct testsuite, list) -static long -testsuite_cmp(const bfdev_list_head_t *node1, - const bfdev_list_head_t *node2, void *pdata) -{ - struct testsuite *test1, *test2; - int retval; - - test1 = list_to_testsuite(node1); - test2 = list_to_testsuite(node2); - - retval = strcmp(test1->name, test2->name); - if (retval) - return retval; - - return 0; -} - static struct testsuite * testsuite_find(const char *name) { @@ -79,7 +62,7 @@ testsuite_register(struct testsuite *test) return -BFDEV_EALREADY; bfdev_log_info("register '%s'\n", test->name); - bfdev_list_add(&tests, &test->list); + bfdev_list_add_prev(&tests, &test->list); return -BFDEV_ENOERR; } @@ -204,9 +187,7 @@ main(int argc, char *const argv[]) setbuf(stdout, NULL); setbuf(stderr, NULL); - loops = DEFAULT_LOOPS; - bfdev_list_sort(&tests, testsuite_cmp, NULL); for (;;) { arg = getopt(argc, argv, "c:dh"); From 3952b1845b16319ae9fc8f3846aba844127400c3 Mon Sep 17 00:00:00 2001 From: John Sanpe Date: Sat, 30 Mar 2024 14:56:10 +0800 Subject: [PATCH 07/31] fixup testsuite: fixed some gitignore Signed-off-by: John Sanpe --- examples/slist/.gitignore | 1 - testsuite/array/.gitignore | 2 ++ testsuite/slist/.gitignore | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 testsuite/array/.gitignore create mode 100644 testsuite/slist/.gitignore diff --git a/examples/slist/.gitignore b/examples/slist/.gitignore index a78e6719..b4434afa 100644 --- a/examples/slist/.gitignore +++ b/examples/slist/.gitignore @@ -1,3 +1,2 @@ # SPDX-License-Identifier: GPL-2.0-or-later -/slist-selftest /slist-simple diff --git a/testsuite/array/.gitignore b/testsuite/array/.gitignore new file mode 100644 index 00000000..a6e4626f --- /dev/null +++ b/testsuite/array/.gitignore @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +/array-fuzzy diff --git a/testsuite/slist/.gitignore b/testsuite/slist/.gitignore new file mode 100644 index 00000000..c50d8b14 --- /dev/null +++ b/testsuite/slist/.gitignore @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +/slist-iterator From f0d037ec4b7ffdeeefebb3078ea7cb277d2a938b Mon Sep 17 00:00:00 2001 From: John Sanpe Date: Sat, 30 Mar 2024 14:56:48 +0800 Subject: [PATCH 08/31] fixup testsuite: remove slist iterator excess prefix Signed-off-by: John Sanpe --- testsuite/slist/iterator.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/testsuite/slist/iterator.c b/testsuite/slist/iterator.c index 2c972928..1f9c2077 100644 --- a/testsuite/slist/iterator.c +++ b/testsuite/slist/iterator.c @@ -3,7 +3,7 @@ * Copyright(c) 2023 John Sanpe */ -#define MODULE_NAME "slist-fuzzy" +#define MODULE_NAME "slist-iterator" #define bfdev_log_fmt(fmt) MODULE_NAME ": " fmt #include @@ -68,7 +68,7 @@ TESTSUITE( bfdev_slist_for_each(list, &test->head) { node = slist_to_test(list); - bfdev_log_debug("slist 'for_each' test: %u\n", node->num); + bfdev_log_debug("'for_each' test: %u\n", node->num); if (count++ == TEST_LOOP / 2) break; } @@ -76,14 +76,14 @@ TESTSUITE( tlist = list; bfdev_slist_for_each_continue(list) { node = slist_to_test(list); - bfdev_log_debug("slist 'for_each_continue' test: %u\n", node->num); + bfdev_log_debug("'for_each_continue' test: %u\n", node->num); count++; } list = tlist; bfdev_slist_for_each_from(list) { node = slist_to_test(list); - bfdev_log_debug("slist 'for_each_from' test: %u\n", node->num); + bfdev_log_debug("'for_each_from' test: %u\n", node->num); count++; } @@ -108,7 +108,7 @@ TESTSUITE( bfdev_slist_for_each_safe(list, nlist, &test->head) { node = slist_to_test(list); - bfdev_log_debug("slist 'for_each_safe' test: %u\n", node->num); + bfdev_log_debug("'for_each_safe' test: %u\n", node->num); if (count++ == TEST_LOOP / 2) break; } @@ -116,14 +116,14 @@ TESTSUITE( tlist = list; bfdev_slist_for_each_continue_safe(list, nlist) { node = slist_to_test(list); - bfdev_log_debug("slist 'for_each_continue_safe' test: %u\n", node->num); + bfdev_log_debug("'for_each_continue_safe' test: %u\n", node->num); count++; } list = tlist; bfdev_slist_for_each_from_safe(list, nlist) { node = slist_to_test(list); - bfdev_log_debug("slist 'for_each_from_safe' test: %u\n", node->num); + bfdev_log_debug("'for_each_from_safe' test: %u\n", node->num); count++; } @@ -146,20 +146,20 @@ TESTSUITE( count = 0; bfdev_slist_for_each_entry(node, &test->head, list) { - bfdev_log_debug("slist 'for_each_entry' test: %u\n", node->num); + bfdev_log_debug("'for_each_entry' test: %u\n", node->num); if (count++ == TEST_LOOP / 2) break; } tnode = node; bfdev_slist_for_each_entry_continue(node, list) { - bfdev_log_debug("slist 'for_each_entry_continue' test: %u\n", node->num); + bfdev_log_debug("'for_each_entry_continue' test: %u\n", node->num); count++; } node = tnode; bfdev_slist_for_each_entry_from(node, list) { - bfdev_log_debug("slist 'for_each_entry_from' test: %u\n", node->num); + bfdev_log_debug("'for_each_entry_from' test: %u\n", node->num); count++; } @@ -182,20 +182,20 @@ TESTSUITE( count = 0; bfdev_slist_for_each_entry_safe(node, nnode, &test->head, list) { - bfdev_log_debug("slist 'for_each_entry_safe' test: %u\n", node->num); + bfdev_log_debug("'for_each_entry_safe' test: %u\n", node->num); if (count++ == TEST_LOOP / 2) break; } tnode = node; bfdev_slist_for_each_entry_continue_safe(node, nnode, list) { - bfdev_log_debug("slist 'for_each_entry_continue_safe' test: %u\n", node->num); + bfdev_log_debug("'for_each_entry_continue_safe' test: %u\n", node->num); count++; } node = tnode; bfdev_slist_for_each_entry_from_safe(node, nnode, list) { - bfdev_log_debug("slist 'for_each_entry_from_safe' test: %u\n", node->num); + bfdev_log_debug("'for_each_entry_from_safe' test: %u\n", node->num); count++; } From d655009e71eca26eaa7612eaf69a0be3e3fdb534 Mon Sep 17 00:00:00 2001 From: John Sanpe Date: Sat, 30 Mar 2024 17:14:09 +0800 Subject: [PATCH 09/31] fixup bitmap: fixed some optimization logic issues Signed-off-by: John Sanpe --- include/bfdev/bitmap.h | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/include/bfdev/bitmap.h b/include/bfdev/bitmap.h index e88f99f5..b3c0978d 100644 --- a/include/bfdev/bitmap.h +++ b/include/bfdev/bitmap.h @@ -36,7 +36,8 @@ bfdev_bitmap_empty(const unsigned long *src, unsigned int bits) { if (bfdev_const_small_nbits(bits)) return !(*src & BFDEV_BIT_LOW_MASK(bits)); - else if (!bfdev_bitmap_const_aligned(bits)) + + if (!bfdev_bitmap_const_aligned(bits)) return bfdev_find_first_bit(src, bits) >= bits; return !bfdev_memdiff(src, BFDEV_UINT_MIN, bits / BFDEV_BITS_PER_BYTE); @@ -47,7 +48,8 @@ bfdev_bitmap_full(const unsigned long *src, unsigned int bits) { if (bfdev_const_small_nbits(bits)) return !(~(*src) & BFDEV_BIT_LOW_MASK(bits)); - else if (!bfdev_bitmap_const_aligned(bits)) + + if (!bfdev_bitmap_const_aligned(bits)) return bfdev_find_first_zero(src, bits) >= bits; return !bfdev_memdiff(src, BFDEV_UINT_MAX, bits / BFDEV_BITS_PER_BYTE); @@ -59,7 +61,8 @@ bfdev_bitmap_equal(const unsigned long *src1, const unsigned long *src2, { if (bfdev_const_small_nbits(bits)) return !!((*src1 ^ *src2) & BFDEV_BIT_LOW_MASK(bits)); - else if (!bfdev_bitmap_const_aligned(bits)) + + if (!bfdev_bitmap_const_aligned(bits)) return bfdev_bitmap_comp_equal(src1, src2, bits); return memcmp(src1, src2, bits / BFDEV_BITS_PER_BYTE); @@ -189,8 +192,9 @@ bfdev_bitmap_set(unsigned long *bitmap, unsigned int start, unsigned int bits) if (__builtin_constant_p(bits) && bits == 1) return bfdev_bit_set(bitmap, start); - else if (!bfdev_bitmap_const_aligned(start) || - !bfdev_bitmap_const_aligned(bits)) + + if (!bfdev_bitmap_const_aligned(start) || + !bfdev_bitmap_const_aligned(bits)) return bfdev_bitmap_comp_set(bitmap, start, bits); offset = start / BFDEV_BITS_PER_BYTE; @@ -206,8 +210,9 @@ bfdev_bitmap_clr(unsigned long *bitmap, unsigned int start, unsigned int bits) if (__builtin_constant_p(bits) && bits == 1) return bfdev_bit_clr(bitmap, start); - else if (!bfdev_bitmap_const_aligned(start) || - !bfdev_bitmap_const_aligned(bits)) + + if (!bfdev_bitmap_const_aligned(start) || + !bfdev_bitmap_const_aligned(bits)) return bfdev_bitmap_comp_clr(bitmap, start, bits); offset = start / BFDEV_BITS_PER_BYTE; @@ -221,8 +226,10 @@ bfdev_bitmap_zero(unsigned long *bitmap, unsigned int bits) { unsigned int length; - if (bfdev_const_small_nbits(bits)) + if (bfdev_const_small_nbits(bits)) { *bitmap = 0; + return; + } length = BFDEV_BITS_TO_U8(bits); memset(bitmap, 0, length); @@ -233,11 +240,13 @@ bfdev_bitmap_fill(unsigned long *bitmap, unsigned int bits) { unsigned int length; - if (bfdev_const_small_nbits(bits)) - *bitmap = 0xff; + if (bfdev_const_small_nbits(bits)) { + *bitmap = BFDEV_ULONG_MAX; + return; + } length = BFDEV_BITS_TO_U8(bits); - memset(bitmap, UINT8_MAX, length); + memset(bitmap, BFDEV_UINT8_MAX, length); } static __bfdev_always_inline void @@ -245,8 +254,10 @@ bfdev_bitmap_copy(unsigned long *dest, unsigned long *src, unsigned int bits) { unsigned int length; - if (bfdev_const_small_nbits(bits)) + if (bfdev_const_small_nbits(bits)) { *dest = *src; + return; + } length = BFDEV_BITS_TO_U8(bits); memcpy(dest, src, length); From 85e08d7fa2cf2a73a20f1704aeb3e8c5a100633c Mon Sep 17 00:00:00 2001 From: John Sanpe Date: Sun, 31 Mar 2024 19:47:19 +0800 Subject: [PATCH 10/31] build testsuite: not enable suite on default Signed-off-by: John Sanpe --- .github/workflows/ubuntu-clang.yml | 1 - .github/workflows/ubuntu-gcc.yml | 11 +++++------ .github/workflows/windows.yml | 17 +++++++++++------ CMakeLists.txt | 3 ++- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ubuntu-clang.yml b/.github/workflows/ubuntu-clang.yml index 9842a3d3..9d88c4e5 100644 --- a/.github/workflows/ubuntu-clang.yml +++ b/.github/workflows/ubuntu-clang.yml @@ -44,7 +44,6 @@ jobs: --config ${{env.BUILD_TYPE}} - name: install - working-directory: ${{github.workspace}}/build run: | cmake --build ${{github.workspace}}/build \ --config ${{env.BUILD_TYPE}} -- install diff --git a/.github/workflows/ubuntu-gcc.yml b/.github/workflows/ubuntu-gcc.yml index 589ca0dd..35cb7d68 100644 --- a/.github/workflows/ubuntu-gcc.yml +++ b/.github/workflows/ubuntu-gcc.yml @@ -32,11 +32,11 @@ jobs: - name: configure cmake run: | - cmake -B ${{github.workspace}}/build \ - -D CMAKE_INSTALL_PREFIX=${{github.workspace}}/build/install \ - -D CMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \ - -D CMAKE_C_COMPILER=/usr/lib/ccache/gcc \ - -D BFDEV_DEVEL=ON + cmake -B ${{github.workspace}}/build \ + -D CMAKE_INSTALL_PREFIX=${{github.workspace}}/build/install \ + -D CMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \ + -D CMAKE_C_COMPILER=/usr/lib/ccache/gcc \ + -D BFDEV_DEVEL=ON - name: make run: | @@ -44,7 +44,6 @@ jobs: --config ${{env.BUILD_TYPE}} - name: install - working-directory: ${{github.workspace}}/build run: | cmake --build ${{github.workspace}}/build \ --config ${{env.BUILD_TYPE}} -- install diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 6387b39e..8d8c1ce9 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -38,16 +38,21 @@ jobs: - name: configure cmake run: | - cmake -B build \ - -D CMAKE_INSTALL_PREFIX=build/install \ - -D CMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \ - -D BFDEV_EXAMPLES=ON + cmake -B build \ + -D CMAKE_INSTALL_PREFIX=build/install \ + -D CMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \ + -D BFDEV_EXAMPLES=ON \ + -D BFDEV_TESTSUITE=ON - name: make - run: cmake --build build --config ${{env.BUILD_TYPE}} + run: | + cmake --build build \ + --config ${{env.BUILD_TYPE}} - name: install - run: cmake --build build --config ${{env.BUILD_TYPE}} -- install + run: | + cmake --build build \ + --config ${{env.BUILD_TYPE}} -- install - name: ctest working-directory: ${{github.workspace}}/build diff --git a/CMakeLists.txt b/CMakeLists.txt index 80976ac0..a146bcc2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,7 +41,7 @@ commit_branch(BFDEV_BRANCH) option(BFDEV_DEVEL "Enable development mode" OFF) option(BFDEV_STRICT "Enable strict compilation" ON) option(BFDEV_EXAMPLES "Build examples" OFF) -option(BFDEV_TESTSUITE "Build testsuite" ON) +option(BFDEV_TESTSUITE "Build testsuite" OFF) option(BFDEV_ASAN "Enable Address Sanitizer" OFF) option(BFDEV_UBSAN "Enable Undefined Behaviour Sanitizer" OFF) @@ -58,6 +58,7 @@ option(BFDEV_CRC_EXTEND "CRC loop unfolding optimize" ON) if(BFDEV_DEVEL) set(BFDEV_EXAMPLES ON) + set(BFDEV_TESTSUITE ON) set(BFDEV_ASAN ON) set(BFDEV_UBSAN ON) set(BFDEV_GCOV ON) From 3be59cfe0d9a465fc92295e005d43a607eed8ff0 Mon Sep 17 00:00:00 2001 From: John Sanpe Date: Mon, 1 Apr 2024 19:19:29 +0800 Subject: [PATCH 11/31] feat macro: added compare function Signed-off-by: John Sanpe --- include/bfdev/macro.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/bfdev/macro.h b/include/bfdev/macro.h index 3f40eb13..49e05a8a 100644 --- a/include/bfdev/macro.h +++ b/include/bfdev/macro.h @@ -20,6 +20,17 @@ BFDEV_BEGIN_DECLS (a) = (b); (b) = __a; \ }) +/** + * bfdev_cmp() - compare values. + * @cond: compare condition. + * + * If the @cond is met, return an positive number; + * otherwise, return a negative number. + */ +#define bfdev_cmp(cond) ( \ + (cond) ? BFDEV_BT : BFDEV_LT \ +) + /** * BFDEV_ARRAY_SIZE() - get the number of elements in array. * @arr: array to be sized. From 4c28b8bd346c9a240fe84bd31dda8373d58586fa Mon Sep 17 00:00:00 2001 From: John Sanpe Date: Mon, 1 Apr 2024 19:40:56 +0800 Subject: [PATCH 12/31] fixup testsuite: return error on testing failed Signed-off-by: John Sanpe --- testsuite/testsuite.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/testsuite/testsuite.c b/testsuite/testsuite.c index 31f85665..6ece9cbd 100644 --- a/testsuite/testsuite.c +++ b/testsuite/testsuite.c @@ -118,6 +118,7 @@ trigger_testsuite(struct testsuite *test, unsigned int loops, return retval; } + retval = -BFDEV_ENOERR; for (count = 1; count <= loops; ++count) { bfdev_log_debug("Testing loop%u...\n", count); EXAMPLE_TIME_STATISTICAL( @@ -140,7 +141,7 @@ trigger_testsuite(struct testsuite *test, unsigned int loops, bfdev_log_notice("Released.\n"); } - return -BFDEV_ENOERR; + return retval; } static int From b30969270cfd19f1f5497a8fe0c7d47441568bdd Mon Sep 17 00:00:00 2001 From: John Sanpe Date: Tue, 2 Apr 2024 12:38:06 +0800 Subject: [PATCH 13/31] fixup bitwalk: fixed some calculation errors Signed-off-by: John Sanpe --- include/bfdev/bits.h | 1 + include/bfdev/bitwalk-comp.h | 16 +--- include/bfdev/bitwalk.h | 152 ++++++++++++++++++++++------------- src/bitwalk.c | 99 ++++++++--------------- 4 files changed, 133 insertions(+), 135 deletions(-) diff --git a/include/bfdev/bits.h b/include/bfdev/bits.h index 642e0d86..c1b1c475 100644 --- a/include/bfdev/bits.h +++ b/include/bfdev/bits.h @@ -22,6 +22,7 @@ BFDEV_BEGIN_DECLS #define BFDEV_BITS_PER_U32 BFDEV_BITS_PER_TYPE(uint32_t) #define BFDEV_BITS_PER_U64 BFDEV_BITS_PER_TYPE(uint64_t) +#define BFDEV_BITS_PER_CHAR BFDEV_BITS_PER_TYPE(char) #define BFDEV_BITS_PER_SHORT BFDEV_BITS_PER_TYPE(short) #define BFDEV_BITS_PER_INT BFDEV_BITS_PER_TYPE(int) #define BFDEV_BITS_PER_LONG_LONG BFDEV_BITS_PER_TYPE(long long) diff --git a/include/bfdev/bitwalk-comp.h b/include/bfdev/bitwalk-comp.h index 78476731..12c89461 100644 --- a/include/bfdev/bitwalk-comp.h +++ b/include/bfdev/bitwalk-comp.h @@ -13,20 +13,12 @@ BFDEV_BEGIN_DECLS extern unsigned int -bfdev_comp_find_first_bit(const unsigned long *block, - unsigned int bits, bool swap); +bfdev_comp_find_first_bit(const unsigned long *block, unsigned int bits, + unsigned long invert, bool swap); extern unsigned int -bfdev_comp_find_last_bit(const unsigned long *block, - unsigned int bits, bool swap); - -extern unsigned int -bfdev_comp_find_first_zero(const unsigned long *block, - unsigned int bits, bool swap); - -extern unsigned int -bfdev_comp_find_last_zero(const unsigned long *block, - unsigned int bits, bool swap); +bfdev_comp_find_last_bit(const unsigned long *block, unsigned int bits, + unsigned long invert, bool swap); extern unsigned int bfdev_comp_find_next_bit(const unsigned long *addr1, const unsigned long *addr2, diff --git a/include/bfdev/bitwalk.h b/include/bfdev/bitwalk.h index b9ef2b46..86150060 100644 --- a/include/bfdev/bitwalk.h +++ b/include/bfdev/bitwalk.h @@ -26,10 +26,16 @@ BFDEV_BEGIN_DECLS static inline unsigned int bfdev_find_first_bit(const unsigned long *addr, unsigned int bits) { - if (bfdev_const_small_nbits(bits)) - return *addr ? bfdev_ffsuf(*addr & BFDEV_BIT_LOW_MASK(bits)) : bits; - else - return bfdev_comp_find_first_bit(addr, bits, false); + unsigned long value; + + if (!bfdev_const_small_nbits(bits)) + return bfdev_comp_find_first_bit(addr, bits, 0UL, false); + + value = *addr & BFDEV_BIT_LOW_MASK(bits); + if (value == BFDEV_ULONG_MIN) + return bits; + + return bfdev_ffsuf(value); } #endif @@ -37,10 +43,16 @@ bfdev_find_first_bit(const unsigned long *addr, unsigned int bits) static inline unsigned int bfdev_find_last_bit(const unsigned long *addr, unsigned int bits) { - if (bfdev_const_small_nbits(bits)) - return *addr ? bfdev_ffsuf(*addr & BFDEV_BIT_LOW_MASK(bits)) : bits; - else - return bfdev_comp_find_last_bit(addr, bits, false); + unsigned long value; + + if (!bfdev_const_small_nbits(bits)) + return bfdev_comp_find_last_bit(addr, bits, 0UL, false); + + value = *addr & BFDEV_BIT_LOW_MASK(bits); + if (value == BFDEV_ULONG_MIN) + return bits; + + return bfdev_flsuf(value); } #endif @@ -56,10 +68,16 @@ bfdev_find_last_bit(const unsigned long *addr, unsigned int bits) static inline unsigned int bfdev_find_first_zero(const unsigned long *addr, unsigned int bits) { - if (bfdev_const_small_nbits(bits)) - return *addr ? bfdev_ffz(*addr | BFDEV_BIT_HIGH_MASK(bits)) : bits; - else - return bfdev_comp_find_first_zero(addr, bits, false); + unsigned long value; + + if (!bfdev_const_small_nbits(bits)) + return bfdev_comp_find_first_bit(addr, bits, ~0UL, false); + + value = *addr | BFDEV_BIT_HIGH_MASK(bits); + if (value == BFDEV_ULONG_MAX) + return bits; + + return bfdev_ffzuf(value); } #endif @@ -67,10 +85,16 @@ bfdev_find_first_zero(const unsigned long *addr, unsigned int bits) static inline unsigned int bfdev_find_last_zero(const unsigned long *addr, unsigned int bits) { - if (bfdev_const_small_nbits(bits)) - return *addr ? bfdev_flz(*addr | BFDEV_BIT_HIGH_MASK(bits)) : bits; - else - return bfdev_comp_find_last_zero(addr, bits, false); + unsigned long value; + + if (!bfdev_const_small_nbits(bits)) + return bfdev_comp_find_last_bit(addr, bits, ~0UL, false); + + value = *addr | BFDEV_BIT_HIGH_MASK(bits); + if (value == BFDEV_ULONG_MAX) + return bits; + + return bfdev_flzuf(value); } #endif @@ -90,15 +114,17 @@ bfdev_find_next_bit(const unsigned long *addr, { unsigned long value; - if (bfdev_const_small_nbits(bits)) { - if (bfdev_unlikely(offset >= bits)) - return bits; + if (!bfdev_const_small_nbits(bits)) + return bfdev_comp_find_next_bit(addr, NULL, bits, offset, 0UL, false); + + if (bfdev_unlikely(offset >= bits)) + return bits; - value = *addr & BFDEV_BIT_RANGE(bits - 1, offset); - return value ? bfdev_ffsuf(value) : bits; - } + value = *addr & BFDEV_BIT_RANGE(bits - 1, offset); + if (value == BFDEV_ULONG_MIN) + return bits; - return bfdev_comp_find_next_bit(addr, NULL, bits, offset, 0UL, false); + return bfdev_ffsuf(value); } #endif @@ -109,15 +135,17 @@ bfdev_find_prev_bit(const unsigned long *addr, { unsigned long value; - if (bfdev_const_small_nbits(bits)) { - if (bfdev_unlikely(offset >= bits)) - return bits; + if (!bfdev_const_small_nbits(bits)) + return bfdev_comp_find_prev_bit(addr, NULL, bits, offset, 0UL, false); - value = *addr & BFDEV_BIT_RANGE(bits - 1, offset); - return value ? bfdev_flsuf(value) : bits; - } + if (bfdev_unlikely(offset >= bits)) + return bits; - return bfdev_comp_find_prev_bit(addr, NULL, bits, offset, 0UL, false); + value = *addr & BFDEV_BIT_LOW_MASK(offset + 1); + if (value == BFDEV_ULONG_MIN) + return bits; + + return bfdev_flsuf(value); } #endif @@ -137,15 +165,17 @@ bfdev_find_next_zero(const unsigned long *addr, { unsigned long value; - if (bfdev_const_small_nbits(bits)) { - if (bfdev_unlikely(offset >= bits)) - return bits; + if (!bfdev_const_small_nbits(bits)) + return bfdev_comp_find_next_bit(addr, NULL, bits, offset, ~0UL, false); + + if (bfdev_unlikely(offset >= bits)) + return bits; - value = *addr | ~BFDEV_BIT_RANGE(bits - 1, offset); - return value ? bfdev_ffzuf(value) : bits; - } + value = *addr | ~BFDEV_BIT_RANGE(bits - 1, offset); + if (value == BFDEV_ULONG_MAX) + return bits; - return bfdev_comp_find_next_bit(addr, NULL, bits, offset, ~0UL, false); + return bfdev_ffzuf(value); } #endif @@ -156,15 +186,17 @@ bfdev_find_prev_zero(const unsigned long *addr, { unsigned long value; - if (bfdev_const_small_nbits(bits)) { - if (bfdev_unlikely(offset >= bits)) - return bits; + if (!bfdev_const_small_nbits(bits)) + return bfdev_comp_find_prev_bit(addr, NULL, bits, offset, ~0UL, false); + + if (bfdev_unlikely(offset >= bits)) + return bits; - value = *addr | ~BFDEV_BIT_RANGE(bits - 1, offset); - return value ? bfdev_flzuf(value) : bits; - } + value = *addr | BFDEV_BIT_HIGH_MASK(offset + 1); + if (value == BFDEV_ULONG_MAX) + return bits; - return bfdev_comp_find_prev_bit(addr, NULL, bits, offset, ~0UL, false); + return bfdev_flzuf(value); } #endif @@ -185,15 +217,17 @@ bfdev_find_next_and_bit(const unsigned long *addr1, const unsigned long *addr2, { unsigned long value; - if (bfdev_const_small_nbits(bits)) { - if (bfdev_unlikely(offset >= bits)) - return bits; + if (bfdev_unlikely(offset >= bits)) + return bits; - value = *addr1 & *addr2 & BFDEV_BIT_RANGE(bits - 1, offset); - return value ? bfdev_ffsuf(value) : bits; - } + if (!bfdev_const_small_nbits(bits)) + return bfdev_comp_find_next_bit(addr1, addr2, bits, offset, 0UL, false); - return bfdev_comp_find_next_bit(addr1, addr2, bits, offset, 0UL, false); + value = *addr1 & *addr2 & BFDEV_BIT_RANGE(bits - 1, offset); + if (value == BFDEV_ULONG_MIN) + return bits; + + return value ? bfdev_ffsuf(value) : bits; } #endif @@ -204,15 +238,17 @@ bfdev_find_prev_and_bit(const unsigned long *addr1, const unsigned long *addr2, { unsigned long value; - if (bfdev_const_small_nbits(bits)) { - if (bfdev_unlikely(offset >= bits)) - return bits; + if (!bfdev_const_small_nbits(bits)) + return bfdev_comp_find_prev_bit(addr1, addr2, bits, offset, 0UL, false); + + if (bfdev_unlikely(offset >= bits)) + return bits; - value = *addr1 & *addr2 & BFDEV_BIT_RANGE(bits - 1, offset); - return value ? bfdev_flsuf(value) : bits; - } + value = *addr1 & *addr2 & BFDEV_BIT_LOW_MASK(offset + 1); + if (value == BFDEV_ULONG_MIN) + return bits; - return bfdev_comp_find_prev_bit(addr1, addr2, bits, offset, 0UL, false); + return value ? bfdev_flsuf(value) : bits; } #endif diff --git a/src/bitwalk.c b/src/bitwalk.c index 3a169fea..1694729c 100644 --- a/src/bitwalk.c +++ b/src/bitwalk.c @@ -9,95 +9,64 @@ #include export unsigned int -bfdev_comp_find_first_bit(const unsigned long *block, - unsigned int bits, bool swap) +bfdev_comp_find_first_bit(const unsigned long *block, unsigned int bits, + unsigned long invert, bool swap) { - unsigned int base; + unsigned long value; + unsigned int base, offset; for (base = 0; base < bits; base += BFDEV_BITS_PER_LONG) { - unsigned long value; - if (swap) value = bfdev_swabp(block); else value = *block; + value ^= invert; - if (value != BFDEV_ULONG_MIN) - return base + bfdev_ffsuf(value); - block++; - } + if (value == BFDEV_ULONG_MIN) { + block++; + continue; + } - return bits; -} + offset = base + bfdev_ffsuf(value); + if (offset >= bits) + break; -export unsigned int -bfdev_comp_find_last_bit(const unsigned long *block, - unsigned int bits, bool swap) -{ - if (bits) { - unsigned long val = BFDEV_BIT_LOW_MASK(bits); - unsigned long idx = (bits - 1) / BFDEV_BITS_PER_LONG; - - do { - unsigned long value; - - if (swap) - value = bfdev_swab(block[idx]); - else - value = block[idx]; - - if ((value ^ BFDEV_ULONG_MIN) & val) - return idx * BFDEV_BITS_PER_LONG + bfdev_flsuf(value); - val = BFDEV_ULONG_MAX; - } while (idx--); + return offset; } return bits; } export unsigned int -bfdev_comp_find_first_zero(const unsigned long *block, - unsigned int bits, bool swap) +bfdev_comp_find_last_bit(const unsigned long *block, unsigned int bits, + unsigned long invert, bool swap) { - unsigned int base; + unsigned long value, mask; + unsigned int base, offset; - for (base = 0; base < bits; base += BFDEV_BITS_PER_LONG) { - unsigned long value; + if (bfdev_unlikely(!bits)) + return 0; + mask = BFDEV_BIT_LOW_MASK(bits); + base = BFDEV_BITS_DIV_LONG(bits - 1); + + do { if (swap) - value = bfdev_swabp(block); + value = bfdev_swab(block[base]); else - value = *block; + value = block[base]; - if (value != BFDEV_ULONG_MAX) - return base + bfdev_ffzuf(value); - block++; - } + value ^= invert; + value &= mask; - return bits; -} + if (value == BFDEV_ULONG_MIN) { + mask = BFDEV_ULONG_MAX; + continue; + } -export unsigned int -bfdev_comp_find_last_zero(const unsigned long *block, - unsigned int bits, bool swap) -{ - if (bits) { - unsigned long val = BFDEV_BIT_LOW_MASK(bits); - unsigned long idx = (bits - 1) / BFDEV_BITS_PER_LONG; - - do { - unsigned long value; - - if (swap) - value = bfdev_swab(block[idx]); - else - value = block[idx]; - - if ((value ^ BFDEV_ULONG_MAX) & val) - return idx * BFDEV_BITS_PER_LONG + bfdev_flzuf(value); - val = BFDEV_ULONG_MAX; - } while (idx--); - } + offset = base * BFDEV_BITS_PER_LONG; + return offset + bfdev_flsuf(value); + } while (base--); return bits; } From 6b9883e835b5e23616449fab55f265b650435d20 Mon Sep 17 00:00:00 2001 From: John Sanpe Date: Tue, 2 Apr 2024 12:39:18 +0800 Subject: [PATCH 14/31] feat bitwalk: added iterator functions Signed-off-by: John Sanpe --- include/bfdev/bitwalk.h | 56 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/include/bfdev/bitwalk.h b/include/bfdev/bitwalk.h index 86150060..9fb21acd 100644 --- a/include/bfdev/bitwalk.h +++ b/include/bfdev/bitwalk.h @@ -252,6 +252,62 @@ bfdev_find_prev_and_bit(const unsigned long *addr1, const unsigned long *addr2, } #endif +#define bfdev_for_each_bit(index, bitmap, bits) \ + for ((index) = bfdev_find_first_bit(bitmap, bits); \ + (index) < (bits); \ + (index) = bfdev_find_next_bit(bitmap, bits, (index) + 1)) + +#define bfdev_for_each_zero(index, bitmap, bits) \ + for ((index) = bfdev_find_first_zero(bitmap, bits); \ + (index) < (bits); \ + (index) = bfdev_find_next_zero(bitmap, bits, (index) + 1)) + +#define bfdev_for_each_bit_reverse(index, bitmap, bits) \ + for ((index) = bfdev_find_last_bit(bitmap, bits); \ + (index) < (bits); \ + (index) = bfdev_find_prev_bit(bitmap, bits, (index) - 1)) + +#define bfdev_for_each_zero_reverse(index, bitmap, bits) \ + for ((index) = bfdev_find_last_zero(bitmap, bits); \ + (index) < (bits); \ + (index) = bfdev_find_prev_zero(bitmap, bits, (index) - 1)) + +#define bfdev_for_each_bit_form(index, bitmap, bits) \ + for (; (index) < (bits); \ + (index) = bfdev_find_next_bit(bitmap, bits, (index) + 1)) + +#define bfdev_for_each_zero_form(index, bitmap, bits) \ + for (; (index) < (bits); \ + (index) = bfdev_find_next_zero(bitmap, bits, (index) + 1)) + +#define bfdev_for_each_bit_reverse_form(index, bitmap, bits) \ + for (; (index) < (bits); \ + (index) = bfdev_find_prev_bit(bitmap, bits, (index) - 1)) + +#define bfdev_for_each_zero_reverse_form(index, bitmap, bits) \ + for (; (index) < (bits); \ + (index) = bfdev_find_prev_zero(bitmap, bits, (index) - 1)) + +#define bfdev_for_each_bit_continue(index, bitmap, bits) \ + for ((index) = bfdev_find_next_bit(bitmap, bits, (index) + 1); \ + (index) < (bits); \ + (index) = bfdev_find_next_bit(bitmap, bits, (index) + 1)) + +#define bfdev_for_each_zero_continue(index, bitmap, bits) \ + for ((index) = bfdev_find_next_zero(bitmap, bits, (index) + 1); \ + (index) < (bits); \ + (index) = bfdev_find_next_zero(bitmap, bits, (index) + 1)) + +#define bfdev_for_each_bit_reverse_continue(index, bitmap, bits) \ + for ((index) = bfdev_find_prev_bit(bitmap, bits, (index) - 1); \ + (index) < (bits); \ + (index) = bfdev_find_prev_bit(bitmap, bits, (index) - 1)) + +#define bfdev_for_each_zero_reverse_continue(index, bitmap, bits) \ + for ((index) = bfdev_find_prev_zero(bitmap, bits, (index) - 1); \ + (index) < (bits); \ + (index) = bfdev_find_prev_zero(bitmap, bits, (index) - 1)) + BFDEV_END_DECLS #endif /* _BFDEV_BITWALK_H_ */ From 15002d88cdfb9049a0e196e9db97aa777dde9899 Mon Sep 17 00:00:00 2001 From: John Sanpe Date: Tue, 2 Apr 2024 12:40:12 +0800 Subject: [PATCH 15/31] feat bitwalk: added fuzzy testsuite Signed-off-by: John Sanpe --- testsuite/CMakeLists.txt | 1 + testsuite/bitwalk/.gitignore | 2 + testsuite/bitwalk/CMakeLists.txt | 16 ++ testsuite/bitwalk/fuzzy.c | 334 +++++++++++++++++++++++++++++++ 4 files changed, 353 insertions(+) create mode 100644 testsuite/bitwalk/.gitignore create mode 100644 testsuite/bitwalk/CMakeLists.txt create mode 100644 testsuite/bitwalk/fuzzy.c diff --git a/testsuite/CMakeLists.txt b/testsuite/CMakeLists.txt index de5613d4..c972884a 100644 --- a/testsuite/CMakeLists.txt +++ b/testsuite/CMakeLists.txt @@ -7,5 +7,6 @@ include(build.cmake) include(testsuite.cmake) add_subdirectory(array) +add_subdirectory(bitwalk) add_subdirectory(list) add_subdirectory(slist) diff --git a/testsuite/bitwalk/.gitignore b/testsuite/bitwalk/.gitignore new file mode 100644 index 00000000..15915d7e --- /dev/null +++ b/testsuite/bitwalk/.gitignore @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +/bitwalk-fuzzy diff --git a/testsuite/bitwalk/CMakeLists.txt b/testsuite/bitwalk/CMakeLists.txt new file mode 100644 index 00000000..8b40f5ef --- /dev/null +++ b/testsuite/bitwalk/CMakeLists.txt @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright(c) 2024 John Sanpe +# + +add_executable(bitwalk-fuzzy fuzzy.c) +target_link_libraries(bitwalk-fuzzy bfdev testsuite) +add_test(bitwalk-fuzzy bitwalk-fuzzy) + +if(${CMAKE_PROJECT_NAME} STREQUAL "bfdev") + install(TARGETS + bitwalk-fuzzy + DESTINATION + ${CMAKE_INSTALL_DOCDIR}/testsuite + ) +endif() diff --git a/testsuite/bitwalk/fuzzy.c b/testsuite/bitwalk/fuzzy.c new file mode 100644 index 00000000..c754b03e --- /dev/null +++ b/testsuite/bitwalk/fuzzy.c @@ -0,0 +1,334 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright(c) 2023 John Sanpe + */ + +#define MODULE_NAME "bitwalk-fuzzy" +#define bfdev_log_fmt(fmt) MODULE_NAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TEST_SMALL_LOOP 10 +#define TEST_SMALL_SIZE 30 + +#define TEST_LARGE_LOOP 200 +#define TEST_LARGE_SIZE 500 + +static long +index_sort(const void *key1, const void *key2, void *pdata) +{ + unsigned int index1, index2; + + index1 = *(unsigned int *)key1; + index2 = *(unsigned int *)key2; + + return bfdev_cmp(index1 > index2); +} + +static int +bitwalk_bit(unsigned int size, unsigned int loop) +{ + unsigned long *bitmap; + unsigned int *record, count, index; + unsigned int verify, tmp1, tmp2; + int retval; + bool test; + + bitmap = bfdev_bitmap_alloc(NULL, size); + if (!bitmap) + return -BFDEV_ENOMEM; + + record = malloc(sizeof(*record) * loop); + if (!record) { + bfdev_bitmap_free(NULL, bitmap); + return -BFDEV_ENOMEM; + } + + srand(time(NULL)); + bfdev_bitmap_zero(bitmap, size); + + for (count = 0; count < loop; ++count) { + do { + index = (unsigned int)rand() % size; + test = bfdev_bit_test(bitmap, index); + } while (test); + + record[count] = index; + bfdev_bit_set(bitmap, index); + } + + bfdev_sort(record, loop, sizeof(*record), index_sort, NULL); + retval = -BFDEV_ENOERR; + + count = 0; + verify = 0; + + bfdev_for_each_bit(index, bitmap, size) { + bfdev_log_debug("'for_each_bit' test%u: %u\n", count, index); + verify++; + + if (index != record[count++]) { + retval = -BFDEV_EFAULT; + goto failed; + } + + if (count == loop / 2) + break; + } + + tmp1 = index; + tmp2 = count; + + bfdev_for_each_bit_continue(index, bitmap, size) { + bfdev_log_debug("'for_each_bit_continue' test%u: %u\n", count, index); + verify++; + + if (index != record[count++]) { + retval = -BFDEV_EFAULT; + goto failed; + } + } + + index = tmp1; + count = tmp2 - 1; + + bfdev_for_each_bit_form(index, bitmap, size) { + bfdev_log_debug("'for_each_bit_form' test%u: %u\n", count, index); + verify++; + + if (index != record[count++]) { + retval = -BFDEV_EFAULT; + goto failed; + } + } + + if (verify - 1 != loop + (loop / 2)) { + retval = -BFDEV_ENODATA; + goto failed; + } + + count = 0; + verify = 0; + + bfdev_for_each_bit_reverse(index, bitmap, size) { + bfdev_log_debug("'for_each_bit_reverse' test%u: %u\n", count, index); + verify++; + + if (index != record[loop - ++count]) { + retval = -BFDEV_EFAULT; + goto failed; + } + + if (count == loop / 2) + break; + } + + tmp1 = index; + tmp2 = count; + + bfdev_for_each_bit_reverse_continue(index, bitmap, size) { + bfdev_log_debug("'for_each_bit_reverse_continue' test%u: %u\n", count, index); + verify++; + + if (index != record[loop - ++count]) { + retval = -BFDEV_EFAULT; + goto failed; + } + } + + index = tmp1; + count = tmp2 - 1; + + bfdev_for_each_bit_reverse_form(index, bitmap, size) { + bfdev_log_debug("'for_each_bit_reverse_form' test%u: %u\n", count, index); + verify++; + + if (index != record[loop - ++count]) { + retval = -BFDEV_EFAULT; + goto failed; + } + } + + if (verify - 1 != loop + (loop / 2)) { + retval = -BFDEV_ENODATA; + goto failed; + } + +failed: + free(record); + bfdev_bitmap_free(NULL, bitmap); + return retval; +} + +static int +bitwalk_zero(unsigned int size, unsigned int loop) +{ + unsigned long *bitmap; + unsigned int *record, count, index; + unsigned int verify, tmp1, tmp2; + int retval; + bool test; + + bitmap = bfdev_bitmap_alloc(NULL, size); + if (!bitmap) + return -BFDEV_ENOMEM; + + record = malloc(sizeof(*record) * loop); + if (!record) { + bfdev_bitmap_free(NULL, bitmap); + return -BFDEV_ENOMEM; + } + + srand(time(NULL)); + bfdev_bitmap_fill(bitmap, size); + + for (count = 0; count < loop; ++count) { + do { + index = (unsigned int)rand() % size; + test = bfdev_bit_test(bitmap, index); + } while (!test); + + record[count] = index; + bfdev_bit_clr(bitmap, index); + } + + bfdev_sort(record, loop, sizeof(*record), index_sort, NULL); + retval = -BFDEV_ENOERR; + + count = 0; + verify = 0; + + bfdev_for_each_zero(index, bitmap, size) { + bfdev_log_debug("'for_each_zero' test%u: %u\n", count, index); + verify++; + + if (index != record[count++]) { + retval = -BFDEV_EFAULT; + goto failed; + } + + if (count == loop / 2) + break; + } + + tmp1 = index; + tmp2 = count; + + bfdev_for_each_zero_continue(index, bitmap, size) { + bfdev_log_debug("'for_each_zero_continue' test%u: %u\n", count, index); + verify++; + + if (index != record[count++]) { + retval = -BFDEV_EFAULT; + goto failed; + } + } + + index = tmp1; + count = tmp2 - 1; + + bfdev_for_each_zero_form(index, bitmap, size) { + bfdev_log_debug("'for_each_zero_form' test%u: %u\n", count, index); + verify++; + + if (index != record[count++]) { + retval = -BFDEV_EFAULT; + goto failed; + } + } + + if (verify - 1 != loop + (loop / 2)) { + retval = -BFDEV_ENODATA; + goto failed; + } + + count = 0; + verify = 0; + + bfdev_for_each_zero_reverse(index, bitmap, size) { + bfdev_log_debug("'for_each_zero_reverse' test%u: %u\n", count, index); + verify++; + + if (index != record[loop - ++count]) { + retval = -BFDEV_EFAULT; + goto failed; + } + + if (count == loop / 2) + break; + } + + tmp1 = index; + tmp2 = count; + + bfdev_for_each_zero_reverse_continue(index, bitmap, size) { + bfdev_log_debug("'for_each_zero_reverse_continue' test%u: %u\n", count, index); + verify++; + + if (index != record[loop - ++count]) { + retval = -BFDEV_EFAULT; + goto failed; + } + } + + index = tmp1; + count = tmp2 - 1; + + bfdev_for_each_zero_reverse_form(index, bitmap, size) { + bfdev_log_debug("'for_each_zero_reverse_form' test%u: %u\n", count, index); + verify++; + + if (index != record[loop - ++count]) { + retval = -BFDEV_EFAULT; + goto failed; + } + } + + if (verify - 1 != loop + (loop / 2)) { + retval = -BFDEV_ENODATA; + goto failed; + } + +failed: + free(record); + bfdev_bitmap_free(NULL, bitmap); + return retval; +} + +TESTSUITE( + "bitwalk:bit_small", NULL, NULL, + "" +) { + return bitwalk_bit(TEST_SMALL_SIZE, TEST_SMALL_LOOP); +} + +TESTSUITE( + "bitwalk:bit_large", NULL, NULL, + "" +) { + return bitwalk_bit(TEST_LARGE_SIZE, TEST_LARGE_LOOP); +} + +TESTSUITE( + "bitwalk:zero_small", NULL, NULL, + "" +) { + return bitwalk_zero(TEST_SMALL_SIZE, TEST_SMALL_LOOP); +} + + +TESTSUITE( + "bitwalk:zero_large", NULL, NULL, + "" +) { + return bitwalk_zero(TEST_LARGE_SIZE, TEST_LARGE_LOOP); +} From e49725e4e4f6b476619b71c0bba5bdddf860dfcb Mon Sep 17 00:00:00 2001 From: John Sanpe Date: Tue, 2 Apr 2024 23:28:56 +0800 Subject: [PATCH 16/31] fixup bfdev: added byte order check Signed-off-by: John Sanpe --- include/bfdev/bitmap.h | 15 ++++++++++----- include/bfdev/bitops-endian.h | 2 ++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/include/bfdev/bitmap.h b/include/bfdev/bitmap.h index b3c0978d..b85152e7 100644 --- a/include/bfdev/bitmap.h +++ b/include/bfdev/bitmap.h @@ -11,17 +11,22 @@ #include #include #include +#include #include #include BFDEV_BEGIN_DECLS -#ifdef CONFIG_ARCH_LITTLE_ENDIAN +#if defined(__BFDEV_LITTLE_ENDIAN__) # define BFDEV_BITMAP_ALIGN BFDEV_BITS_PER_BYTE -#else +#elif defined(__BFDEV_BIG_ENDIAN__) # define BFDEV_BITMAP_ALIGN (BFDEV_BITS_PER_BYTE * BFDEV_BYTES_PER_LONG) +#else +# error "Unknown endian" #endif -#define BFDEV_BITMAP_MASK (BFDEV_BITMAP_ALIGN - 1) + +#define BFDEV_BITMAP_MASK \ + (BFDEV_BITMAP_ALIGN - 1) #define BFDEV_DEFINE_BITMAP(name, bits) \ unsigned long name[BFDEV_BITS_TO_LONG(bits)]; @@ -40,7 +45,7 @@ bfdev_bitmap_empty(const unsigned long *src, unsigned int bits) if (!bfdev_bitmap_const_aligned(bits)) return bfdev_find_first_bit(src, bits) >= bits; - return !bfdev_memdiff(src, BFDEV_UINT_MIN, bits / BFDEV_BITS_PER_BYTE); + return !bfdev_memdiff(src, BFDEV_UINT8_MIN, bits / BFDEV_BITS_PER_BYTE); } static __bfdev_always_inline bool @@ -52,7 +57,7 @@ bfdev_bitmap_full(const unsigned long *src, unsigned int bits) if (!bfdev_bitmap_const_aligned(bits)) return bfdev_find_first_zero(src, bits) >= bits; - return !bfdev_memdiff(src, BFDEV_UINT_MAX, bits / BFDEV_BITS_PER_BYTE); + return !bfdev_memdiff(src, BFDEV_UINT8_MAX, bits / BFDEV_BITS_PER_BYTE); } static __bfdev_always_inline bool diff --git a/include/bfdev/bitops-endian.h b/include/bfdev/bitops-endian.h index fa0252f4..c3fc4190 100644 --- a/include/bfdev/bitops-endian.h +++ b/include/bfdev/bitops-endian.h @@ -19,6 +19,8 @@ BFDEV_BEGIN_DECLS #elif defined(__BFDEV_BIG_ENDIAN__) # define BFDEV_BITOPS_LE_SWIZZLE ((BFDEV_BITS_PER_LONG - 1) & ~0x7) # define BFDEV_BITOPS_BE_SWIZZLE 0 +#else +# error "Unknown endian" #endif static inline void From a3fd31a4434c9f011676bf400c6c387c9083c19c Mon Sep 17 00:00:00 2001 From: John Sanpe Date: Tue, 2 Apr 2024 23:40:02 +0800 Subject: [PATCH 17/31] fixup testsuite: added testsuite target dependencies Signed-off-by: John Sanpe --- testsuite/testsuite.cmake | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/testsuite/testsuite.cmake b/testsuite/testsuite.cmake index bb84f082..08b10f98 100644 --- a/testsuite/testsuite.cmake +++ b/testsuite/testsuite.cmake @@ -9,9 +9,10 @@ function(testsuite_target name src replace) TESTSUIT_OBJECT "${BFDEV_LIBRARY}" ) - add_library(target OBJECT ${src}) - target_compile_options(target PRIVATE -include ${replace}) + add_library("${name}_target" OBJECT ${src}) + target_compile_options("${name}_target" PRIVATE -include ${replace}) + bfdev_dependencies("${name}_target") add_executable("${name}" ${TESTSUIT_OBJECT}) - target_link_libraries("${name}" testsuite target) + target_link_libraries("${name}" "${name}_target" testsuite) endfunction() From b770fdaf573676277dd63417ce0ed00ad06e7c2f Mon Sep 17 00:00:00 2001 From: John Sanpe Date: Wed, 3 Apr 2024 16:53:28 +0800 Subject: [PATCH 18/31] feat mpi: supports static initialization Signed-off-by: John Sanpe --- examples/mpi/bbp.c | 57 +++--- examples/mpi/fibonacci.c | 35 ++-- examples/mpi/helper.h | 20 +- examples/mpi/machin.c | 43 ++-- include/bfdev/mpi.h | 26 ++- src/mpi.c | 409 ++++++++++++++++++++++----------------- 6 files changed, 334 insertions(+), 256 deletions(-) diff --git a/examples/mpi/bbp.c b/examples/mpi/bbp.c index 7c1f4fd8..03c314f7 100644 --- a/examples/mpi/bbp.c +++ b/examples/mpi/bbp.c @@ -27,38 +27,37 @@ factor2[] = { int main(int argc, const char *argv[]) { - bfdev_mpi_t *vv[4], *vq; + bfdev_mpi_t vq, vv[4]; unsigned int k, i, v; int retval; - if (!((vv[0] = bfdev_mpi_create(NULL)) && - (vv[1] = bfdev_mpi_create(NULL)) && - (vv[2] = bfdev_mpi_create(NULL)) && - (vv[3] = bfdev_mpi_create(NULL)) && - (vq = bfdev_mpi_create(NULL)))) - return 1; + bfdev_mpi_init(&vq, NULL); + bfdev_mpi_init(&vv[0], NULL); + bfdev_mpi_init(&vv[1], NULL); + bfdev_mpi_init(&vv[2], NULL); + bfdev_mpi_init(&vv[3], NULL); bfdev_log_info("Convergence BBP %d:\n", TEST_LEN); EXAMPLE_TIME_STATISTICAL( for (i = 0; i < 4; ++i) { - retval = bfdev_mpi_seti(vv[i], 0); + retval = bfdev_mpi_seti(&vv[i], 0); if (retval) return retval; v = factor1[i] + (TEST_LEN << 2); - retval = bfdev_mpi_bseti(vv[i], v); + retval = bfdev_mpi_bseti(&vv[i], v); if (retval) return retval; v = factor2[i]; - retval = bfdev_mpi_divi(vv[i], vv[i], vv[i], v); + retval = bfdev_mpi_divi(&vv[i], &vv[i], &vv[i], v); if (retval) return retval; if (i) - retval = bfdev_mpi_sub(vq, vq, vv[i]); + retval = bfdev_mpi_sub(&vq, &vq, &vv[i]); else - retval = bfdev_mpi_add(vq, vq, *vv); + retval = bfdev_mpi_add(&vq, &vq, vv); if (retval) return retval; @@ -66,27 +65,29 @@ int main(int argc, const char *argv[]) for (k = 1; k < TEST_LEN; ++k) { for (i = 0; i < 4; ++i) { - retval = bfdev_mpi_seti(vv[i], 0); + retval = bfdev_mpi_seti(&vv[i], 0); if (retval) return retval; v = factor1[i] + ((TEST_LEN - k) << 2); - retval = bfdev_mpi_bseti(vv[i], v); + retval = bfdev_mpi_bseti(&vv[i], v); if (retval) return retval; v = factor2[i] | (k << 3); - retval = bfdev_mpi_divi(vv[i], vv[i], vv[i], v); + retval = bfdev_mpi_divi(&vv[i], &vv[i], &vv[i], v); if (retval) return retval; - if (i) - retval = bfdev_mpi_sub(vq, vq, vv[i]); - else - retval = bfdev_mpi_add(vq, vq, *vv); - - if (retval) - return retval; + if (i) { + retval = bfdev_mpi_sub(&vq, &vq, &vv[i]); + if (retval) + return retval; + } else { + retval = bfdev_mpi_add(&vq, &vq, vv); + if (retval) + return retval; + } } } 0; @@ -95,7 +96,7 @@ int main(int argc, const char *argv[]) #if PRINT_RESULT char *result; - result = print_num(vq, 16); + result = print_num(&vq, 16); if (!result) return 1; @@ -104,11 +105,11 @@ int main(int argc, const char *argv[]) free(result); #endif - bfdev_mpi_destory(vv[0]); - bfdev_mpi_destory(vv[1]); - bfdev_mpi_destory(vv[2]); - bfdev_mpi_destory(vv[3]); - bfdev_mpi_destory(vq); + bfdev_mpi_release(&vv[0]); + bfdev_mpi_release(&vv[1]); + bfdev_mpi_release(&vv[2]); + bfdev_mpi_release(&vv[3]); + bfdev_mpi_release(&vq); return 0; } diff --git a/examples/mpi/fibonacci.c b/examples/mpi/fibonacci.c index 1afc5849..cc80d82b 100644 --- a/examples/mpi/fibonacci.c +++ b/examples/mpi/fibonacci.c @@ -13,33 +13,38 @@ int main(int argc, const char *argv[]) { - bfdev_mpi_t *va, *vb, *vc; unsigned int count; char *result; int retval; - if (!((va = bfdev_mpi_create(NULL)) && - (vb = bfdev_mpi_create(NULL)) && - (vc = bfdev_mpi_create(NULL)))) - return 1; + BFDEV_DEFINE_MPI(va, NULL); + BFDEV_DEFINE_MPI(vb, NULL); + BFDEV_DEFINE_MPI(vc, NULL); + + bfdev_mpi_seti(&va, 0); + bfdev_mpi_seti(&vb, 0); + vb.plus = 0; + + retval = bfdev_mpi_cmp(&va, &vb); + printf("%d\n", retval); - if ((retval = bfdev_mpi_seti(va, 1)) || - (retval = bfdev_mpi_seti(vb, 0)) || - (retval = bfdev_mpi_seti(vc, 0))) + if ((retval = bfdev_mpi_seti(&va, 1)) || + (retval = bfdev_mpi_seti(&vb, 0)) || + (retval = bfdev_mpi_seti(&vc, 0))) return retval; EXAMPLE_TIME_STATISTICAL( for (count = 0; count < TEST_LOOP - 1; ++count) { - if ((retval = bfdev_mpi_add(vc, va, vb)) || - (retval = bfdev_mpi_set(vb, va)) || - (retval = bfdev_mpi_set(va, vc))) + if ((retval = bfdev_mpi_add(&vc, &va, &vb)) || + (retval = bfdev_mpi_set(&vb, &va)) || + (retval = bfdev_mpi_set(&va, &vc))) return retval; } 0; ); #if PRINT_RESULT - result = print_num(va, 10); + result = print_num(&va, 10); if (!result) return 1; @@ -47,9 +52,9 @@ int main(int argc, const char *argv[]) free(result); #endif - bfdev_mpi_destory(va); - bfdev_mpi_destory(vb); - bfdev_mpi_destory(vc); + bfdev_mpi_release(&va); + bfdev_mpi_release(&vb); + bfdev_mpi_release(&vc); return 0; } diff --git a/examples/mpi/helper.h b/examples/mpi/helper.h index 5d025617..46d2ecd4 100644 --- a/examples/mpi/helper.h +++ b/examples/mpi/helper.h @@ -15,28 +15,26 @@ static inline char * print_num(const bfdev_mpi_t *var, unsigned int base) { BFDEV_DEFINE_ARRAY(stack, NULL, sizeof(char)); - bfdev_mpi_t *taken, *value; unsigned long count; char *buffer, *str; size_t size; int retval; - if (!((value = bfdev_mpi_create(NULL)) && - (taken = bfdev_mpi_create(NULL)))) - return NULL; + BFDEV_DEFINE_MPI(value, NULL); + BFDEV_DEFINE_MPI(taken, NULL); - retval = bfdev_mpi_set(value, var); + retval = bfdev_mpi_set(&value, var); if (retval) return NULL; - while (bfdev_mpi_cmpi(value, 0)) { + while (bfdev_mpi_cmpi(&value, 0)) { const BFDEV_MPI_TYPE *walk; - retval = bfdev_mpi_divi(value, taken, value, base); + retval = bfdev_mpi_divi(&value, &taken, &value, base); if (retval) return NULL; - walk = bfdev_mpi_data(taken, 0, NULL); + walk = bfdev_mpi_data(&taken, NULL); if (!walk) return NULL; @@ -69,6 +67,8 @@ print_num(const bfdev_mpi_t *var, unsigned int base) size = bfdev_array_size(&stack); buffer = malloc(size + 1); + if (!buffer) + return NULL; for (count = 0; count < size; ++count) { str = bfdev_array_pop(&stack, 1); @@ -78,8 +78,8 @@ print_num(const bfdev_mpi_t *var, unsigned int base) buffer[count] = '\0'; bfdev_array_release(&stack); - bfdev_mpi_destory(taken); - bfdev_mpi_destory(value); + bfdev_mpi_release(&taken); + bfdev_mpi_release(&value); return buffer; } diff --git a/examples/mpi/machin.c b/examples/mpi/machin.c index 25262a4c..504a6276 100644 --- a/examples/mpi/machin.c +++ b/examples/mpi/machin.c @@ -19,15 +19,14 @@ int main(int argc, const char *argv[]) { - bfdev_mpi_t *vw, *vs, *vv, *vq; + bfdev_mpi_t vw, vs, vv, vq; unsigned int k; int retval; - if (!((vw = bfdev_mpi_create(NULL)) && - (vs = bfdev_mpi_create(NULL)) && - (vv = bfdev_mpi_create(NULL)) && - (vq = bfdev_mpi_create(NULL)))) - return 1; + bfdev_mpi_init(&vw, NULL); + bfdev_mpi_init(&vs, NULL); + bfdev_mpi_init(&vv, NULL); + bfdev_mpi_init(&vq, NULL); /** * Machin-like formula: @@ -38,30 +37,30 @@ int main(int argc, const char *argv[]) * arctan(x) = x - (x^3)/3 + (x^5)/5 - (x^7)/7 + ... */ - if ((retval = bfdev_mpi_seti(vw, 16 * 5)) || - (retval = bfdev_mpi_seti(vv, 4 * 239)) || - (retval = bfdev_mpi_seti(vq, 10000))) + if ((retval = bfdev_mpi_seti(&vw, 16 * 5)) || + (retval = bfdev_mpi_seti(&vv, 4 * 239)) || + (retval = bfdev_mpi_seti(&vq, 10000))) return retval; for (k = 0; k < TEST_SIZE; ++k) { - if ((retval = bfdev_mpi_mul(vw, vw, vq)) || - (retval = bfdev_mpi_mul(vv, vv, vq))) + if ((retval = bfdev_mpi_mul(&vw, &vw, &vq)) || + (retval = bfdev_mpi_mul(&vv, &vv, &vq))) return retval; } bfdev_log_info("Convergence Machin %d:\n", TEST_LEN); EXAMPLE_TIME_STATISTICAL( for (k = 1; k <= TEST_LOOP; ++k) { - if ((retval = bfdev_mpi_divi(vw, vw, vw, 5 * 5)) || - (retval = bfdev_mpi_divi(vv, vv, vv, 239 * 239)) || - (retval = bfdev_mpi_sub(vq, vw, vv)) || - (retval = bfdev_mpi_divi(vq, vq, vq, 2 * k - 1))) + if ((retval = bfdev_mpi_divi(&vw, &vw, &vw, 5 * 5)) || + (retval = bfdev_mpi_divi(&vv, &vv, &vv, 239 * 239)) || + (retval = bfdev_mpi_sub(&vq, &vw, &vv)) || + (retval = bfdev_mpi_divi(&vq, &vq, &vq, 2 * k - 1))) return retval; if (k & 1) - retval = bfdev_mpi_add(vs, vs, vq); + retval = bfdev_mpi_add(&vs, &vs, &vq); else - retval = bfdev_mpi_sub(vs, vs, vq); + retval = bfdev_mpi_sub(&vs, &vs, &vq); if (retval) return retval; @@ -72,7 +71,7 @@ int main(int argc, const char *argv[]) #if PRINT_RESULT char *result; - result = print_num(vs, 10); + result = print_num(&vs, 10); if (!result) return 1; @@ -81,10 +80,10 @@ int main(int argc, const char *argv[]) free(result); #endif - bfdev_mpi_destory(vw); - bfdev_mpi_destory(vs); - bfdev_mpi_destory(vv); - bfdev_mpi_destory(vq); + bfdev_mpi_release(&vw); + bfdev_mpi_release(&vs); + bfdev_mpi_release(&vv); + bfdev_mpi_release(&vq); return 0; } diff --git a/include/bfdev/mpi.h b/include/bfdev/mpi.h index 2c90ab3f..204620aa 100644 --- a/include/bfdev/mpi.h +++ b/include/bfdev/mpi.h @@ -22,11 +22,27 @@ BFDEV_BEGIN_DECLS typedef struct bfdev_mpi bfdev_mpi_t; struct bfdev_mpi { - const bfdev_alloc_t *alloc; bfdev_array_t value; bool plus; }; +#define BFDEV_MPI_STATIC(alloc) { \ + .value = BFDEV_ARRAY_STATIC(alloc, BFDEV_MPI_SIZE), \ + .plus = true, \ +} + +#define BFDEV_MPI_INIT(alloc) \ + (bfdev_mpi_t) BFDEV_MPI_STATIC(alloc) + +#define BFDEV_DEFINE_MPI(name, alloc) \ + bfdev_mpi_t name = BFDEV_MPI_INIT(alloc) + +static inline void +bfdev_mpi_init(bfdev_mpi_t *mpi, bfdev_alloc_t *alloc) +{ + *mpi = BFDEV_MPI_INIT(alloc); +} + static inline unsigned long bfdev_mpi_length(const bfdev_mpi_t *mpi) { @@ -125,14 +141,10 @@ bfdev_mpi_import(bfdev_mpi_t *var, const BFDEV_MPI_TYPE *buffer, unsigned long length, bool sign); extern const BFDEV_MPI_TYPE * -bfdev_mpi_data(const bfdev_mpi_t *var, - unsigned long index, bool *sign); - -extern bfdev_mpi_t * -bfdev_mpi_create(const bfdev_alloc_t *alloc); +bfdev_mpi_data(const bfdev_mpi_t *var, bool *sign); extern void -bfdev_mpi_destory(bfdev_mpi_t *var); +bfdev_mpi_release(bfdev_mpi_t *var); BFDEV_END_DECLS diff --git a/src/mpi.c b/src/mpi.c index fa8a5cb6..e30b1774 100644 --- a/src/mpi.c +++ b/src/mpi.c @@ -17,6 +17,9 @@ #define mpi_val(mpi) bfdev_array_data(&(mpi)->value, 0) #define mpi_resize(mpi, size) bfdev_array_resize(&(mpi)->value, size) +static const +BFDEV_MPI_TYPE mpi_zero; + /** * Multi Precision Array Computing. * @@ -42,15 +45,12 @@ mpa_cmpi(const BFDEV_MPI_TYPE *ptra, BFDEV_MPI_TYPE vi, unsigned long length) { if (length > 1) - return 1; + return BFDEV_BT; - if (*ptra != vi) { - if (*ptra > vi) - return 1; - return -1; - } + if (*ptra != vi) + return bfdev_cmp(*ptra > vi); - return 0; + return BFDEV_EQ; } static inline int @@ -59,11 +59,8 @@ mpa_cmp(const BFDEV_MPI_TYPE *ptra, const BFDEV_MPI_TYPE *ptrb, { unsigned long length; - if (lena != lenb) { - if (lena > lenb) - return 1; - return -1; - } + if (lena != lenb) + return bfdev_cmp(lena > lenb); ptra += lena - 1; ptrb += lenb - 1; @@ -75,13 +72,10 @@ mpa_cmp(const BFDEV_MPI_TYPE *ptra, const BFDEV_MPI_TYPE *ptrb, ptrb--; } - if (length) { - if (*ptra > *ptrb) - return 1; - return -1; - } + if (length) + return bfdev_cmp(*ptra > *ptrb); - return 0; + return BFDEV_EQ; } static inline bool @@ -343,7 +337,7 @@ mpa_divrem(BFDEV_MPI_TYPE *ptrs, { BFDEV_MPI_TYPE dhigh, dlow, value; unsigned long index; - bool limb; + bool limb, borrow; /** * Argument constraints: @@ -365,7 +359,9 @@ mpa_divrem(BFDEV_MPI_TYPE *ptrs, limb = false; if (value >= dhigh) { if (value > dhigh || mpa_cmp(ptra, ptrb, cntb - 1, cntb - 1) >= 0) { - mpa_sub(ptra, ptra, ptrb, cntb, cntb, false); + borrow = mpa_sub(ptra, ptra, ptrb, cntb, cntb, false); + BFDEV_BUG_ON(borrow); + value = ptra[cntb - 1]; limb = true; } @@ -429,7 +425,7 @@ mpi_relocation(bfdev_mpi_t *var) { BFDEV_MPI_TYPE *value; - while (mpi_len(var) > 1) { + while (mpi_len(var)) { value = bfdev_array_peek(&var->value, 1); if (*value) break; @@ -438,21 +434,6 @@ mpi_relocation(bfdev_mpi_t *var) } } -static inline int -mpi_set(bfdev_mpi_t *dest, BFDEV_MPI_TYPE vi) -{ - BFDEV_MPI_TYPE *value; - - bfdev_array_reset(&dest->value); - value = bfdev_array_push(&dest->value, 1); - if (bfdev_unlikely(!value)) - return -BFDEV_ENOMEM; - - *value = vi; - - return -BFDEV_ENOERR; -} - static inline int mpi_extend(bfdev_mpi_t *var, unsigned long length) { @@ -475,28 +456,58 @@ mpi_extend(bfdev_mpi_t *var, unsigned long length) } static inline int -mpi_copy(bfdev_mpi_t *dest, const bfdev_mpi_t *src) +mpi_copy(bfdev_mpi_t *var, const BFDEV_MPI_TYPE *buffer, + unsigned long length) { - BFDEV_MPI_TYPE *ptrs, *ptra; - unsigned long length; + BFDEV_MPI_TYPE *ptrs; int retval; - if (dest == src) - return -BFDEV_EINVAL; - - length = mpi_len(src); - retval = mpi_resize(dest, length); + retval = mpi_resize(var, length); if (bfdev_unlikely(retval)) return retval; - ptrs = mpi_val(dest); - ptra = mpi_val(src); + if (length) { + ptrs = mpi_val(var); + mpa_copy(ptrs, buffer, length); + mpi_relocation(var); + } - mpa_copy(ptrs, ptra, length); + return -BFDEV_ENOERR; +} + +static inline int +mpi_seti(bfdev_mpi_t *dest, BFDEV_MPI_TYPE vi) +{ + BFDEV_MPI_TYPE *value; + int retval; + + retval = bfdev_array_resize(&dest->value, !!vi); + if (bfdev_unlikely(retval)) + return retval; + + if (vi) { + value = mpi_val(dest); + *value = vi; + } return -BFDEV_ENOERR; } +static inline int +mpi_set(bfdev_mpi_t *dest, const bfdev_mpi_t *src) +{ + BFDEV_MPI_TYPE *ptra; + unsigned long length; + + if (dest == src) + return -BFDEV_ENOERR; + + length = mpi_len(src); + ptra = mpi_val(src); + + return mpi_copy(dest, ptra, length); +} + static inline int mpi_cmpi(const bfdev_mpi_t *va, BFDEV_MPI_TYPE vi) { @@ -506,6 +517,12 @@ mpi_cmpi(const bfdev_mpi_t *va, BFDEV_MPI_TYPE vi) length = mpi_len(va); value = mpi_val(va); + if (!length) { + if (vi) + return BFDEV_LT; + return BFDEV_EQ; + } + return mpa_cmpi(value, vi, length); } @@ -518,6 +535,15 @@ mpi_cmp(const bfdev_mpi_t *va, const bfdev_mpi_t *vb) lena = mpi_len(va); lenb = mpi_len(vb); + if (!lena) { + if (lenb) + return BFDEV_LT; + return BFDEV_EQ; + } + + if (!lenb) + return BFDEV_BT; + ptra = mpi_val(va); ptrb = mpi_val(vb); @@ -533,7 +559,10 @@ mpi_addi(bfdev_mpi_t *dest, bool carry; int retval; + /* parameter check */ length = mpi_len(va); + if (!length) + return mpi_seti(dest, vi); retval = mpi_resize(dest, length + 1); if (bfdev_unlikely(retval)) @@ -558,16 +587,21 @@ mpi_add(bfdev_mpi_t *dest, bool carry; int retval; + /* parameter check */ + cnta = mpi_len(va); + if (!cnta) + return mpi_set(dest, vb); + cntb = mpi_len(vb); - ptrb = mpi_val(vb); + if (!cntb) + return mpi_set(dest, va); /* degrade to addi */ + ptrb = mpi_val(vb); if (cntb == 1) return mpi_addi(dest, va, *ptrb); - cnta = mpi_len(va); length = bfdev_max(cnta, cntb); - retval = mpi_resize(dest, length + 1); if (bfdev_unlikely(retval)) return retval; @@ -591,7 +625,9 @@ mpi_subi(bfdev_mpi_t *dest, bool borrow; int retval; + /* parameter check */ length = mpi_len(va); + BFDEV_BUG_ON(!length); retval = mpi_resize(dest, length); if (bfdev_unlikely(retval)) @@ -616,10 +652,13 @@ mpi_sub(bfdev_mpi_t *dest, bool borrow; int retval; + /* parameter check */ cntb = mpi_len(vb); - ptrb = mpi_val(vb); + if (!cntb) + return mpi_set(dest, va); /* degrade to subi */ + ptrb = mpi_val(vb); if (cntb == 1) return mpi_subi(dest, va, *ptrb); @@ -649,7 +688,10 @@ mpi_muli(bfdev_mpi_t *dest, unsigned long length; int retval; + /* parameter check */ length = mpi_len(va); + if (!length || !vi) + return mpi_seti(dest, 0); retval = mpi_resize(dest, length + 1); if (bfdev_unlikely(retval)) @@ -675,10 +717,17 @@ mpi_mul(bfdev_mpi_t *dest, int retval; bool nval; + /* parameter check */ + cnta = mpi_len(va); + if (!cnta) + return mpi_seti(dest, 0); + cntb = mpi_len(vb); - ptrb = mpi_val(vb); + if (!cntb) + return mpi_seti(dest, 0); /* degrade to muli */ + ptrb = mpi_val(vb); if (cntb == 1) return mpi_muli(dest, va, *ptrb); @@ -691,7 +740,6 @@ mpi_mul(bfdev_mpi_t *dest, nval = true; } - cnta = mpi_len(va); length = cnta + cntb; retval = bfdev_array_resize(buffer, length); @@ -720,12 +768,24 @@ mpi_divi(bfdev_mpi_t *quot, bfdev_mpi_t *rem, unsigned long length; int retval; + /* parameter check */ + length = mpi_len(va); + if (!length) { + retval = mpi_seti(quot, 0); + if (retval) + return retval; + + retval = mpi_seti(rem, 0); + if (retval) + return retval; + + return -BFDEV_ENOERR; + } + /* divide by zero */ if (bfdev_unlikely(!vi)) return -BFDEV_EOVERFLOW; - length = mpi_len(va); - retval = mpi_resize(quot, length); if (bfdev_unlikely(retval)) return retval; @@ -735,7 +795,7 @@ mpi_divi(bfdev_mpi_t *quot, bfdev_mpi_t *rem, value = mpa_divmodi(ptrs, ptra, vi, length); if (quot != rem) - mpi_set(rem, value); + mpi_seti(rem, value); mpi_relocation(quot); return -BFDEV_ENOERR; @@ -748,6 +808,11 @@ mpi_modi(bfdev_mpi_t *rem, BFDEV_MPI_TYPE *ptra, value; unsigned long length; + /* parameter check */ + length = mpi_len(va); + if (!length) + return mpi_seti(rem, 0); + /* divide by zero */ if (bfdev_unlikely(!vi)) return -BFDEV_EOVERFLOW; @@ -756,7 +821,7 @@ mpi_modi(bfdev_mpi_t *rem, ptra = mpi_val(va); value = mpa_modi(ptra, vi, length); - mpi_set(rem, value); + mpi_seti(rem, value); return -BFDEV_ENOERR; } @@ -771,19 +836,32 @@ mpi_div(bfdev_mpi_t *quot, bfdev_mpi_t *rem, bool limb, nval; int retval; + /* parameter check */ + length = mpi_len(va); + if (!length) { + retval = mpi_seti(quot, 0); + if (retval) + return retval; + + retval = mpi_seti(rem, 0); + if (retval) + return retval; + + return -BFDEV_ENOERR; + } + + /* divide by zero */ cntb = mpi_len(vb); - ptrb = mpi_val(vb); + if (bfdev_unlikely(!cntb)) + return -BFDEV_EOVERFLOW; /* degrade to divi */ + ptrb = mpi_val(vb); if (cntb == 1) return mpi_divi(quot, rem, va, *ptrb); - /* divide by zero */ - if (bfdev_unlikely(!mpi_cmpi(vb, 0))) - return -BFDEV_EOVERFLOW; - if (rem != va) { - retval = mpi_copy(rem, va); + retval = mpi_set(rem, va); if (bfdev_unlikely(retval)) return retval; } @@ -837,19 +915,23 @@ mpi_mod(bfdev_mpi_t *rem, unsigned long cnta, cntb; int retval; + /* parameter check */ + cnta = mpi_len(va); + if (!cnta) + return mpi_seti(rem, 0); + + /* divide by zero */ cntb = mpi_len(vb); - ptrb = mpi_val(vb); + if (bfdev_unlikely(!cntb)) + return -BFDEV_EOVERFLOW; /* degrade to divi */ + ptrb = mpi_val(vb); if (cntb == 1) return mpi_modi(rem, va, *ptrb); - /* divide by zero */ - if (bfdev_unlikely(!mpi_cmpi(vb, 0))) - return -BFDEV_EOVERFLOW; - if (rem != va) { - retval = mpi_copy(rem, va); + retval = mpi_set(rem, va); if (bfdev_unlikely(retval)) return retval; } @@ -877,6 +959,10 @@ mpi_and(bfdev_mpi_t *dest, cntb = mpi_len(vb); length = bfdev_min(cnta, cntb); + /* parameter check */ + if (!length) + return mpi_seti(dest, 0); + retval = mpi_resize(dest, length); if (bfdev_unlikely(retval)) return retval; @@ -903,6 +989,10 @@ mpi_or(bfdev_mpi_t *dest, cntb = mpi_len(vb); length = bfdev_max(cnta, cntb); + /* parameter check */ + if (!length) + return mpi_seti(dest, 0); + retval = mpi_resize(dest, length); if (bfdev_unlikely(retval)) return retval; @@ -937,6 +1027,10 @@ mpi_xor(bfdev_mpi_t *dest, cntb = mpi_len(vb); length = bfdev_max(cnta, cntb); + /* parameter check */ + if (!length) + return mpi_seti(dest, 0); + retval = mpi_resize(dest, length); if (bfdev_unlikely(retval)) return retval; @@ -968,18 +1062,20 @@ mpi_shli(bfdev_mpi_t *dest, unsigned long length, cnta; int retval; - if (dest == va && !shift) - return -BFDEV_ENOERR; + /* parameter check */ + if (!shift) + return mpi_set(dest, va); cnta = mpi_len(va); - length = cnta + BFDEV_BITS_TO_LONG(shift); + if (!cnta) + return mpi_seti(dest, 0); + length = cnta + BFDEV_BITS_TO_LONG(shift); retval = mpi_resize(dest, length); if (bfdev_unlikely(retval)) return retval; ptrs = mpi_val(dest); - if (dest != va) { ptra = mpi_val(va); mpa_copy(ptrs, ptra, cnta); @@ -999,10 +1095,13 @@ mpi_shri(bfdev_mpi_t *dest, unsigned long length; int retval; - if (dest == va && !shift) - return -BFDEV_ENOERR; + /* parameter check */ + if (!shift) + return mpi_set(dest, va); length = mpi_len(va); + if (!length) + return mpi_seti(dest, 0); retval = mpi_resize(dest, length); if (bfdev_unlikely(retval)) @@ -1029,33 +1128,24 @@ bfdev_mpi_cmp(const bfdev_mpi_t *va, const bfdev_mpi_t *vb) { int diff; - if (va->plus != vb->plus) { - if (va->plus) - return 1; - return -1; - } + if (va->plus != vb->plus) + return bfdev_cmp(va->plus); diff = mpi_cmp(va, vb); - if (!diff) - return 0; + if (diff > 0) + return bfdev_cmp(va->plus); - if (diff > 0) { - if (va->plus) - return 1; - return -1; - } + if (diff < 0) + return bfdev_cmp(!va->plus); - /* diff < 0 */ - if (va->plus) - return -1; - return 1; + return BFDEV_EQ; } export int bfdev_mpi_cmpi(const bfdev_mpi_t *va, BFDEV_MPI_TYPE vi) { if (!va->plus) - return -1; + return BFDEV_LT; return mpi_cmpi(va, vi); } @@ -1085,15 +1175,15 @@ bfdev_mpi_add(bfdev_mpi_t *dest, diff = mpi_cmp(va, vb); switch (diff) { - case 0: default: - retval = mpi_set(dest, 0); + case BFDEV_EQ: default: + retval = mpi_seti(dest, 0); if (bfdev_unlikely(retval)) return retval; dest->plus = true; break; - case 1: + case BFDEV_BT: retval = mpi_sub(dest, va, vb); if (bfdev_unlikely(retval)) return retval; @@ -1101,7 +1191,7 @@ bfdev_mpi_add(bfdev_mpi_t *dest, dest->plus = va->plus; break; - case -1: + case BFDEV_LT: retval = mpi_sub(dest, vb, va); if (bfdev_unlikely(retval)) return retval; @@ -1131,24 +1221,24 @@ bfdev_mpi_addi(bfdev_mpi_t *dest, diff = bfdev_mpi_cmpi(va, vi); switch (diff) { - case 0: default: - retval = mpi_set(dest, 0); + case BFDEV_EQ: default: + retval = mpi_seti(dest, 0); if (bfdev_unlikely(retval)) return retval; dest->plus = true; break; - case -1: + case BFDEV_LT: value = mpi_val(va); - retval = mpi_set(dest, vi - *value); + retval = mpi_seti(dest, vi - *value); if (bfdev_unlikely(retval)) return retval; dest->plus = true; break; - case 1: + case BFDEV_BT: retval = mpi_subi(dest, va, vi); if (bfdev_unlikely(retval)) return retval; @@ -1177,15 +1267,15 @@ bfdev_mpi_sub(bfdev_mpi_t *dest, diff = mpi_cmp(va, vb); switch (diff) { - case 0: default: - retval = mpi_set(dest, 0); + case BFDEV_EQ: default: + retval = mpi_seti(dest, 0); if (bfdev_unlikely(retval)) return retval; dest->plus = true; break; - case 1: + case BFDEV_BT: retval = mpi_sub(dest, va, vb); if (bfdev_unlikely(retval)) return retval; @@ -1193,7 +1283,7 @@ bfdev_mpi_sub(bfdev_mpi_t *dest, dest->plus = va->plus; break; - case -1: + case BFDEV_LT: retval = mpi_sub(dest, vb, va); if (bfdev_unlikely(retval)) return retval; @@ -1223,24 +1313,24 @@ bfdev_mpi_subi(bfdev_mpi_t *dest, diff = mpi_cmpi(va, vi); switch (diff) { - case 0: default: - retval = mpi_set(dest, 0); + case BFDEV_EQ: default: + retval = mpi_seti(dest, 0); if (bfdev_unlikely(retval)) return retval; dest->plus = true; break; - case -1: + case BFDEV_LT: value = mpi_val(va); - retval = mpi_set(dest, vi - *value); + retval = mpi_seti(dest, vi - *value); if (bfdev_unlikely(retval)) return retval; dest->plus = false; break; - case 1: + case BFDEV_BT: retval = mpi_subi(dest, va, vi); if (bfdev_unlikely(retval)) return retval; @@ -1298,12 +1388,12 @@ bfdev_mpi_div(bfdev_mpi_t *quot, bfdev_mpi_t *rem, diff = mpi_cmp(va, vb); switch (diff) { - case 0: default: - retval = mpi_set(quot, 1); + case BFDEV_EQ: default: + retval = mpi_seti(quot, 1); if (bfdev_unlikely(retval)) return retval; - retval = mpi_set(rem, 0); + retval = mpi_seti(rem, 0); if (bfdev_unlikely(retval)) return retval; @@ -1311,9 +1401,9 @@ bfdev_mpi_div(bfdev_mpi_t *quot, bfdev_mpi_t *rem, rem->plus = true; break; - case -1: + case BFDEV_LT: if (rem != va) { - retval = mpi_copy(rem, va); + retval = mpi_set(rem, va); if (bfdev_unlikely(retval)) return retval; @@ -1321,14 +1411,14 @@ bfdev_mpi_div(bfdev_mpi_t *quot, bfdev_mpi_t *rem, } /* quot can be equal to va */ - retval = mpi_set(quot, 0); + retval = mpi_seti(quot, 0); if (bfdev_unlikely(retval)) return retval; quot->plus = true; break; - case 1: + case BFDEV_BT: retval = mpi_div(quot, rem, va, vb); if (bfdev_unlikely(retval)) return retval; @@ -1349,12 +1439,12 @@ bfdev_mpi_divi(bfdev_mpi_t *quot, bfdev_mpi_t *rem, diff = mpi_cmpi(va, vi); switch (diff) { - case 0: default: - retval = mpi_set(quot, 1); + case BFDEV_EQ: default: + retval = mpi_seti(quot, 1); if (bfdev_unlikely(retval)) return retval; - retval = mpi_set(rem, 0); + retval = mpi_seti(rem, 0); if (bfdev_unlikely(retval)) return retval; @@ -1362,9 +1452,9 @@ bfdev_mpi_divi(bfdev_mpi_t *quot, bfdev_mpi_t *rem, rem->plus = true; break; - case -1: + case BFDEV_LT: if (rem != va) { - retval = mpi_copy(rem, va); + retval = mpi_set(rem, va); if (bfdev_unlikely(retval)) return retval; @@ -1372,14 +1462,14 @@ bfdev_mpi_divi(bfdev_mpi_t *quot, bfdev_mpi_t *rem, } /* quot can be equal to va */ - retval = mpi_set(quot, 0); + retval = mpi_seti(quot, 0); if (bfdev_unlikely(retval)) return retval; quot->plus = true; break; - case 1: + case BFDEV_BT: retval = mpi_divi(quot, rem, va, vi); if (bfdev_unlikely(retval)) return retval; @@ -1400,17 +1490,17 @@ bfdev_mpi_mod(bfdev_mpi_t *rem, diff = mpi_cmp(va, vb); switch (diff) { - case 0: default: - retval = mpi_set(rem, 0); + case BFDEV_EQ: default: + retval = mpi_seti(rem, 0); if (bfdev_unlikely(retval)) return retval; rem->plus = true; break; - case -1: + case BFDEV_LT: if (rem != va) { - retval = mpi_copy(rem, va); + retval = mpi_set(rem, va); if (bfdev_unlikely(retval)) return retval; @@ -1418,7 +1508,7 @@ bfdev_mpi_mod(bfdev_mpi_t *rem, } break; - case 1: + case BFDEV_BT: retval = mpi_mod(rem, va, vb); if (bfdev_unlikely(retval)) return retval; @@ -1438,17 +1528,17 @@ bfdev_mpi_modi(bfdev_mpi_t *rem, diff = mpi_cmpi(va, vi); switch (diff) { - case 0: default: - retval = mpi_set(rem, 0); + case BFDEV_EQ: default: + retval = mpi_seti(rem, 0); if (bfdev_unlikely(retval)) return retval; rem->plus = true; break; - case -1: + case BFDEV_LT: if (rem != va) { - retval = mpi_copy(rem, va); + retval = mpi_set(rem, va); if (bfdev_unlikely(retval)) return retval; @@ -1456,7 +1546,7 @@ bfdev_mpi_modi(bfdev_mpi_t *rem, } break; - case 1: + case BFDEV_BT: retval = mpi_modi(rem, va, vi); if (bfdev_unlikely(retval)) return retval; @@ -1607,7 +1697,7 @@ bfdev_mpi_seti(bfdev_mpi_t *dest, BFDEV_MPI_TYPE val) { int retval; - retval = mpi_set(dest, val); + retval = mpi_seti(dest, val); if (bfdev_unlikely(retval)) return retval; @@ -1621,7 +1711,7 @@ bfdev_mpi_set(bfdev_mpi_t *dest, const bfdev_mpi_t *src) { int retval; - retval = mpi_copy(dest, src); + retval = mpi_set(dest, src); if (bfdev_unlikely(retval)) return retval; @@ -1634,64 +1724,35 @@ export int bfdev_mpi_import(bfdev_mpi_t *var, const BFDEV_MPI_TYPE *buffer, unsigned long length, bool sign) { - BFDEV_MPI_TYPE *data; int retval; - retval = mpi_resize(var, length); + retval = mpi_copy(var, buffer, length); if (bfdev_unlikely(retval)) return retval; - data = mpi_val(var); - mpa_copy(data, buffer, length); var->plus = sign; return -BFDEV_ENOERR; } export const BFDEV_MPI_TYPE * -bfdev_mpi_data(const bfdev_mpi_t *var, - unsigned long index, bool *sign) +bfdev_mpi_data(const bfdev_mpi_t *var, bool *sign) { - BFDEV_MPI_TYPE *data; + const BFDEV_MPI_TYPE *retval; - data = bfdev_array_data(&var->value, index); - if (bfdev_unlikely(!data)) - return NULL; + if (!mpi_len(var)) + retval = &mpi_zero; + else + retval = mpi_val(var); if (sign) *sign = var->plus; - return data; -} - -export bfdev_mpi_t * -bfdev_mpi_create(const bfdev_alloc_t *alloc) -{ - bfdev_mpi_t *var; - int retval; - - var = bfdev_malloc(alloc, sizeof(*var)); - if (bfdev_unlikely(!var)) - return NULL; - - var->alloc = alloc; - bfdev_array_init(&var->value, alloc, BFDEV_MPI_SIZE); - retval = bfdev_mpi_seti(var, 0); - - if (bfdev_unlikely(retval)) { - bfdev_free(alloc, var); - return NULL; - } - - return var; + return retval; } export void -bfdev_mpi_destory(bfdev_mpi_t *var) +bfdev_mpi_release(bfdev_mpi_t *var) { - const bfdev_alloc_t *alloc; - - alloc = var->alloc; bfdev_array_release(&var->value); - bfdev_free(alloc, var); } From cd84a7528e808f529d564449664d36a80318d12c Mon Sep 17 00:00:00 2001 From: John Sanpe Date: Wed, 3 Apr 2024 16:54:01 +0800 Subject: [PATCH 19/31] feat mpi: added initial testsuite Signed-off-by: John Sanpe --- testsuite/CMakeLists.txt | 1 + testsuite/mpi/.gitignore | 3 + testsuite/mpi/CMakeLists.txt | 21 +++ testsuite/mpi/empty.c | 241 +++++++++++++++++++++++++++++++++++ testsuite/mpi/fuzzy.c | 144 +++++++++++++++++++++ 5 files changed, 410 insertions(+) create mode 100644 testsuite/mpi/.gitignore create mode 100644 testsuite/mpi/CMakeLists.txt create mode 100644 testsuite/mpi/empty.c create mode 100644 testsuite/mpi/fuzzy.c diff --git a/testsuite/CMakeLists.txt b/testsuite/CMakeLists.txt index c972884a..f2ea2e5f 100644 --- a/testsuite/CMakeLists.txt +++ b/testsuite/CMakeLists.txt @@ -9,4 +9,5 @@ include(testsuite.cmake) add_subdirectory(array) add_subdirectory(bitwalk) add_subdirectory(list) +add_subdirectory(mpi) add_subdirectory(slist) diff --git a/testsuite/mpi/.gitignore b/testsuite/mpi/.gitignore new file mode 100644 index 00000000..ee6fb154 --- /dev/null +++ b/testsuite/mpi/.gitignore @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +/mpi-empty +/mpi-fuzzy diff --git a/testsuite/mpi/CMakeLists.txt b/testsuite/mpi/CMakeLists.txt new file mode 100644 index 00000000..7b9948e9 --- /dev/null +++ b/testsuite/mpi/CMakeLists.txt @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright(c) 2024 John Sanpe +# + +add_executable(mpi-fuzzy fuzzy.c) +target_link_libraries(mpi-fuzzy bfdev testsuite) +add_test(mpi-fuzzy mpi-fuzzy) + +add_executable(mpi-empty empty.c) +target_link_libraries(mpi-empty bfdev testsuite) +add_test(mpi-empty mpi-empty) + +if(${CMAKE_PROJECT_NAME} STREQUAL "bfdev") + install(TARGETS + mpi-fuzzy + mpi-empty + DESTINATION + ${CMAKE_INSTALL_DOCDIR}/testsuite + ) +endif() diff --git a/testsuite/mpi/empty.c b/testsuite/mpi/empty.c new file mode 100644 index 00000000..94548eef --- /dev/null +++ b/testsuite/mpi/empty.c @@ -0,0 +1,241 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright(c) 2024 John Sanpe + */ + +#include +#include + +TESTSUITE( + "mpi:add", NULL, NULL, + "mpi add empty test" +) { + int retval; + + BFDEV_DEFINE_MPI(va, NULL); + BFDEV_DEFINE_MPI(vb, NULL); + + retval = bfdev_mpi_add(&va, &va, &vb); + if (retval) + goto failed; + + retval = bfdev_mpi_cmpi(&va, 0); + if (retval) { + retval = -BFDEV_EFAULT; + goto failed; + } + +failed: + bfdev_mpi_release(&va); + bfdev_mpi_release(&vb); + + return retval; +} + +TESTSUITE( + "mpi:sub", NULL, NULL, + "mpi sub empty test" +) { + int retval; + + BFDEV_DEFINE_MPI(va, NULL); + BFDEV_DEFINE_MPI(vb, NULL); + + retval = bfdev_mpi_sub(&va, &va, &vb); + if (retval) + goto failed; + + retval = bfdev_mpi_cmpi(&va, 0); + if (retval) { + retval = -BFDEV_EFAULT; + goto failed; + } + +failed: + bfdev_mpi_release(&va); + bfdev_mpi_release(&vb); + + return retval; +} + +TESTSUITE( + "mpi:mul", NULL, NULL, + "mpi mul empty test" +) { + int retval; + + BFDEV_DEFINE_MPI(va, NULL); + BFDEV_DEFINE_MPI(vb, NULL); + + retval = bfdev_mpi_mul(&va, &va, &vb); + if (retval) + goto failed; + + retval = bfdev_mpi_cmpi(&va, 0); + if (retval) { + retval = -BFDEV_EFAULT; + goto failed; + } + +failed: + bfdev_mpi_release(&va); + bfdev_mpi_release(&vb); + + return retval; +} + +TESTSUITE( + "mpi:div", NULL, NULL, + "mpi div empty test" +) { + int retval; + + BFDEV_DEFINE_MPI(va, NULL); + BFDEV_DEFINE_MPI(vb, NULL); + + retval = bfdev_mpi_seti(&vb, 1); + if (retval) + goto failed; + + retval = bfdev_mpi_div(&va, &va, &va, &vb); + if (retval) + goto failed; + + retval = bfdev_mpi_cmpi(&va, 0); + if (retval) { + retval = -BFDEV_EFAULT; + goto failed; + } + +failed: + bfdev_mpi_release(&va); + bfdev_mpi_release(&vb); + + return retval; +} + +TESTSUITE( + "mpi:and", NULL, NULL, + "mpi bit and empty test" +) { + int retval; + + BFDEV_DEFINE_MPI(va, NULL); + BFDEV_DEFINE_MPI(vb, NULL); + + retval = bfdev_mpi_and(&va, &va, &vb); + if (retval) + goto failed; + + retval = bfdev_mpi_cmpi(&va, 0); + if (retval) { + retval = -BFDEV_EFAULT; + goto failed; + } + +failed: + bfdev_mpi_release(&va); + bfdev_mpi_release(&vb); + + return retval; +} + +TESTSUITE( + "mpi:or", NULL, NULL, + "mpi bit or empty test" +) { + int retval; + + BFDEV_DEFINE_MPI(va, NULL); + BFDEV_DEFINE_MPI(vb, NULL); + + retval = bfdev_mpi_or(&va, &va, &vb); + if (retval) + goto failed; + + retval = bfdev_mpi_cmpi(&va, 0); + if (retval) { + retval = -BFDEV_EFAULT; + goto failed; + } + +failed: + bfdev_mpi_release(&va); + bfdev_mpi_release(&vb); + + return retval; +} + +TESTSUITE( + "mpi:xor", NULL, NULL, + "mpi bit xor empty test" +) { + int retval; + + BFDEV_DEFINE_MPI(va, NULL); + BFDEV_DEFINE_MPI(vb, NULL); + + retval = bfdev_mpi_xor(&va, &va, &vb); + if (retval) + goto failed; + + retval = bfdev_mpi_cmpi(&va, 0); + if (retval) { + retval = -BFDEV_EFAULT; + goto failed; + } + +failed: + bfdev_mpi_release(&va); + bfdev_mpi_release(&vb); + + return retval; +} + +TESTSUITE( + "mpi:shl", NULL, NULL, + "mpi shift left empty test" +) { + int retval; + + BFDEV_DEFINE_MPI(va, NULL); + + retval = bfdev_mpi_shli(&va, &va, 1); + if (retval) + goto failed; + + retval = bfdev_mpi_cmpi(&va, 0); + if (retval) { + retval = -BFDEV_EFAULT; + goto failed; + } + +failed: + bfdev_mpi_release(&va); + + return retval; +} + +TESTSUITE( + "mpi:shr", NULL, NULL, + "mpi shift right empty test" +) { + int retval; + + BFDEV_DEFINE_MPI(va, NULL); + + retval = bfdev_mpi_shri(&va, &va, 1); + if (retval) + goto failed; + + retval = bfdev_mpi_cmpi(&va, 0); + if (retval) { + retval = -BFDEV_EFAULT; + goto failed; + } + +failed: + bfdev_mpi_release(&va); + + return retval; +} diff --git a/testsuite/mpi/fuzzy.c b/testsuite/mpi/fuzzy.c new file mode 100644 index 00000000..a1d1c3b4 --- /dev/null +++ b/testsuite/mpi/fuzzy.c @@ -0,0 +1,144 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright(c) 2024 John Sanpe + */ + +#include +#include +#include + +#define TEST_LOOP 100 +#define TEST_SIZE 512 + +static inline int +filling_random(bfdev_mpi_t *var, unsigned int length) +{ + BFDEV_MPI_TYPE *buff; + size_t size, count; + int retval; + + size = sizeof(*buff) * length; + buff = bfdev_malloc(NULL, size); + if (bfdev_unlikely(!buff)) + return -BFDEV_ENOMEM; + + for (count = 0; count < size; ++count) + ((char *)buff)[count] = rand(); + + retval = bfdev_mpi_import(var, buff, length, buff[0] & 1); + bfdev_free(NULL, buff); + + return retval; +} + +TESTSUITE( + "mpi:add", NULL, NULL, + "mpi add fuzzy test" +) { + unsigned int count; + int retval; + + BFDEV_DEFINE_MPI(va, NULL); + BFDEV_DEFINE_MPI(vb, NULL); + + if ((retval = filling_random(&va, TEST_SIZE)) || + (retval = filling_random(&vb, TEST_SIZE))) + goto failed; + + for (count = 0; count < TEST_LOOP; ++count) { + retval = bfdev_mpi_add(&va, &va, &vb); + if (retval) + goto failed; + } + +failed: + bfdev_mpi_release(&va); + bfdev_mpi_release(&vb); + return retval; +} + +TESTSUITE( + "mpi:sub", NULL, NULL, + "mpi sub fuzzy test" +) { + unsigned int count; + int retval; + + BFDEV_DEFINE_MPI(va, NULL); + BFDEV_DEFINE_MPI(vb, NULL); + + if ((retval = filling_random(&va, TEST_SIZE)) || + (retval = filling_random(&vb, TEST_SIZE))) + goto failed; + + for (count = 0; count < TEST_LOOP; ++count) { + retval = bfdev_mpi_sub(&va, &va, &vb); + if (retval) + goto failed; + } + +failed: + bfdev_mpi_release(&va); + bfdev_mpi_release(&vb); + return retval; +} + +TESTSUITE( + "mpi:mul", NULL, NULL, + "mpi mul fuzzy test" +) { + unsigned int count; + int retval; + + BFDEV_DEFINE_MPI(result, NULL); + BFDEV_DEFINE_MPI(va, NULL); + BFDEV_DEFINE_MPI(vb, NULL); + + if ((retval = filling_random(&va, TEST_SIZE)) || + (retval = filling_random(&vb, TEST_SIZE))) + goto failed; + + for (count = 0; count < TEST_LOOP; ++count) { + retval = bfdev_mpi_mul(&result, &va, &vb); + if (retval) + goto failed; + } + +failed: + bfdev_mpi_release(&result); + bfdev_mpi_release(&va); + bfdev_mpi_release(&vb); + return retval; +} + +TESTSUITE( + "mpi:div", NULL, NULL, + "mpi div fuzzy test" +) { + unsigned int count; + int retval; + + BFDEV_DEFINE_MPI(result, NULL); + BFDEV_DEFINE_MPI(va, NULL); + BFDEV_DEFINE_MPI(vb, NULL); + + if ((retval = filling_random(&va, TEST_SIZE)) || + (retval = filling_random(&vb, TEST_SIZE))) + goto failed; + + retval = bfdev_mpi_seti(&vb, 1); + if (retval) + goto failed; + + for (count = 0; count < TEST_LOOP; ++count) { + retval = bfdev_mpi_div(&result, &result, &va, &vb); + if (retval) + goto failed; + } + +failed: + bfdev_mpi_release(&result); + bfdev_mpi_release(&va); + bfdev_mpi_release(&vb); + return retval; +} From 43ab2cefde9b5417a15d3bee3915751f4a601052 Mon Sep 17 00:00:00 2001 From: John Sanpe Date: Thu, 4 Apr 2024 17:28:22 +0800 Subject: [PATCH 20/31] feat fsm: added transition condition check function Signed-off-by: John Sanpe --- include/bfdev/fsm.h | 29 +++++++++++++++++++++++++---- src/fsm.c | 8 +------- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/include/bfdev/fsm.h b/include/bfdev/fsm.h index 5b17b791..82f87282 100644 --- a/include/bfdev/fsm.h +++ b/include/bfdev/fsm.h @@ -122,8 +122,8 @@ bfdev_fsm_curr(bfdev_fsm_t *fsm) } /** - * bfdev_fsm_curr() - Get the previous state. - * @fsm: the state machine to get the current state from. + * bfdev_fsm_prev() - Get the previous state. + * @fsm: the state machine to get the previous state from. * * Return a pointer to the previous state. */ @@ -157,8 +157,29 @@ bfdev_fsm_finished(bfdev_fsm_t *fsm) } /** - * bfdev_fsm_handle() - Pass an event to the state machine. - * @fsm: the state machine to pass an event to. + * bfdev_fsm_cond() - Check if transition meet the condition of event. + * @trans: the transition to be checked. + * @event: the event to be handled. + * + * Return true if the transition meeted. + */ +static inline bool +bfdev_fsm_cond(const bfdev_fsm_transition_t *trans, bfdev_fsm_event_t *event) +{ + /* A transition for the given event has been found. */ + if (trans->type != event->type) + return false; + + /* If transition is guarded, ensure that the condition is held. */ + if (!trans->guard) + return true; + + return !trans->guard(event, trans->cond); +} + +/** + * bfdev_fsm_error() - Set the state machine to into the error state. + * @fsm: the state machine to enter the error state. * @event: the event to be handled. * * Return the entry trigger return value of the error state. diff --git a/src/fsm.c b/src/fsm.c index 51564146..21b568ce 100644 --- a/src/fsm.c +++ b/src/fsm.c @@ -26,13 +26,7 @@ fsm_find_transition(const bfdev_fsm_state_t *state, bfdev_fsm_event_t *event) for (count = 0; count < state->tnum; ++count) { find = &state->trans[count]; - - /* A transition for the given event has been found. */ - if (find->type != event->type) - continue; - - /* If transition is guarded, ensure that the condition is held. */ - if (!find->guard || !find->guard(event, find->cond)) + if (bfdev_fsm_cond(find, event)) return find; } From 4cb89c68aebdf04b6b0ee1a0c976f67efb5bc82b Mon Sep 17 00:00:00 2001 From: John Sanpe Date: Fri, 5 Apr 2024 12:00:30 +0800 Subject: [PATCH 21/31] perf mpi: optimize logic under variable rename Signed-off-by: John Sanpe --- include/bfdev/mpi.h | 7 +-- src/mpi.c | 124 ++++++++++++++++++++------------------------ 2 files changed, 59 insertions(+), 72 deletions(-) diff --git a/include/bfdev/mpi.h b/include/bfdev/mpi.h index 204620aa..13382d69 100644 --- a/include/bfdev/mpi.h +++ b/include/bfdev/mpi.h @@ -22,13 +22,14 @@ BFDEV_BEGIN_DECLS typedef struct bfdev_mpi bfdev_mpi_t; struct bfdev_mpi { + const bfdev_alloc_t *alloc; bfdev_array_t value; bool plus; }; -#define BFDEV_MPI_STATIC(alloc) { \ - .value = BFDEV_ARRAY_STATIC(alloc, BFDEV_MPI_SIZE), \ - .plus = true, \ +#define BFDEV_MPI_STATIC(ALLOC) { \ + .alloc = (ALLOC), .plus = true, \ + .value = BFDEV_ARRAY_STATIC(ALLOC, BFDEV_MPI_SIZE), \ } #define BFDEV_MPI_INIT(alloc) \ diff --git a/src/mpi.c b/src/mpi.c index e30b1774..3481df79 100644 --- a/src/mpi.c +++ b/src/mpi.c @@ -420,7 +420,7 @@ mpa_divrem(BFDEV_MPI_TYPE *ptrs, * calculating unsigned mpi. */ -static inline void +static __bfdev_always_inline void mpi_relocation(bfdev_mpi_t *var) { BFDEV_MPI_TYPE *value; @@ -481,7 +481,7 @@ mpi_seti(bfdev_mpi_t *dest, BFDEV_MPI_TYPE vi) BFDEV_MPI_TYPE *value; int retval; - retval = bfdev_array_resize(&dest->value, !!vi); + retval = mpi_resize(dest, !!vi); if (bfdev_unlikely(retval)) return retval; @@ -711,11 +711,11 @@ static inline int mpi_mul(bfdev_mpi_t *dest, const bfdev_mpi_t *va, const bfdev_mpi_t *vb) { + BFDEV_DEFINE_MPI(buffer, dest->alloc); BFDEV_MPI_TYPE *ptrs, *ptra, *ptrb; unsigned long length, cnta, cntb; - bfdev_array_t *buffer, array; + bfdev_mpi_t *rename; int retval; - bool nval; /* parameter check */ cnta = mpi_len(va); @@ -731,31 +731,27 @@ mpi_mul(bfdev_mpi_t *dest, if (cntb == 1) return mpi_muli(dest, va, *ptrb); - nval = false; - if (dest != va && dest != vb) - buffer = &dest->value; - else { - bfdev_array_init(&array, dest->value.alloc, BFDEV_MPI_SIZE); - buffer = &array; - nval = true; + rename = NULL; + if (dest == va && dest == vb) { + rename = dest; + dest = &buffer; } length = cnta + cntb; - - retval = bfdev_array_resize(buffer, length); + retval = mpi_resize(dest, length); if (bfdev_unlikely(retval)) return retval; + ptrs = mpi_val(dest); ptra = mpi_val(va); - ptrs = bfdev_array_data(buffer, 0); mpa_mul(ptrs, ptra, ptrb, cnta, cntb); + mpi_relocation(dest); - if (nval) { - bfdev_array_release(&dest->value); - dest->value = array; + if (rename) { + mpi_set(rename, dest); + bfdev_mpi_release(dest); } - mpi_relocation(dest); return -BFDEV_ENOERR; } @@ -768,6 +764,10 @@ mpi_divi(bfdev_mpi_t *quot, bfdev_mpi_t *rem, unsigned long length; int retval; + /* divide by zero */ + if (bfdev_unlikely(!vi)) + return -BFDEV_EOVERFLOW; + /* parameter check */ length = mpi_len(va); if (!length) { @@ -782,10 +782,6 @@ mpi_divi(bfdev_mpi_t *quot, bfdev_mpi_t *rem, return -BFDEV_ENOERR; } - /* divide by zero */ - if (bfdev_unlikely(!vi)) - return -BFDEV_EOVERFLOW; - retval = mpi_resize(quot, length); if (bfdev_unlikely(retval)) return retval; @@ -794,9 +790,10 @@ mpi_divi(bfdev_mpi_t *quot, bfdev_mpi_t *rem, ptra = mpi_val(va); value = mpa_divmodi(ptrs, ptra, vi, length); + mpi_relocation(quot); + if (quot != rem) mpi_seti(rem, value); - mpi_relocation(quot); return -BFDEV_ENOERR; } @@ -808,15 +805,15 @@ mpi_modi(bfdev_mpi_t *rem, BFDEV_MPI_TYPE *ptra, value; unsigned long length; + /* divide by zero */ + if (bfdev_unlikely(!vi)) + return -BFDEV_EOVERFLOW; + /* parameter check */ length = mpi_len(va); if (!length) return mpi_seti(rem, 0); - /* divide by zero */ - if (bfdev_unlikely(!vi)) - return -BFDEV_EOVERFLOW; - length = mpi_len(va); ptra = mpi_val(va); @@ -830,15 +827,26 @@ static inline int mpi_div(bfdev_mpi_t *quot, bfdev_mpi_t *rem, const bfdev_mpi_t *va, const bfdev_mpi_t *vb) { + BFDEV_DEFINE_MPI(buffer, quot->alloc); BFDEV_MPI_TYPE *ptrs, *ptra, *ptrb; unsigned long cnta, cntb, length; - bfdev_array_t *buffer, array; - bool limb, nval; + bfdev_mpi_t *rename; + bool limb; int retval; + /* divide by zero */ + cntb = mpi_len(vb); + if (bfdev_unlikely(!cntb)) + return -BFDEV_EOVERFLOW; + + /* degrade to divi */ + ptrb = mpi_val(vb); + if (cntb == 1) + return mpi_divi(quot, rem, va, *ptrb); + /* parameter check */ - length = mpi_len(va); - if (!length) { + cnta = mpi_len(va); + if (!cnta) { retval = mpi_seti(quot, 0); if (retval) return retval; @@ -850,39 +858,24 @@ mpi_div(bfdev_mpi_t *quot, bfdev_mpi_t *rem, return -BFDEV_ENOERR; } - /* divide by zero */ - cntb = mpi_len(vb); - if (bfdev_unlikely(!cntb)) - return -BFDEV_EOVERFLOW; - - /* degrade to divi */ - ptrb = mpi_val(vb); - if (cntb == 1) - return mpi_divi(quot, rem, va, *ptrb); - if (rem != va) { retval = mpi_set(rem, va); if (bfdev_unlikely(retval)) return retval; } - nval = false; - if (quot != va) - buffer = "->value; - else { - bfdev_array_init(&array, va->value.alloc, BFDEV_MPI_SIZE); - buffer = &array; - nval = true; + rename = NULL; + if (quot == va) { + rename = quot; + quot = &buffer; } - cnta = mpi_len(va); length = cnta + cntb; - - retval = bfdev_array_resize(buffer, length); + retval = mpi_resize(quot, length); if (bfdev_unlikely(retval)) return retval; - ptrs = bfdev_array_data(buffer, 0); + ptrs = mpi_val(quot); ptra = mpi_val(rem); limb = mpa_divrem(ptrs, ptra, ptrb, cnta, cntb); @@ -893,17 +886,17 @@ mpi_div(bfdev_mpi_t *quot, bfdev_mpi_t *rem, length += 1; } - if (nval) { - bfdev_array_release("->value); - quot->value = array; - } - BFDEV_BUG_ON(mpi_resize(quot, length)); BFDEV_BUG_ON(mpi_resize(rem, cntb)); mpi_relocation(quot); mpi_relocation(rem); + if (rename) { + mpi_set(rename, quot); + bfdev_mpi_release(quot); + } + return -BFDEV_ENOERR; } @@ -915,11 +908,6 @@ mpi_mod(bfdev_mpi_t *rem, unsigned long cnta, cntb; int retval; - /* parameter check */ - cnta = mpi_len(va); - if (!cnta) - return mpi_seti(rem, 0); - /* divide by zero */ cntb = mpi_len(vb); if (bfdev_unlikely(!cntb)) @@ -930,6 +918,11 @@ mpi_mod(bfdev_mpi_t *rem, if (cntb == 1) return mpi_modi(rem, va, *ptrb); + /* parameter check */ + cnta = mpi_len(va); + if (!cnta) + return mpi_seti(rem, 0); + if (rem != va) { retval = mpi_set(rem, va); if (bfdev_unlikely(retval)) @@ -940,7 +933,6 @@ mpi_mod(bfdev_mpi_t *rem, ptra = mpi_val(rem); mpa_divrem(NULL, ptra, ptrb, cnta, cntb); - BFDEV_BUG_ON(mpi_resize(rem, cntb)); mpi_relocation(rem); @@ -1609,9 +1601,6 @@ bfdev_mpi_shli(bfdev_mpi_t *dest, { int retval; - if (dest == va && !shift) - return -BFDEV_ENOERR; - retval = mpi_shli(dest, va, shift); if (bfdev_unlikely(retval)) return retval; @@ -1627,9 +1616,6 @@ bfdev_mpi_shri(bfdev_mpi_t *dest, { int retval; - if (dest == va && !shift) - return -BFDEV_ENOERR; - retval = mpi_shri(dest, va, shift); if (bfdev_unlikely(retval)) return retval; From ceee18a05773da19a98b204d86e9ce23a2af9908 Mon Sep 17 00:00:00 2001 From: John Sanpe Date: Fri, 5 Apr 2024 12:01:23 +0800 Subject: [PATCH 22/31] fixup mpi: remove debug code in fibonacci example Signed-off-by: John Sanpe --- examples/mpi/fibonacci.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/examples/mpi/fibonacci.c b/examples/mpi/fibonacci.c index cc80d82b..030bafe9 100644 --- a/examples/mpi/fibonacci.c +++ b/examples/mpi/fibonacci.c @@ -21,13 +21,6 @@ int main(int argc, const char *argv[]) BFDEV_DEFINE_MPI(vb, NULL); BFDEV_DEFINE_MPI(vc, NULL); - bfdev_mpi_seti(&va, 0); - bfdev_mpi_seti(&vb, 0); - vb.plus = 0; - - retval = bfdev_mpi_cmp(&va, &vb); - printf("%d\n", retval); - if ((retval = bfdev_mpi_seti(&va, 1)) || (retval = bfdev_mpi_seti(&vb, 0)) || (retval = bfdev_mpi_seti(&vc, 0))) From 1c43a2723e3238b991014c871ec4b78f8b092fe6 Mon Sep 17 00:00:00 2001 From: John Sanpe Date: Fri, 5 Apr 2024 12:02:14 +0800 Subject: [PATCH 23/31] feat mpi: use func test each other in fuzzy testsuite Signed-off-by: John Sanpe --- testsuite/mpi/fuzzy.c | 107 +++++++++++++++++------------------------- 1 file changed, 42 insertions(+), 65 deletions(-) diff --git a/testsuite/mpi/fuzzy.c b/testsuite/mpi/fuzzy.c index a1d1c3b4..22f4254b 100644 --- a/testsuite/mpi/fuzzy.c +++ b/testsuite/mpi/fuzzy.c @@ -4,6 +4,7 @@ */ #include +#include #include #include @@ -11,13 +12,16 @@ #define TEST_SIZE 512 static inline int -filling_random(bfdev_mpi_t *var, unsigned int length) +filling_random(bfdev_mpi_t *var) { BFDEV_MPI_TYPE *buff; + unsigned int length; size_t size, count; int retval; + length = ((unsigned int)rand() % TEST_SIZE) | 1; size = sizeof(*buff) * length; + buff = bfdev_malloc(NULL, size); if (bfdev_unlikely(!buff)) return -BFDEV_ENOMEM; @@ -25,67 +29,55 @@ filling_random(bfdev_mpi_t *var, unsigned int length) for (count = 0; count < size; ++count) ((char *)buff)[count] = rand(); - retval = bfdev_mpi_import(var, buff, length, buff[0] & 1); + retval = bfdev_mpi_import(var, buff, length, rand() & 1); bfdev_free(NULL, buff); return retval; } TESTSUITE( - "mpi:add", NULL, NULL, - "mpi add fuzzy test" + "mpi:addsub", NULL, NULL, + "mpi addsub fuzzy test" ) { unsigned int count; int retval; + BFDEV_DEFINE_MPI(result, NULL); BFDEV_DEFINE_MPI(va, NULL); BFDEV_DEFINE_MPI(vb, NULL); - if ((retval = filling_random(&va, TEST_SIZE)) || - (retval = filling_random(&vb, TEST_SIZE))) - goto failed; + srand(time(NULL)); + retval = -BFDEV_ENOERR; for (count = 0; count < TEST_LOOP; ++count) { - retval = bfdev_mpi_add(&va, &va, &vb); - if (retval) + if ((retval = filling_random(&va)) || + (retval = filling_random(&vb))) goto failed; - } - -failed: - bfdev_mpi_release(&va); - bfdev_mpi_release(&vb); - return retval; -} - -TESTSUITE( - "mpi:sub", NULL, NULL, - "mpi sub fuzzy test" -) { - unsigned int count; - int retval; - BFDEV_DEFINE_MPI(va, NULL); - BFDEV_DEFINE_MPI(vb, NULL); - - if ((retval = filling_random(&va, TEST_SIZE)) || - (retval = filling_random(&vb, TEST_SIZE))) - goto failed; + retval = bfdev_mpi_add(&result, &va, &vb); + if (retval) + goto failed; - for (count = 0; count < TEST_LOOP; ++count) { - retval = bfdev_mpi_sub(&va, &va, &vb); + retval = bfdev_mpi_sub(&result, &result, &vb); if (retval) goto failed; + + if (bfdev_mpi_cmp(&result, &va)) { + retval = -BFDEV_EFAULT; + goto failed; + } } failed: + bfdev_mpi_release(&result); bfdev_mpi_release(&va); bfdev_mpi_release(&vb); return retval; } TESTSUITE( - "mpi:mul", NULL, NULL, - "mpi mul fuzzy test" + "mpi:muldiv", NULL, NULL, + "mpi muldiv fuzzy test" ) { unsigned int count; int retval; @@ -94,46 +86,31 @@ TESTSUITE( BFDEV_DEFINE_MPI(va, NULL); BFDEV_DEFINE_MPI(vb, NULL); - if ((retval = filling_random(&va, TEST_SIZE)) || - (retval = filling_random(&vb, TEST_SIZE))) - goto failed; + srand(time(NULL)); + retval = -BFDEV_ENOERR; for (count = 0; count < TEST_LOOP; ++count) { - retval = bfdev_mpi_mul(&result, &va, &vb); - if (retval) + if ((retval = filling_random(&va)) || + (retval = filling_random(&vb))) goto failed; - } - -failed: - bfdev_mpi_release(&result); - bfdev_mpi_release(&va); - bfdev_mpi_release(&vb); - return retval; -} - -TESTSUITE( - "mpi:div", NULL, NULL, - "mpi div fuzzy test" -) { - unsigned int count; - int retval; - BFDEV_DEFINE_MPI(result, NULL); - BFDEV_DEFINE_MPI(va, NULL); - BFDEV_DEFINE_MPI(vb, NULL); - - if ((retval = filling_random(&va, TEST_SIZE)) || - (retval = filling_random(&vb, TEST_SIZE))) - goto failed; + /* Prevent division by zero */ + retval = bfdev_mpi_bseti(&vb, 0); + if (retval) + goto failed; - retval = bfdev_mpi_seti(&vb, 1); - if (retval) - goto failed; + retval = bfdev_mpi_mul(&result, &va, &vb); + if (retval) + goto failed; - for (count = 0; count < TEST_LOOP; ++count) { - retval = bfdev_mpi_div(&result, &result, &va, &vb); + retval = bfdev_mpi_div(&result, &result, &result, &vb); if (retval) goto failed; + + if (bfdev_mpi_cmp(&result, &va)) { + retval = -BFDEV_EFAULT; + goto failed; + } } failed: From d58a1bf4e0d0759ef30737cf8720dee3a5f4c43e Mon Sep 17 00:00:00 2001 From: John Sanpe Date: Sat, 6 Apr 2024 21:37:39 +0800 Subject: [PATCH 24/31] fixup bitmap: fixed issue in bit shift functions Signed-off-by: John Sanpe --- include/bfdev/bits.h | 3 +++ src/bitmap.c | 16 ++++++++-------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/include/bfdev/bits.h b/include/bfdev/bits.h index c1b1c475..1e11a18f 100644 --- a/include/bfdev/bits.h +++ b/include/bfdev/bits.h @@ -31,6 +31,9 @@ BFDEV_BEGIN_DECLS * BFDEV_BIT_LOW_MASK - create a low position mask. * @nbits: mask length. * + * The input &nbits is from 1 to BFDEV_BITS_PER_LONG, + * if it is not within this range, it will wrap back. + * * For example: * BFDEV_BIT_LOW_MASK(8) gives us the vector 0x000000ff. */ diff --git a/src/bitmap.c b/src/bitmap.c index 19298cdb..8cb0c39c 100644 --- a/src/bitmap.c +++ b/src/bitmap.c @@ -174,30 +174,30 @@ bfdev_bitmap_comp_shl(unsigned long *dest, const unsigned long *src, /* length > offset */ rem = BFDEV_BITS_MOD_LONG(shift); - index = length - offset - 1; + index = length - offset; if (BFDEV_BITS_MOD_LONG(bits)) { - vhigh = src[index] << rem; + vhigh = src[--index] << rem; if (rem && index) - vlow = src[--index] >> (BFDEV_BITS_PER_LONG - rem); + vlow = src[index - 1] >> (BFDEV_BITS_PER_LONG - rem); else vlow = 0; value = vhigh | vlow; - dest[--length] = value & BFDEV_BIT_LOW_MASK(bits); + dest[index + offset] = value & BFDEV_BIT_LOW_MASK(bits); } - while (length) { - vhigh = src[index] << rem; + while (index) { + vhigh = src[--index] << rem; if (rem && index) - vlow = src[--index] >> (BFDEV_BITS_PER_LONG - rem); + vlow = src[index - 1] >> (BFDEV_BITS_PER_LONG - rem); else vlow = 0; value = vhigh | vlow; - dest[--length] = value; + dest[index + offset] = value; } if (offset) From dfb248c0f8e195b89df31d1e0fea1523406f1fcf Mon Sep 17 00:00:00 2001 From: John Sanpe Date: Sat, 6 Apr 2024 22:11:43 +0800 Subject: [PATCH 25/31] fixup mpi: fixed issue in bit shift functions Signed-off-by: John Sanpe --- src/mpi.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/mpi.c b/src/mpi.c index 3481df79..57ae8c7a 100644 --- a/src/mpi.c +++ b/src/mpi.c @@ -420,18 +420,23 @@ mpa_divrem(BFDEV_MPI_TYPE *ptrs, * calculating unsigned mpi. */ -static __bfdev_always_inline void +static __bfdev_always_inline unsigned long mpi_relocation(bfdev_mpi_t *var) { BFDEV_MPI_TYPE *value; + unsigned long length; + length = 0; while (mpi_len(var)) { value = bfdev_array_peek(&var->value, 1); if (*value) break; bfdev_array_pop(&var->value, 1); + length++; } + + return length; } static inline int @@ -889,7 +894,7 @@ mpi_div(bfdev_mpi_t *quot, bfdev_mpi_t *rem, BFDEV_BUG_ON(mpi_resize(quot, length)); BFDEV_BUG_ON(mpi_resize(rem, cntb)); - mpi_relocation(quot); + BFDEV_BUG_ON(mpi_relocation(quot)); mpi_relocation(rem); if (rename) { @@ -1003,6 +1008,7 @@ mpi_or(bfdev_mpi_t *dest, length = cnta - cntb; mpa_copy(ptrs + cntb, ptra + cntb, length); + BFDEV_BUG_ON(mpi_relocation(dest)); return -BFDEV_ENOERR; } @@ -1051,7 +1057,7 @@ mpi_shli(bfdev_mpi_t *dest, const bfdev_mpi_t *va, BFDEV_MPI_TYPE shift) { BFDEV_MPI_TYPE *ptrs, *ptra; - unsigned long length, cnta; + unsigned long length, cnta, rem; int retval; /* parameter check */ @@ -1062,7 +1068,9 @@ mpi_shli(bfdev_mpi_t *dest, if (!cnta) return mpi_seti(dest, 0); - length = cnta + BFDEV_BITS_TO_LONG(shift); + rem = BFDEV_BITS_TO_LONG(shift); + length = cnta + rem; + retval = mpi_resize(dest, length); if (bfdev_unlikely(retval)) return retval; @@ -1073,6 +1081,7 @@ mpi_shli(bfdev_mpi_t *dest, mpa_copy(ptrs, ptra, cnta); } + mpa_zero(ptrs + cnta, rem); bfdev_bitmap_shl(ptrs, ptrs, shift, length * BFDEV_MPI_BITS); mpi_relocation(dest); From 2f951979bcd6ee9cd8b80c66d0cdabdd77471d3f Mon Sep 17 00:00:00 2001 From: John Sanpe Date: Sat, 6 Apr 2024 22:13:02 +0800 Subject: [PATCH 26/31] feat mpi: added shift fuzzy testsuites Signed-off-by: John Sanpe --- testsuite/mpi/fuzzy.c | 100 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 94 insertions(+), 6 deletions(-) diff --git a/testsuite/mpi/fuzzy.c b/testsuite/mpi/fuzzy.c index 22f4254b..d9a7ff97 100644 --- a/testsuite/mpi/fuzzy.c +++ b/testsuite/mpi/fuzzy.c @@ -12,11 +12,12 @@ #define TEST_SIZE 512 static inline int -filling_random(bfdev_mpi_t *var) +filling_random(bfdev_mpi_t *var, bool unsign) { BFDEV_MPI_TYPE *buff; unsigned int length; size_t size, count; + bool sign; int retval; length = ((unsigned int)rand() % TEST_SIZE) | 1; @@ -29,7 +30,8 @@ filling_random(bfdev_mpi_t *var) for (count = 0; count < size; ++count) ((char *)buff)[count] = rand(); - retval = bfdev_mpi_import(var, buff, length, rand() & 1); + sign = unsign ? true : rand() & 1; + retval = bfdev_mpi_import(var, buff, length, sign); bfdev_free(NULL, buff); return retval; @@ -50,8 +52,8 @@ TESTSUITE( retval = -BFDEV_ENOERR; for (count = 0; count < TEST_LOOP; ++count) { - if ((retval = filling_random(&va)) || - (retval = filling_random(&vb))) + if ((retval = filling_random(&va, false)) || + (retval = filling_random(&vb, false))) goto failed; retval = bfdev_mpi_add(&result, &va, &vb); @@ -90,8 +92,8 @@ TESTSUITE( retval = -BFDEV_ENOERR; for (count = 0; count < TEST_LOOP; ++count) { - if ((retval = filling_random(&va)) || - (retval = filling_random(&vb))) + if ((retval = filling_random(&va, false)) || + (retval = filling_random(&vb, false))) goto failed; /* Prevent division by zero */ @@ -119,3 +121,89 @@ TESTSUITE( bfdev_mpi_release(&vb); return retval; } + +TESTSUITE( + "mpi:bitmap", NULL, NULL, + "mpi bitmap fuzzy test" +) { + unsigned int count; + int retval; + + BFDEV_DEFINE_MPI(result, NULL); + BFDEV_DEFINE_MPI(va, NULL); + BFDEV_DEFINE_MPI(vb, NULL); + + srand(time(NULL)); + + retval = -BFDEV_ENOERR; + for (count = 0; count < TEST_LOOP; ++count) { + if ((retval = filling_random(&va, true)) || + (retval = filling_random(&vb, true))) + goto failed; + + retval = bfdev_mpi_or(&result, &va, &vb); + if (retval) + goto failed; + + retval = bfdev_mpi_and(&result, &result, &va); + if (retval) + goto failed; + + retval = bfdev_mpi_xor(&va, &va, &vb); + if (retval) + goto failed; + + retval = bfdev_mpi_xor(&vb, &vb, &va); + if (retval) + goto failed; + + if (bfdev_mpi_cmp(&result, &vb)) { + retval = -BFDEV_EFAULT; + goto failed; + } + } + +failed: + bfdev_mpi_release(&result); + bfdev_mpi_release(&va); + bfdev_mpi_release(&vb); + return retval; +} + +TESTSUITE( + "mpi:shift", NULL, NULL, + "mpi shift fuzzy test" +) { + unsigned int count, shift; + int retval; + + BFDEV_DEFINE_MPI(result, NULL); + BFDEV_DEFINE_MPI(va, NULL); + + srand(time(NULL)); + + retval = -BFDEV_ENOERR; + for (count = 0; count < TEST_LOOP; ++count) { + if ((retval = filling_random(&va, false))) + goto failed; + + shift = (unsigned int)rand() % TEST_SIZE; + retval = bfdev_mpi_shli(&result, &va, shift); + if (retval) + goto failed; + + retval = bfdev_mpi_shri(&result, &result, shift); + if (retval) + goto failed; + + if (bfdev_mpi_cmp(&result, &va)) { + retval = -BFDEV_EFAULT; + goto failed; + } + } + +failed: + bfdev_mpi_release(&result); + bfdev_mpi_release(&va); + return retval; +} From 3221bc55d27883b8e5cc061abe92ad57d8993add Mon Sep 17 00:00:00 2001 From: John Sanpe Date: Mon, 8 Apr 2024 13:04:05 +0800 Subject: [PATCH 27/31] feat port: porting glibc functions to the abstraction layer Signed-off-by: John Sanpe --- include/bfdev/bitmap.h | 10 ++--- include/bfdev/port/stdio.h | 32 +++++++++++++++ include/bfdev/port/stdlib.h | 45 +++++++++++++++++++++ include/bfdev/port/string.h | 81 +++++++++++++++++++++++++++++++++++++ include/port/allocator.h | 8 ++-- include/port/log.h | 8 ++-- src/argv.c | 12 +++--- src/bitmap.c | 8 ++-- src/bloom.c | 6 ++- src/btree.c | 10 ++--- src/cache/cache.c | 4 +- src/crypto/ascii85.c | 4 +- src/fifo.c | 4 +- src/levenshtein.c | 4 +- src/libc/strdup.c | 8 ++-- src/matrix.c | 4 +- src/minpool.c | 2 +- src/mpi.c | 4 +- src/ringbuf.c | 4 +- src/scnprintf.c | 2 +- src/skiplist.c | 2 +- src/sort.c | 6 +-- src/textsearch/bm.c | 2 +- src/textsearch/kmp.c | 2 +- src/textsearch/sunday.c | 2 +- 25 files changed, 217 insertions(+), 57 deletions(-) diff --git a/include/bfdev/bitmap.h b/include/bfdev/bitmap.h index b85152e7..51d6c125 100644 --- a/include/bfdev/bitmap.h +++ b/include/bfdev/bitmap.h @@ -205,7 +205,7 @@ bfdev_bitmap_set(unsigned long *bitmap, unsigned int start, unsigned int bits) offset = start / BFDEV_BITS_PER_BYTE; size = bits / BFDEV_BITS_PER_BYTE; - memset((char *)bitmap + offset, 0xff, size); + bfport_memset((char *)bitmap + offset, 0xff, size); } static __bfdev_always_inline void @@ -223,7 +223,7 @@ bfdev_bitmap_clr(unsigned long *bitmap, unsigned int start, unsigned int bits) offset = start / BFDEV_BITS_PER_BYTE; size = bits / BFDEV_BITS_PER_BYTE; - memset((char *)bitmap + offset, 0, size); + bfport_memset((char *)bitmap + offset, 0, size); } static __bfdev_always_inline void @@ -237,7 +237,7 @@ bfdev_bitmap_zero(unsigned long *bitmap, unsigned int bits) } length = BFDEV_BITS_TO_U8(bits); - memset(bitmap, 0, length); + bfport_memset(bitmap, 0, length); } static __bfdev_always_inline void @@ -251,7 +251,7 @@ bfdev_bitmap_fill(unsigned long *bitmap, unsigned int bits) } length = BFDEV_BITS_TO_U8(bits); - memset(bitmap, BFDEV_UINT8_MAX, length); + bfport_memset(bitmap, BFDEV_UINT8_MAX, length); } static __bfdev_always_inline void @@ -265,7 +265,7 @@ bfdev_bitmap_copy(unsigned long *dest, unsigned long *src, unsigned int bits) } length = BFDEV_BITS_TO_U8(bits); - memcpy(dest, src, length); + bfport_memcpy(dest, src, length); } BFDEV_END_DECLS diff --git a/include/bfdev/port/stdio.h b/include/bfdev/port/stdio.h index bdf2040e..46d530a7 100644 --- a/include/bfdev/port/stdio.h +++ b/include/bfdev/port/stdio.h @@ -16,6 +16,38 @@ BFDEV_BEGIN_DECLS +#ifndef bfport_file +# define bfport_file FILE +#endif + +#ifndef bfport_stdout +# define bfport_stdout stdout +#endif + +#ifndef bfport_stderr +# define bfport_stderr stderr +#endif + +#ifndef bfport_fwrite +# define bfport_fwrite bfport_fwrite +static __bfdev_always_inline unsigned long +bfport_fwrite(const void *restrict ptr, size_t size, + size_t n, FILE *restrict stream) +{ + return fwrite(ptr, size, n, stream); +} +#endif + +#ifndef bfport_vsnprintf +# define bfport_vsnprintf bfport_vsnprintf +static __bfdev_always_inline int +bfport_vsnprintf(char *restrict s, size_t maxlen, + const char *restrict format, va_list arg) +{ + return vsnprintf(s, maxlen, format, arg); +} +#endif + BFDEV_END_DECLS #endif /* _BFDEV_PORT_STDIO_H_ */ diff --git a/include/bfdev/port/stdlib.h b/include/bfdev/port/stdlib.h index 755a2b09..5b14ed9f 100644 --- a/include/bfdev/port/stdlib.h +++ b/include/bfdev/port/stdlib.h @@ -16,6 +16,51 @@ BFDEV_BEGIN_DECLS +#ifndef bfport_rand +# define bfport_rand bfport_rand +static __bfdev_always_inline int +bfport_rand() +{ + return rand(); +} +#endif + +#ifndef bfport_malloc +# define bfport_malloc bfport_malloc +static __bfdev_always_inline __bfdev_malloc void * +bfport_malloc(size_t size) +{ + return malloc(size); +} +#endif + +#ifndef bfport_calloc +# define bfport_calloc bfport_calloc +static __bfdev_always_inline __bfdev_malloc void * +bfport_calloc(size_t nmemb, size_t size) +{ + return calloc(nmemb, size); +} +#endif + +#ifndef bfport_realloc +# define bfport_realloc bfport_realloc +static __bfdev_always_inline __bfdev_malloc void * +bfport_realloc(void *ptr, size_t size) +{ + return realloc(ptr, size); +} +#endif + +#ifndef bfport_free +# define bfport_free bfport_free +static __bfdev_always_inline void +bfport_free(void *ptr) +{ + free(ptr); +} +#endif + BFDEV_END_DECLS #endif /* _BFDEV_PORT_STDLIB_H_ */ diff --git a/include/bfdev/port/string.h b/include/bfdev/port/string.h index 0b43ce68..5dd4af79 100644 --- a/include/bfdev/port/string.h +++ b/include/bfdev/port/string.h @@ -16,6 +16,87 @@ BFDEV_BEGIN_DECLS +#ifndef bfport_memcpy +# define bfport_memcpy bfport_memcpy +static __bfdev_always_inline void * +bfport_memcpy(void *restrict dest, const void *restrict src, size_t n) +{ + return memcpy(dest, src, n); +} +#endif + +#ifndef bfport_memset +# define bfport_memset bfport_memset +static __bfdev_always_inline void * +bfport_memset(void *s, int c, size_t n) +{ + return memset(s, c, n); +} +#endif + +#ifndef bfport_strchr +# define bfport_strchr bfport_strchr +static __bfdev_always_inline char * +bfport_strchr(const char *s, int c) +{ + return strchr(s, c); +} +#endif + +#ifndef bfport_strspn +# define bfport_strspn bfport_strspn +static __bfdev_always_inline size_t +bfport_strspn(const char *s, const char *accept) +{ + return strspn(s, accept); +} +#endif + +#ifndef bfport_strcspn +# define bfport_strcspn bfport_strcspn +static __bfdev_always_inline size_t +bfport_strcspn(const char *s, const char *reject) +{ + return strcspn(s, reject); +} +#endif + +#ifndef bfport_strcpy +# define bfport_strcpy bfport_strcpy +static __bfdev_always_inline char * +bfport_strcpy(char *restrict dest, const char *restrict src) +{ + return strcpy(dest, src); +} +#endif + +#ifndef bfport_strncpy +# define bfport_strncpy bfport_strncpy +static __bfdev_always_inline char * +bfport_strncpy(char *restrict dest, const char *restrict src, size_t n) +{ + return strncpy(dest, src, n); +} +#endif + +#ifndef bfport_strlen +# define bfport_strlen bfport_strlen +static __bfdev_always_inline size_t +bfport_strlen(const char *s) +{ + return strlen(s); +} +#endif + +#ifndef bfport_strnlen +# define bfport_strnlen bfport_strnlen +static __bfdev_always_inline size_t +bfport_strnlen(const char *s, size_t len) +{ + return strnlen(s, len); +} +#endif + BFDEV_END_DECLS #endif /* _BFDEV_PORT_STRING_H_ */ diff --git a/include/port/allocator.h b/include/port/allocator.h index cce3a01e..4dd16841 100644 --- a/include/port/allocator.h +++ b/include/port/allocator.h @@ -23,7 +23,7 @@ generic_alloc(size_t size, void *pdata) return retval; } - return malloc(size); + return bfport_malloc(size); } static __bfdev_always_inline void * @@ -36,7 +36,7 @@ generic_zalloc(size_t size, void *pdata) return retval; } - return calloc(1, size); + return bfport_calloc(1, size); } static __bfdev_always_inline void * @@ -49,7 +49,7 @@ generic_realloc(void *block, size_t resize, void *pdata) return retval; } - return realloc(block, resize); + return bfport_realloc(block, resize); } static __bfdev_always_inline void @@ -60,7 +60,7 @@ generic_free(void *block, void *pdata) return; } - free((void *)block); + bfport_free((void *)block); } #endif /* _LOCAL_PORT_ALLOCATOR_H_ */ diff --git a/include/port/log.h b/include/port/log.h index 630c94fa..6ec0c74b 100644 --- a/include/port/log.h +++ b/include/port/log.h @@ -16,14 +16,14 @@ static inline void generic_log_write(bfdev_log_message_t *msg) { - FILE *file; + bfport_file *file; if (msg->level > BFDEV_LEVEL_WARNING) - file = stdout; + file = bfport_stdout; else - file = stderr; + file = bfport_stderr; - fwrite(msg->data, msg->length, 1, file); + bfport_fwrite(msg->data, msg->length, 1, file); } #endif /* _LOCAL_PORT_LOG_H_ */ diff --git a/src/argv.c b/src/argv.c index 01763745..bfceaa54 100644 --- a/src/argv.c +++ b/src/argv.c @@ -17,13 +17,13 @@ bfdev_argv_count(const char *args) argc = 0; for (;;) { - offset = strspn(args, ARGV_SEPARA); + offset = bfport_strspn(args, ARGV_SEPARA); if (!args[offset]) break; args += offset; argc++; - offset = strcspn(args, ARGV_SEPARA); + offset = bfport_strcspn(args, ARGV_SEPARA); if (!args[offset]) break; args += offset; @@ -42,17 +42,17 @@ bfdev_argv_split(const bfdev_alloc_t *alloc, const char *args, argc = bfdev_argv_count(args); count = (argc + 1) * sizeof(*argv); - argv = bfdev_malloc(alloc, count + strlen(args) + 1); + argv = bfdev_malloc(alloc, count + bfport_strlen(args) + 1); if (bfdev_unlikely(!argv)) return NULL; block = (void *)argv + count; - strcpy(block, args); + bfport_strcpy(block, args); for (count = 0; count < argc; ++count) { - block += strspn(block, ARGV_SEPARA); + block += bfport_strspn(block, ARGV_SEPARA); argv[count] = block; - block += strcspn(block, ARGV_SEPARA); + block += bfport_strcspn(block, ARGV_SEPARA); *block++ = '\0'; } diff --git a/src/bitmap.c b/src/bitmap.c index 8cb0c39c..e853143e 100644 --- a/src/bitmap.c +++ b/src/bitmap.c @@ -168,7 +168,7 @@ bfdev_bitmap_comp_shl(unsigned long *dest, const unsigned long *src, offset = BFDEV_BITS_DIV_LONG(shift); if (length <= offset) { - memset(dest, 0, length * sizeof(*dest)); + bfport_memset(dest, 0, length * sizeof(*dest)); return; } @@ -201,7 +201,7 @@ bfdev_bitmap_comp_shl(unsigned long *dest, const unsigned long *src, } if (offset) - memset(dest, 0, offset * sizeof(*dest)); + bfport_memset(dest, 0, offset * sizeof(*dest)); } export void @@ -215,7 +215,7 @@ bfdev_bitmap_comp_shr(unsigned long *dest, const unsigned long *src, offset = BFDEV_BITS_DIV_LONG(shift); if (length <= offset) { - memset(dest, 0, length * sizeof(*dest)); + bfport_memset(dest, 0, length * sizeof(*dest)); return; } @@ -248,7 +248,7 @@ bfdev_bitmap_comp_shr(unsigned long *dest, const unsigned long *src, } if (offset) - memset(dest + length - offset, 0, offset * sizeof(*dest)); + bfport_memset(dest + length - offset, 0, offset * sizeof(*dest)); } export void diff --git a/src/bloom.c b/src/bloom.c index 3f7bc14c..1bf541d5 100644 --- a/src/bloom.c +++ b/src/bloom.c @@ -55,8 +55,10 @@ bfdev_bloom_push(bfdev_bloom_t *bloom, void *key) export void bfdev_bloom_flush(bfdev_bloom_t *bloom) { - size_t size = BFDEV_BITS_WORD(bloom->capacity); - memset(bloom->bitmap, 0, size); + size_t size; + + size = BFDEV_BITS_WORD(bloom->capacity); + bfport_memset(bloom->bitmap, 0, size); } export bfdev_bloom_t * diff --git a/src/btree.c b/src/btree.c index 32ba524b..cad71bbc 100644 --- a/src/btree.c +++ b/src/btree.c @@ -58,7 +58,7 @@ bnode_set_key(bfdev_btree_root_t *root, bfdev_btree_node_t *node, size = layout->keylen * sizeof(uintptr_t); slot = bnode_get_key(root, node, index); - memcpy(slot, key, size); + bfport_memcpy(slot, key, size); } static inline long @@ -86,7 +86,7 @@ bnode_takeout_key(bfdev_btree_root_t *root, bfdev_btree_node_t *node, size = layout->keylen * sizeof(uintptr_t); slot = bnode_get_key(root, node, index); - memcpy(key, slot, size); + bfport_memcpy(key, slot, size); } static inline void @@ -102,7 +102,7 @@ bnode_clear_index(bfdev_btree_root_t *root, bfdev_btree_node_t *node, bnode_set_value(root, node, index, NULL); slot = bnode_get_key(root, node, index); - memset(slot, 0, size); + bfport_memset(slot, 0, size); } static inline bool @@ -146,7 +146,7 @@ bnode_alloc(bfdev_btree_root_t *root) node = ops->alloc(root); if (bfdev_likely(node)) - memset(node, 0, layout->nodesize); + bfport_memset(node, 0, layout->nodesize); return node; } @@ -582,7 +582,7 @@ bfdev_btree_key_copy(bfdev_btree_root_t *root, uintptr_t *dest, uintptr_t *src) bfdev_btree_layout_t *layout; layout = root->layout; - memcpy(dest, src, layout->keylen * sizeof(uintptr_t)); + bfport_memcpy(dest, src, layout->keylen * sizeof(uintptr_t)); } export void * diff --git a/src/cache/cache.c b/src/cache/cache.c index f7e649c6..f9d19ae3 100644 --- a/src/cache/cache.c +++ b/src/cache/cache.c @@ -248,11 +248,11 @@ bfdev_cache_reset(bfdev_cache_head_t *head) bfdev_list_head_init(&head->changing); head->algo->reset(head); - memset(head->taghash, 0, sizeof(*head->taghash) * head->size); + bfport_memset(head->taghash, 0, sizeof(*head->taghash) * head->size); for (count = 0; count < head->size; ++count) { node = head->nodes[count]; - memset(node, 0, sizeof(*node)); + bfport_memset(node, 0, sizeof(*node)); node->index = count; node->tag = BFDEV_CACHE_FREE_TAG; diff --git a/src/crypto/ascii85.c b/src/crypto/ascii85.c index 6f7e5da0..a4f5a6c7 100644 --- a/src/crypto/ascii85.c +++ b/src/crypto/ascii85.c @@ -58,7 +58,7 @@ ascii85_decode(void *buff, const char *data, size_t size) while (size) { if (*data == 'z' && size >= 1) { - memset(buff, 0, 4); + bfport_memset(buff, 0, 4); data += 1; size -= 1; } else if (size >= 5) { @@ -104,7 +104,7 @@ ascii85_encode_length(const uint32_t *data, size_t size) static __bfdev_always_inline size_t ascii85_decode_length(const char *data, size_t size) { - while ((data = strchr(data, 'z'))) { + while ((data = bfport_strchr(data, 'z'))) { size += 4; data++; } diff --git a/src/fifo.c b/src/fifo.c index 8d8e1b6e..cf5326db 100644 --- a/src/fifo.c +++ b/src/fifo.c @@ -23,8 +23,8 @@ } \ \ llen = bfdev_min(len, size - offset); \ - memcpy(copy1, copy2, llen); \ - memcpy(fold1, fold2, len - llen); \ + bfport_memcpy(copy1, copy2, llen); \ + bfport_memcpy(fold1, fold2, len - llen); \ } while (0) static __bfdev_always_inline void diff --git a/src/levenshtein.c b/src/levenshtein.c index e57bba80..ad5ec68d 100644 --- a/src/levenshtein.c +++ b/src/levenshtein.c @@ -74,8 +74,8 @@ bfdev_levenshtein(const bfdev_alloc_t *alloc, { size_t len1, len2; - len1 = strlen(str1); - len2 = strlen(str2); + len1 = bfport_strlen(str1); + len2 = bfport_strlen(str2); return bfdev_levenshtein_len(alloc, str1, str2, len1, len2, s, w, a, d); } diff --git a/src/libc/strdup.c b/src/libc/strdup.c index 4ae7d157..500894c6 100644 --- a/src/libc/strdup.c +++ b/src/libc/strdup.c @@ -17,11 +17,11 @@ bfdev_strdup(const bfdev_alloc_t *alloc, if (bfdev_unlikely(!string)) return NULL; - length = strlen(string); + length = bfport_strlen(string); dump = bfdev_malloc(alloc, length + 1); if (bfdev_likely(dump)) - strcpy(dump, string); + bfport_strcpy(dump, string); return dump; } @@ -36,11 +36,11 @@ bfdev_strndup(const bfdev_alloc_t *alloc, if (bfdev_unlikely(!string)) return NULL; - length = strnlen(string, len); + length = bfport_strnlen(string, len); dump = bfdev_malloc(alloc, length + 1); if (bfdev_likely(dump)) - strncpy(dump, string, len); + bfport_strncpy(dump, string, len); return dump; } diff --git a/src/matrix.c b/src/matrix.c index ca4f189c..eefd05cd 100644 --- a/src/matrix.c +++ b/src/matrix.c @@ -10,14 +10,14 @@ static inline void matrix_zero(BFDEV_MATRIX_TYPE *var, unsigned int size) { - memset(var, 0, size * BFDEV_MATRIX_SIZE); + bfport_memset(var, 0, size * BFDEV_MATRIX_SIZE); } static inline void matrix_copy(BFDEV_MATRIX_TYPE *dest, const BFDEV_MATRIX_TYPE *src, unsigned int size) { - memcpy(dest, src, size * BFDEV_MATRIX_SIZE); + bfport_memcpy(dest, src, size * BFDEV_MATRIX_SIZE); } #define GENERIC_MATRIX_ADDSUB(name, operate) \ diff --git a/src/minpool.c b/src/minpool.c index 30b40627..2f6f4bfc 100644 --- a/src/minpool.c +++ b/src/minpool.c @@ -229,7 +229,7 @@ bfdev_minpool_realloc(struct bfdev_minpool_head *head, void *block, size_t resiz if (bfdev_unlikely(!newblk)) return NULL; - memcpy(newblk, block, origin); + bfport_memcpy(newblk, block, origin); bfdev_minpool_free(head, block); return newblk; diff --git a/src/mpi.c b/src/mpi.c index 57ae8c7a..61895b45 100644 --- a/src/mpi.c +++ b/src/mpi.c @@ -30,14 +30,14 @@ BFDEV_MPI_TYPE mpi_zero; static inline void mpa_zero(BFDEV_MPI_TYPE *dest, unsigned long length) { - memset(dest, 0, length * BFDEV_MPI_SIZE); + bfport_memset(dest, 0, length * BFDEV_MPI_SIZE); } static inline void mpa_copy(BFDEV_MPI_TYPE *dest, const BFDEV_MPI_TYPE *src, unsigned long length) { - memcpy(dest, src, length * BFDEV_MPI_SIZE); + bfport_memcpy(dest, src, length * BFDEV_MPI_SIZE); } static inline int diff --git a/src/ringbuf.c b/src/ringbuf.c index 8cae1183..68b9cdf9 100644 --- a/src/ringbuf.c +++ b/src/ringbuf.c @@ -23,8 +23,8 @@ } \ \ llen = bfdev_min(len, size - offset); \ - memcpy(copy1, copy2, llen); \ - memcpy(fold1, fold2, len - llen); \ + bfport_memcpy(copy1, copy2, llen); \ + bfport_memcpy(fold1, fold2, len - llen); \ } while (0) static __bfdev_always_inline void diff --git a/src/scnprintf.c b/src/scnprintf.c index 32947fde..a6334f95 100644 --- a/src/scnprintf.c +++ b/src/scnprintf.c @@ -12,7 +12,7 @@ bfdev_vscnprintf(char *buf, size_t size, const char *fmt, va_list args) { int len; - len = vsnprintf(buf, size, fmt, args); + len = bfport_vsnprintf(buf, size, fmt, args); if (bfdev_likely(len < size)) return len; diff --git a/src/skiplist.c b/src/skiplist.c index 842be087..8cad0a30 100644 --- a/src/skiplist.c +++ b/src/skiplist.c @@ -14,7 +14,7 @@ random_level(bfdev_skip_head_t *head) level = 1; while (level < head->levels) { - if (rand() > RAND_MAX >> 2) + if (bfport_rand() > RAND_MAX >> 2) break; level++; } diff --git a/src/sort.c b/src/sort.c index 9619a54c..1db6c1e3 100644 --- a/src/sort.c +++ b/src/sort.c @@ -15,9 +15,9 @@ sort_swap(size_t cells, void *cel1, void *cel2) /* alloca hates inline */ buff = bfdev_alloca(cells); - memcpy(buff, cel1, cells); - memcpy(cel1, cel2, cells); - memcpy(cel2, buff, cells); + bfport_memcpy(buff, cel1, cells); + bfport_memcpy(cel1, cel2, cells); + bfport_memcpy(cel2, buff, cells); } static __bfdev_attribute_const __bfdev_always_inline size_t diff --git a/src/textsearch/bm.c b/src/textsearch/bm.c index 6041fa4a..4991cb66 100644 --- a/src/textsearch/bm.c +++ b/src/textsearch/bm.c @@ -128,7 +128,7 @@ bm_prepare(const bfdev_alloc_t *alloc, const void *pattern, bctx->pattern = (void *)bctx + sizeof(*bctx) + gsize; if (!(flags & BFDEV_TS_IGCASE)) - memcpy(bctx->pattern, pattern, len); + bfport_memcpy(bctx->pattern, pattern, len); else for (index = 0; index < len; ++index) bctx->pattern[index] = toupper(((char *)pattern)[index]); bm_compute_prefix(bctx, flags); diff --git a/src/textsearch/kmp.c b/src/textsearch/kmp.c index a31e1d87..c34d8d94 100644 --- a/src/textsearch/kmp.c +++ b/src/textsearch/kmp.c @@ -97,7 +97,7 @@ kmp_prepare(const bfdev_alloc_t *alloc, const void *pattern, kctx->pattern = (void *)kctx + sizeof(*kctx) + prefix_size; if (!(flags & BFDEV_TS_IGCASE)) - memcpy(kctx->pattern, pattern, len); + bfport_memcpy(kctx->pattern, pattern, len); else for (index = 0; index < len; ++index) kctx->pattern[index] = toupper(((char *)pattern)[index]); kmp_compute_prefix(kctx); diff --git a/src/textsearch/sunday.c b/src/textsearch/sunday.c index ed40f179..f3d63d70 100644 --- a/src/textsearch/sunday.c +++ b/src/textsearch/sunday.c @@ -98,7 +98,7 @@ sunday_prepare(const bfdev_alloc_t *alloc, const void *pattern, sctx->pattern_len = len; if (!(flags & BFDEV_TS_IGCASE)) - memcpy(sctx->pattern, pattern, len); + bfport_memcpy(sctx->pattern, pattern, len); else for (index = 0; index < len; ++index) sctx->pattern[index] = toupper(((char *)pattern)[index]); sunday_compute_prefix(sctx, flags); From 2c08c2067d135c5f5c9c8f7ebbb4e94783e1a95d Mon Sep 17 00:00:00 2001 From: John Sanpe Date: Tue, 9 Apr 2024 23:33:49 +0800 Subject: [PATCH 28/31] docs readme: added OpenSSF badge status Signed-off-by: John Sanpe --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 8012fe0c..f2ef79fa 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # BFDEV Introduce +[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/8769/badge)](https://www.bestpractices.dev/projects/8769) + bfdev is a high-performance, aesthetically pleasing, and portable infrastructure provisioning library. Its goal is to provide a comprehensive and streamlined development environment. ![logo](docs/images/logo.png) From e8b30fd96af577e6aa0a49358db188e30acf2192 Mon Sep 17 00:00:00 2001 From: John Sanpe Date: Wed, 10 Apr 2024 20:52:13 +0800 Subject: [PATCH 29/31] fixup bfdev: fixed series of style issues Signed-off-by: John Sanpe --- include/bfdev/container.h | 2 +- include/bfdev/hash.h | 2 +- include/bfdev/math.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/bfdev/container.h b/include/bfdev/container.h index ba9ea8dc..f113277e 100644 --- a/include/bfdev/container.h +++ b/include/bfdev/container.h @@ -21,7 +21,7 @@ BFDEV_BEGIN_DECLS /* Any const qualifier of @ptr is lost. */ #define bfdev_container_of(ptr, type, member) ({ \ const typeof(((type *)0)->member) *__mptr = (ptr); \ - (type *)((char *)__mptr - offsetof(type,member)); \ + (type *)((char *)__mptr - offsetof(type, member)); \ }) /* If ptr is NULL, ptr is returned unchanged. */ diff --git a/include/bfdev/hash.h b/include/bfdev/hash.h index 20addf19..34743efa 100644 --- a/include/bfdev/hash.h +++ b/include/bfdev/hash.h @@ -44,7 +44,7 @@ uint64_t bfdev_hashv64_generic(uint64_t value) } /** - * bfdev_hashv{32/64}() - Fast hashing routine for ints. + * bfdev_hash{32/64}() - Fast hashing routine for ints. * @value: value to hash. * @bits: bit number of result. */ diff --git a/include/bfdev/math.h b/include/bfdev/math.h index 4f420f9c..e6efcf8a 100644 --- a/include/bfdev/math.h +++ b/include/bfdev/math.h @@ -56,8 +56,8 @@ BFDEV_BEGIN_DECLS #define BFDEV_DIV_ROUND_CLOSEST(x, divisor) ({ \ typeof(x) __x = x; \ typeof(divisor) __d = divisor; \ - (((typeof(x)) -1) > 0 || \ - ((typeof(divisor)) -1) > 0 || \ + (bfdev_is_unsigned(x) || \ + bfdev_is_unsigned(divisor) || \ (((__x) > 0) == ((__d) > 0))) \ ? (((__x) + ((__d) / 2)) / (__d)) \ : (((__x) - ((__d) / 2)) / (__d)); \ From 0a9481f6dc685cda3bc99fd30c17acd216c14da8 Mon Sep 17 00:00:00 2001 From: John Sanpe Date: Sun, 14 Apr 2024 15:57:05 +0800 Subject: [PATCH 30/31] feat port: added strcmp function port Signed-off-by: John Sanpe --- include/bfdev/port/string.h | 9 +++++++++ src/cache/cache.c | 2 +- src/textsearch/textsearch.c | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/include/bfdev/port/string.h b/include/bfdev/port/string.h index 5dd4af79..83389d43 100644 --- a/include/bfdev/port/string.h +++ b/include/bfdev/port/string.h @@ -34,6 +34,15 @@ bfport_memset(void *s, int c, size_t n) } #endif +#ifndef bfport_strcmp +# define bfport_strcmp bfport_strcmp +static __bfdev_always_inline int +bfport_strcmp(const char *s1, const char *s2) +{ + return strcmp(s1, s2); +} +#endif + #ifndef bfport_strchr # define bfport_strchr bfport_strchr static __bfdev_always_inline char * diff --git a/src/cache/cache.c b/src/cache/cache.c index f9d19ae3..89ddc4c7 100644 --- a/src/cache/cache.c +++ b/src/cache/cache.c @@ -17,7 +17,7 @@ cache_algorithm_find(const char *name) bfdev_cache_algo_t *algo; bfdev_list_for_each_entry(algo, &cache_algorithms, list) { - if (!strcmp(algo->name, name)) + if (!bfport_strcmp(algo->name, name)) return algo; } diff --git a/src/textsearch/textsearch.c b/src/textsearch/textsearch.c index 9a94ec07..7823f8e0 100644 --- a/src/textsearch/textsearch.c +++ b/src/textsearch/textsearch.c @@ -15,7 +15,7 @@ textsearch_algorithm_find(const char *name) bfdev_ts_algorithm_t *algo; bfdev_list_for_each_entry(algo, &textsearch_algorithms, list) { - if (!strcmp(algo->name, name)) + if (!bfport_strcmp(algo->name, name)) return algo; } From bf2e5e2ed22512d99958dcc7035ed0c62a36bbbe Mon Sep 17 00:00:00 2001 From: John Sanpe Date: Sun, 14 Apr 2024 15:36:28 +0800 Subject: [PATCH 31/31] feat bfdev: update version Signed-off-by: John Sanpe --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a146bcc2..b692f9b1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ # cmake_minimum_required(VERSION 3.12) -project(bfdev VERSION 1.0.2 LANGUAGES C) +project(bfdev VERSION 1.0.3 LANGUAGES C) include(GNUInstallDirs) include(CheckIncludeFiles)