diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..cd4973a9 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,7 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 0 diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 6d5f178b..2dd70270 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -10,30 +10,38 @@ on: jobs: analyze: - name: Analyze - runs-on: ubuntu-latest + name: Analyze on ${{matrix.os}} + runs-on: ${{matrix.os}} permissions: actions: read contents: read security-events: write + strategy: fail-fast: false matrix: + os: [ubuntu-20.04] language: [ 'cpp' ] steps: - name: checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: install dependencies run: | sudo apt update sudo apt install cmake make clang + - name: initialize codeql uses: github/codeql-action/init@v2 with: - languages: ${{ matrix.language }} + languages: ${{matrix.language}} + - name: autobuild uses: github/codeql-action/autobuild@v2 + - name: perform analysis uses: github/codeql-action/analyze@v2 with: diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index a4407dcd..1bc794c6 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -13,30 +13,41 @@ env: jobs: build: - name: Test on ${{ matrix.os }} - runs-on: ${{ matrix.os }} + name: Test on ${{matrix.os}} + runs-on: ${{matrix.os}} strategy: matrix: os: [macos-latest] steps: - name: checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: install dependencies run: | brew update brew install cmake make ccache + - 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/local/opt/ccache/libexec/clang \ - -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/local/opt/ccache/libexec/clang \ + -D BFDEV_DEVEL=ON + - name: make - run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} + run: | + cmake --build ${{github.workspace}}/build \ + --config ${{env.BUILD_TYPE}} + - name: install - run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -- install + run: | + cmake --build ${{github.workspace}}/build \ + --config ${{env.BUILD_TYPE}} -- install + - name: ctest working-directory: ${{github.workspace}}/build run: ctest -C ${{env.BUILD_TYPE}} -V diff --git a/.github/workflows/ubuntu-clang.yml b/.github/workflows/ubuntu-clang.yml index 28fa94d1..9842a3d3 100644 --- a/.github/workflows/ubuntu-clang.yml +++ b/.github/workflows/ubuntu-clang.yml @@ -13,31 +13,42 @@ env: jobs: build: - name: Test on ${{ matrix.os }} - runs-on: ${{ matrix.os }} + name: Test on ${{matrix.os}} + runs-on: ${{matrix.os}} strategy: matrix: - os: [ubuntu-latest] + os: [ubuntu-20.04] steps: - name: checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: install dependencies run: | sudo apt update sudo apt install cmake make clang ccache + - 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/clang \ - -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/clang \ + -D BFDEV_DEVEL=ON + - name: make - run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} + run: | + cmake --build ${{github.workspace}}/build \ + --config ${{env.BUILD_TYPE}} + - name: install working-directory: ${{github.workspace}}/build - run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -- install + run: | + cmake --build ${{github.workspace}}/build \ + --config ${{env.BUILD_TYPE}} -- install + - name: ctest working-directory: ${{github.workspace}}/build run: ctest -C ${{env.BUILD_TYPE}} -V diff --git a/.github/workflows/ubuntu-gcc.yml b/.github/workflows/ubuntu-gcc.yml index 19204721..589ca0dd 100644 --- a/.github/workflows/ubuntu-gcc.yml +++ b/.github/workflows/ubuntu-gcc.yml @@ -13,19 +13,23 @@ env: jobs: build: - name: Test on ${{ matrix.os }} - runs-on: ${{ matrix.os }} + name: Test on ${{matrix.os}} + runs-on: ${{matrix.os}} strategy: matrix: - os: [ubuntu-latest] + os: [ubuntu-20.04] steps: - name: checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: install dependencies run: | sudo apt update sudo apt install cmake make gcc ccache + - name: configure cmake run: | cmake -B ${{github.workspace}}/build \ @@ -33,11 +37,18 @@ jobs: -D CMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \ -D CMAKE_C_COMPILER=/usr/lib/ccache/gcc \ -D BFDEV_DEVEL=ON + - name: make - run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} + run: | + cmake --build ${{github.workspace}}/build \ + --config ${{env.BUILD_TYPE}} + - name: install working-directory: ${{github.workspace}}/build - run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -- install + run: | + cmake --build ${{github.workspace}}/build \ + --config ${{env.BUILD_TYPE}} -- install + - name: ctest working-directory: ${{github.workspace}}/build run: ctest -C ${{env.BUILD_TYPE}} -V diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 953ba450..6387b39e 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -13,34 +13,42 @@ env: jobs: build: - name: Test on ${{ matrix.os }} - runs-on: ${{ matrix.os }} + name: Test on ${{matrix.os}} + runs-on: ${{matrix.os}} strategy: matrix: os: [windows-latest] + defaults: run: shell: msys2 {0} steps: - name: checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: install dependencies uses: msys2/setup-msys2@v2 with: msystem: UCRT64 update: true install: cmake make gcc + - name: configure cmake run: | cmake -B build \ -D CMAKE_INSTALL_PREFIX=build/install \ -D CMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} \ -D BFDEV_EXAMPLES=ON + - name: make run: cmake --build build --config ${{env.BUILD_TYPE}} + - name: install run: cmake --build build --config ${{env.BUILD_TYPE}} -- install + - name: ctest working-directory: ${{github.workspace}}/build run: ctest -C ${{env.BUILD_TYPE}} -V diff --git a/CMakeLists.txt b/CMakeLists.txt index 63ea509b..85ca406f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,21 +5,21 @@ # cmake_minimum_required(VERSION 3.12) -project(bfdev VERSION 1.0.1 LANGUAGES C) +project(bfdev VERSION 1.0.2 LANGUAGES C) include(GNUInstallDirs) include(CheckIncludeFiles) -set(BFDEV_ARCH dummy) set(BFDEV_NAME sirius) - -set(BFDEV_EXTREVERSION -devel) set(BFDEV_VERSION ${PROJECT_VERSION}) +set(BFDEV_EXTREVERSION -stable) if(BFDEV_EXTREVERSION) string(APPEND BFDEV_VERSION ${BFDEV_EXTREVERSION}) endif() +set(BFDEV_ARCH generic) + set(BFDEV_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) set(BFDEV_HEADER_PATH ${PROJECT_SOURCE_DIR}/include) set(BFDEV_SOURCE_PATH ${PROJECT_SOURCE_DIR}/src) @@ -30,7 +30,6 @@ set(BFDEV_ARCH_PATH ${PROJECT_SOURCE_DIR}/arch/${BFDEV_ARCH}) set(BFDEV_ARCH_HEADER_PATH ${BFDEV_ARCH_PATH}/include) set(BFDEV_CONFIGURE ${BFDEV_GENERATED_PATH}/bfdev-config.cmake) -include(scripts/asm-generic.cmake) include(scripts/hostrule.cmake) include(scripts/packed-header.cmake) include(scripts/packed-source.cmake) @@ -42,8 +41,10 @@ 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_ASAN "Enable Address Sanitizer" OFF) option(BFDEV_UBSAN "Enable Undefined Behaviour Sanitizer" OFF) +option(BFDEV_GCOV "Enable Code Coverage Test" OFF) option(BFDEV_DEBUG_LIST "Dynamic debug list" ON) option(BFDEV_DEBUG_SLIST "Dynamic debug slist" ON) @@ -58,98 +59,24 @@ if(BFDEV_DEVEL) set(BFDEV_EXAMPLES ON) set(BFDEV_ASAN ON) set(BFDEV_UBSAN ON) + set(BFDEV_GCOV ON) endif() -asm_generic( - bfdev/asm-generic/ - ${BFDEV_GENERATED_PATH}/bfdev/asm - ${BFDEV_ARCH_HEADER_PATH}/bfdev/asm - ${BFDEV_HEADER_PATH}/bfdev/asm-generic -) - -configure_file( - ${BFDEV_MODULE_PATH}/config.h.in - ${BFDEV_GENERATED_PATH}/bfdev/config.h -) - -configure_file( - ${BFDEV_MODULE_PATH}/bfdev-config.cmake.in - ${BFDEV_CONFIGURE} -) - -add_compile_options( - -std=gnu11 - -Wall - -Wextra - -Wno-override-init - -Wno-unused-parameter - -Wno-sign-compare - -Wno-pointer-sign - -Wno-null-pointer-arithmetic - -Wmissing-prototypes - -Wmissing-declarations - -fvisibility=hidden -) - -if(BFDEV_STRICT) - set(CMAKE_C_FLAGS - "${CMAKE_C_FLAGS} \ - -Werror" - ) -endif() - -if(BFDEV_ASAN) - set(CMAKE_C_FLAGS - "${CMAKE_C_FLAGS} \ - -fsanitize=address \ - -fsanitize=undefined \ - -fsanitize-recover=all \ - -fno-omit-frame-pointer \ - -fno-stack-protector" - ) - if(NOT APPLE) - set(CMAKE_C_FLAGS - "${CMAKE_C_FLAGS} \ - -fsanitize=leak" - ) - endif() -endif() - -if(BFDEV_UBSAN) - set(CMAKE_C_FLAGS - "${CMAKE_C_FLAGS} \ - -fsanitize=alignment \ - -fsanitize=bounds \ - -fsanitize=shift \ - -fsanitize=integer-divide-by-zero \ - -fsanitize=unreachable \ - -fsanitize=bool \ - -fsanitize=enum \ - -fsanitize-undefined-trap-on-error" - ) -endif() - -include_directories(${PROJECT_SOURCE_DIR}/include) -include_directories(${PROJECT_BINARY_DIR}/generated) - -add_subdirectory(${PROJECT_SOURCE_DIR}/scripts) include(${PROJECT_SOURCE_DIR}/build.cmake) +add_subdirectory(${PROJECT_SOURCE_DIR}/scripts) -set(BFDEV_LIBRARY_HEADER - ${BFDEV_HEADER} - ${BFDEV_ASM_HEADER} - ${BFDEV_ARCH_ASM_HEADER} - ${BFDEV_GENERATED_HEADER} -) - -set(BFDEV_LIBRARY_SOURCE - ${BFDEV_SOURCE} - ${BFDEV_ARCH_SOURCE} +packed_header( + bfdev/ + _BFDEV_H_ + ${BFDEV_GENERATED_PATH}/bfdev.h + ${BFDEV_HEADER_PATH}/bfdev ) -set(BFDEV_LIBRARY - ${BFDEV_LIBRARY_HEADER} - ${BFDEV_LIBRARY_SOURCE} +packed_source( + ${PROJECT_BINARY_DIR}/bfdev.c + "${BFDEV_LIBRARY_SOURCE}" + "#undef MODULE_NAME\n" + "#undef bfdev_log_fmt\n" ) macro(bfdev_dependencies target) @@ -165,20 +92,6 @@ macro(bfdev_dependencies target) ) endmacro() -packed_header( - bfdev/ - _BFDEV_H_ - ${BFDEV_GENERATED_PATH}/bfdev.h - ${BFDEV_HEADER_PATH}/bfdev -) - -packed_source( - ${PROJECT_BINARY_DIR}/bfdev.c - "${BFDEV_LIBRARY_SOURCE}" - "#undef MODULE_NAME\n" - "#undef bfdev_log_fmt\n" -) - add_library(bfdev_object OBJECT ${BFDEV_LIBRARY}) bfdev_dependencies(bfdev_object) add_library(bfdev ALIAS bfdev_object) diff --git a/README.md b/README.md index c33e9830..8012fe0c 100644 --- a/README.md +++ b/README.md @@ -57,13 +57,13 @@ graph LR include[include] include/asm-generic[asm-generic] arch/asm[asm] - arch/asm-generated{exist} + arch/asm-generated{exist} subgraph target[User Installation] - include/bfdev[bfdev] - include/bfdev/asm-generic[bfdev:asm-generic] - arch/bfdev/asm[bfdev:asm] - arch/bfdev/asm-generated{exist} + include/bfdev[bfdev] + include/bfdev/asm-generic[bfdev:asm-generic] + arch/bfdev/asm[bfdev:asm] + arch/bfdev/asm-generated{exist} end include --> arch/asm-generated @@ -74,9 +74,9 @@ graph LR arch/bfdev/asm-generated --Y--> arch/bfdev/asm arch/bfdev/asm-generated --N--> include/bfdev/asm-generic arch/bfdev/asm -.-> include/bfdev/asm-generic - include --> include/bfdev - arch/asm --> arch/bfdev/asm - include/asm-generic --> arch/bfdev/asm + include --> include/bfdev + arch/asm --> arch/bfdev/asm + include/asm-generic --> arch/bfdev/asm ``` ## Documentation Tutorial @@ -84,7 +84,7 @@ graph LR Quickly start, API manual, see [Bfdev Documentation Tutorial](https://openbfdev.github.io/bfdev-docs) > [!CAUTION] -> This project is not yet fully completed, so it is not recommended for use in a production environment. +> This project requires additional testing. If used in a production environment, please be aware of the associated risks. ## License diff --git a/arch/dummy/include/bfdev/.gitkeep b/arch/dummy/include/bfdev/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/arch/dummy/build.cmake b/arch/generic/build.cmake similarity index 100% rename from arch/dummy/build.cmake rename to arch/generic/build.cmake diff --git a/arch/generic/include/bfdev/asm/bitops.h b/arch/generic/include/bfdev/asm/bitops.h new file mode 100644 index 00000000..25b8cc6a --- /dev/null +++ b/arch/generic/include/bfdev/asm/bitops.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright(c) 2024 John Sanpe + */ + +#ifndef _BFDEV_ASM_BITOPS_H_ +#define _BFDEV_ASM_BITOPS_H_ + +#include + +BFDEV_BEGIN_DECLS + +BFDEV_END_DECLS + +#include +#include +#include +#include +#include +#include +#include + +#endif /* _BFDEV_ASM_BITOPS_H_ */ diff --git a/build.cmake b/build.cmake index c2ff7da7..71447a6e 100644 --- a/build.cmake +++ b/build.cmake @@ -3,21 +3,88 @@ # Copyright(c) 2023 John Sanpe # -file(GLOB BFDEV_HEADER - ${BFDEV_HEADER_PATH}/bfdev/*.h +add_compile_options( + -std=gnu11 + -Wall + -Wextra + -Wno-override-init + -Wno-unused-parameter + -Wno-sign-compare + -Wno-pointer-sign + -Wno-null-pointer-arithmetic + -Wmissing-prototypes + -Wmissing-declarations + -fvisibility=hidden ) -file(GLOB BFDEV_ASM_HEADER - ${BFDEV_HEADER_PATH}/bfdev/asm-generic/*.h +if(BFDEV_STRICT) + set(CMAKE_C_FLAGS + "${CMAKE_C_FLAGS} \ + -Werror" + ) +endif() + +include(scripts/sanitize.cmake) +include(scripts/asm-generic.cmake) + +asm_generic( + bfdev/asm-generic/ + ${BFDEV_GENERATED_PATH}/bfdev/asm + ${BFDEV_ARCH_HEADER_PATH}/bfdev/asm + ${BFDEV_HEADER_PATH}/bfdev/asm-generic ) -file(GLOB BFDEV_ARCH_ASM_HEADER - ${BFDEV_ARCH_HEADER_PATH}/bfdev/asm/*.h +configure_file( + ${BFDEV_MODULE_PATH}/config.h.in + ${BFDEV_GENERATED_PATH}/bfdev/config.h ) -file(GLOB BFDEV_GENERATED_HEADER +configure_file( + ${BFDEV_MODULE_PATH}/bfdev-config.cmake.in + ${BFDEV_CONFIGURE} +) + +file(GLOB_RECURSE BFDEV_HEADER + ${BFDEV_HEADER_PATH}/*.h +) + +file(GLOB_RECURSE BFDEV_GENERATED_HEADER ${BFDEV_GENERATED_PATH}/*.h ) +file(GLOB_RECURSE BFDEV_ARCH_HEADER + ${BFDEV_ARCH_HEADER_PATH}/*.h +) + +set(BFDEV_INCLUDE_DIRS + ${BFDEV_HEADER_PATH} + ${BFDEV_GENERATED_PATH} + ${BFDEV_ARCH_HEADER_PATH} +) + +set_property( + GLOBAL PROPERTY + "BFDEV_INCLUDE_DIRS" + ${BFDEV_INCLUDE_DIRS} +) + +include_directories(${BFDEV_INCLUDE_DIRS}) include(${BFDEV_ARCH_PATH}/build.cmake) include(${BFDEV_SOURCE_PATH}/build.cmake) + +set(BFDEV_LIBRARY_HEADER + ${BFDEV_HEADER} + ${BFDEV_ASM_HEADER} + ${BFDEV_ARCH_ASM_HEADER} + ${BFDEV_GENERATED_HEADER} +) + +set(BFDEV_LIBRARY_SOURCE + ${BFDEV_SOURCE} + ${BFDEV_ARCH_SOURCE} +) + +set(BFDEV_LIBRARY + ${BFDEV_LIBRARY_HEADER} + ${BFDEV_LIBRARY_SOURCE} +) diff --git a/docs/components.md b/docs/components.md index b90a483a..8ec0b378 100644 --- a/docs/components.md +++ b/docs/components.md @@ -1,93 +1,96 @@ # Supporting Components -## Data Structures - -- array -- bloom -- btree -- fifo -- hashmap -- hashtbl -- heap -- hlist -- ilist -- list -- llist -- radix -- rbtree -- ringbuf -- segtree -- skiplist -- slist +## Data Container + +- array: Dynamic array, also with stack APIs +- bloom: Bloom filter +- btree: B+ tree +- circle: Circular queue +- fifo: First in first out (single read/write needn't lock) +- hashmap: Hash map with burst rehash +- hashtbl: Hash table tools +- heap: Binary heap tree +- hlist: Hash linked list +- ilist: Index linked list +- list: Double linked list +- llist: Lock free linked list +- radix: Radix tree +- rbtree: Red black tree +- ringbuf: Ring buffer +- segtree: Segment tree +- skiplist: Skip list +- slist: Single linked list ## Algorithms -- ascii85 -- base64 -- base64 -- bsearch -- crc -- hash -- prandom -- stringhash +- arc4: RC4 stream cipher +- ascii85: Ascii85 binary-to-text encoding +- base32: Base32 binary-to-text encoding +- base64: Base64 binary-to-text encoding +- bsearch: Array binary search +- crc: Cyclic redundancy check +- hash: Golden ratio Hash +- prandom: Pseudo random generator +- stringhash: String hash functions ## Bit Operation -- bcd -- bitfied -- bitmap -- bitops -- bitrev -- bitwalk -- popcount +- bcd: Binary-coded-decimal encoding +- bitfield: Bit padding functions +- bitmap: Bitmap operations +- bitops: Bit operations +- bitrev: Bitwise reversal +- bitwalk: Bitmap iterator +- popcount: Bitwise statistics ## Architecture -- atomic -- byteorder -- cmpxchg -- overflow -- swab -- unaligned +- atomic: Atomic operation functions +- byteorder: Byte order exchange +- cmpxchg: Atomic compare and exchange +- overflow: Saturation operations +- swab: Byte exchange functions +- unaligned: Non-aligned access functions ## Memory Allocator -- allocator -- allocpool -- minpool +- allocator: Allocation compatibility layer +- allocpool: Mempool optimized for allocation performance +- minpool: Simple memory allocator ## String Process -- argv -- fsm -- levenshtein -- snprintf +- argv: Argv segmentation +- fsm: Finite state machine +- levenshtein: Levenshtein edit distance +- scnprintf: Safe snprintf in buffer ## Mathematics -- align -- log2 -- math -- minmax -- uplower +- align: Alignment functions +- dword: Double word calculate +- log2: Log2 calculate +- math: Mathematical methods +- minmax: Maximum and minimum value +- uplower: High and low bytes +- mpi: Multi precision integer ## Cache -- lfu -- lru +- lfu: Least-frequently-used cache +- lru: Least-recently-used cache ## Textsearch -- bm -- kmp -- sunday +- bm: Boyer–Moore string-search algorithm +- kmp: Knuth–Morris–Pratt string-search algorithm +- sunday:Sunday string-search algorithm ## Miscellaneous -- action -- callback -- container -- guards -- log -- notifier -- once +- action: Callback function framework +- callback: Dummy callbacks +- guards: Clear variable when goes out of scope +- log: Log framework +- notifier: Notifier chain +- once: Do once functions diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index a4f1c612..5e0a745f 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -32,6 +32,7 @@ add_subdirectory(minpool) add_subdirectory(mpi) add_subdirectory(notifier) add_subdirectory(once) +add_subdirectory(prandom) add_subdirectory(radix) add_subdirectory(rbtree) add_subdirectory(ringbuf) diff --git a/examples/btree/benchmark.c b/examples/btree/benchmark.c index 74d1a147..516aa109 100644 --- a/examples/btree/benchmark.c +++ b/examples/btree/benchmark.c @@ -32,7 +32,7 @@ node_dump(struct bench_node *node) # define node_dump(node) ((void)(node)) #endif -static const struct bfdev_btree_ops +static const bfdev_btree_ops_t bench_ops = { .alloc = bfdev_btree_alloc, .free = bfdev_btree_free, @@ -97,7 +97,7 @@ int main(int argc, const char *argv[]) bfdev_log_info("\ttotal num: %u\n", count); bfdev_log_info("Done.\n"); - bfdev_btree_destroy(&bench_root); + bfdev_btree_release(&bench_root, NULL, NULL); free(block); return 0; diff --git a/examples/btree/selftest.c b/examples/btree/selftest.c index 51ff8912..9e3efe3c 100644 --- a/examples/btree/selftest.c +++ b/examples/btree/selftest.c @@ -21,7 +21,7 @@ struct test_node { }; static int -test_clash(struct bfdev_btree_root *root, void *value, void *clash) +test_clash(bfdev_btree_root_t *root, void *value, void *clash) { struct test_node *vnode = value; struct test_node *cnode = clash; @@ -30,7 +30,7 @@ test_clash(struct bfdev_btree_root *root, void *value, void *clash) } static void * -test_remove(struct bfdev_btree_root *root, void *value) +test_remove(bfdev_btree_root_t *root, void *value) { struct test_node *vnode = value; struct test_node *remove; @@ -45,14 +45,14 @@ test_remove(struct bfdev_btree_root *root, void *value) } static long -test_strfind(struct bfdev_btree_root *root, uintptr_t *node, uintptr_t *key) +test_strfind(bfdev_btree_root_t *root, uintptr_t *node, uintptr_t *key) { const char *nstring = (void *)*node ?: ""; const char *kstring = (void *)*key ?: ""; return strcmp(nstring, kstring); } -static const struct bfdev_btree_ops +static const bfdev_btree_ops_t test_value_ops = { .alloc = bfdev_btree_alloc, .free = bfdev_btree_free, @@ -62,7 +62,7 @@ test_value_ops = { }; -static const struct bfdev_btree_ops +static const bfdev_btree_ops_t test_string_ops = { .alloc = bfdev_btree_alloc, .free = bfdev_btree_free, @@ -124,7 +124,7 @@ test_testing(struct test_node *nodes) printf("btree random remove test%d\n", count); } - bfdev_btree_destroy(&root32); + bfdev_btree_release(&root32, NULL, NULL); BFDEV_BTREE_ROOT( rootstr, &bfdev_btree_layout32, @@ -173,7 +173,7 @@ test_testing(struct test_node *nodes) printf("btree string remove test%d\n", count); } - bfdev_btree_destroy(&rootstr); + bfdev_btree_release(&rootstr, NULL, NULL); return 0; } diff --git a/examples/cache/simple.c b/examples/cache/simple.c index 4b995c9c..6558c81e 100644 --- a/examples/cache/simple.c +++ b/examples/cache/simple.c @@ -17,12 +17,13 @@ #define TEST_SIZE 10 #define TEST_MASK 30 -int main(int argc, const char *argv[]) +static int +cache_test(const char *name) { bfdev_cache_head_t *cache; unsigned int count; - cache = bfdev_cache_create("lfu", NULL, TEST_SIZE, 1); + cache = bfdev_cache_create(name, NULL, TEST_SIZE, 1); if (!cache) return 1; @@ -37,15 +38,17 @@ int main(int argc, const char *argv[]) return 1; if (node->status == BFDEV_CACHE_PENDING) { - bfdev_log_info("test%u cache miss: %u\n", count, value); + bfdev_log_info("%s test%u cache miss: %u\n", name, count, value); node->pdata = (void *)(uintptr_t)value; bfdev_cache_committed(cache); } else { verify = (uintptr_t)node->pdata; if (value == verify) - bfdev_log_info("test%u cache hit: %u passed\n", count, verify); + bfdev_log_info("%s test%u cache hit: %u passed\n", + name, count, verify); else { - bfdev_log_err("test%u cache hit: %u failed\n", count, verify); + bfdev_log_err("%s test%u cache hit: %u failed\n", + name, count, verify); return 1; } } @@ -53,11 +56,26 @@ int main(int argc, const char *argv[]) bfdev_cache_put(cache, node); } - bfdev_log_notice("cache changed = %lu\n", cache->changed); - bfdev_log_notice("cache starve = %lu\n", cache->starve); - bfdev_log_notice("cache hits = %lu\n", cache->hits); - bfdev_log_notice("cache misses = %lu\n", cache->misses); + bfdev_log_notice("%s cache changed = %lu\n", name, cache->changed); + bfdev_log_notice("%s cache starve = %lu\n", name, cache->starve); + bfdev_log_notice("%s cache hits = %lu\n", name, cache->hits); + bfdev_log_notice("%s cache misses = %lu\n", name, cache->misses); bfdev_cache_destroy(cache); return 0; } + +int main(int argc, const char *argv[]) +{ + int retval; + + retval = cache_test("lru"); + if (retval) + return retval; + + retval = cache_test("lfu"); + if (retval) + return retval; + + return 0; +} diff --git a/examples/circle/atomic.c b/examples/circle/atomic.c index 2444383b..06b7b313 100644 --- a/examples/circle/atomic.c +++ b/examples/circle/atomic.c @@ -7,15 +7,14 @@ #include #include #include +#include #include #define TEST_SIZE 16 #define TEST_LOOP (TEST_SIZE * 64) -static volatile bfdev_circle_t -test_circle = { - .buffer = (char [TEST_SIZE]){}, -}; +static char buffer[TEST_SIZE]; +static BFDEV_DEFINE_CIRCLE(test_circle, buffer); static void * fifo_production(void *unused) @@ -23,20 +22,28 @@ fifo_production(void *unused) unsigned int index, count; for (count = 0; count < TEST_LOOP; ++count) { - while (!BFDEV_CIRCLE_SPACE(test_circle.head, test_circle.tail, TEST_SIZE)) - sched_yield(); + while (!BFDEV_CIRCLE_SPACE( + BFDEV_READ_ONCE(test_circle.head), + BFDEV_READ_ONCE(test_circle.tail), + TEST_SIZE + ) + ) sched_yield(); - index = test_circle.head % TEST_SIZE; + index = BFDEV_READ_ONCE(test_circle.head) % TEST_SIZE; ((char *)test_circle.buffer)[index] = "123456789ABCDEF\n"[index]; - test_circle.head++; + BFDEV_WRITE_ONCE(test_circle.head, test_circle.head + 1); } - while (!BFDEV_CIRCLE_SPACE(test_circle.head, test_circle.tail, TEST_SIZE)) - sched_yield(); + while (!BFDEV_CIRCLE_SPACE( + BFDEV_READ_ONCE(test_circle.head), + BFDEV_READ_ONCE(test_circle.tail), + TEST_SIZE + ) + ) sched_yield(); - index = test_circle.head % TEST_SIZE; + index = BFDEV_READ_ONCE(test_circle.head) % TEST_SIZE; ((char *)test_circle.buffer)[index] = 0; - test_circle.head++; + BFDEV_WRITE_ONCE(test_circle.head, test_circle.head + 1); return NULL; } @@ -49,12 +56,16 @@ int main(int argc, const char *argv[]) pthread_create(&thread, NULL, fifo_production, NULL); for (;;) { - while (!BFDEV_CIRCLE_CNT(test_circle.head, test_circle.tail, TEST_SIZE)) - sched_yield(); + while (!BFDEV_CIRCLE_CNT( + BFDEV_READ_ONCE(test_circle.head), + BFDEV_READ_ONCE(test_circle.tail), + TEST_SIZE + ) + ) sched_yield(); - index = test_circle.tail % TEST_SIZE; + index = BFDEV_READ_ONCE(test_circle.tail) % TEST_SIZE; ch = ((char *)test_circle.buffer)[index]; - test_circle.tail++; + BFDEV_WRITE_ONCE(test_circle.tail, test_circle.tail + 1); if (!ch) { printf("exit\n"); diff --git a/examples/matrix/benchmark.c b/examples/matrix/benchmark.c index eb7db37f..9c7469c8 100644 --- a/examples/matrix/benchmark.c +++ b/examples/matrix/benchmark.c @@ -18,9 +18,7 @@ #define GENERIC_MATRIX_BENCHMARK(func, name) \ for (count = 0; count < TEST_LOOP; ++count) { \ EXAMPLE_TIME_LOOP(&loop, 1000, \ - result = func(NULL, vara, varb); \ - bfdev_matrix_destory(NULL, result); \ - 0; \ + func(&dest, &vara, &varb); \ ); \ bfdev_log_info( \ name " %u: %uops/s\n", \ @@ -30,30 +28,34 @@ for (count = 0; count < TEST_LOOP; ++count) { \ int main(int argc, char const *argv[]) { + BFDEV_MATRIX_TYPE *buffer; unsigned int count, loop; - bfdev_matrix_t *vara, *varb; - bfdev_matrix_t *result; - vara = bfdev_matrix_create(NULL, TEST_SIZE, TEST_SIZE); - if (!vara) - return 1; + BFDEV_DEFINE_MATRIX(vara, NULL); + BFDEV_DEFINE_MATRIX(varb, NULL); + BFDEV_DEFINE_MATRIX(dest, NULL); - varb = bfdev_matrix_create(NULL, TEST_SIZE, TEST_SIZE); - if (!varb) + buffer = malloc(TEST_SIZE * TEST_SIZE * BFDEV_MATRIX_SIZE); + if (!buffer) return 1; srand(time(NULL)); - for (count = 0; count < TEST_SIZE * TEST_SIZE; ++count) { - vara->values[count] = (uint16_t)rand(); - varb->values[count] = (uint16_t)rand(); - } + for (count = 0; count < TEST_SIZE * TEST_SIZE; ++count) + buffer[count] = (uint16_t)rand(); + bfdev_matrix_import(&vara, buffer, TEST_SIZE, TEST_SIZE); + + for (count = 0; count < TEST_SIZE * TEST_SIZE; ++count) + buffer[count] = (uint16_t)rand(); + bfdev_matrix_import(&varb, buffer, TEST_SIZE, TEST_SIZE); GENERIC_MATRIX_BENCHMARK(bfdev_matrix_add, "adding") GENERIC_MATRIX_BENCHMARK(bfdev_matrix_sub, "subtracting") GENERIC_MATRIX_BENCHMARK(bfdev_matrix_mul, "multiplying") - bfdev_matrix_destory(NULL, vara); - bfdev_matrix_destory(NULL, varb); + bfdev_matrix_release(&vara); + bfdev_matrix_release(&varb); + bfdev_matrix_release(&dest); + free(buffer); return 0; } diff --git a/examples/matrix/fibonacci.c b/examples/matrix/fibonacci.c index b9be90cb..26029a91 100644 --- a/examples/matrix/fibonacci.c +++ b/examples/matrix/fibonacci.c @@ -10,66 +10,78 @@ #define TEST_BASE 1 #define TEST_MAXN 46 -static bfdev_matrix_t -matrix_power = { - .row = 2, .col = 2, - .values = { - 0, 1, - 1, 0, - }, +static const BFDEV_MATRIX_TYPE +matrix_power[] = { + 0, 1, + 1, 0, }; -static bfdev_matrix_t -matrix_fibonacci = { - .row = 2, .col = 2, - .values = { - 1, 1, - 1, 0, - }, +static const BFDEV_MATRIX_TYPE +matrix_fibonacci[] = { + 1, 1, + 1, 0, }; -static bfdev_matrix_t * -power(const bfdev_matrix_t *var, unsigned int pow) +static int +power(bfdev_matrix_t *result, const bfdev_matrix_t *var, + unsigned int pow) { - bfdev_matrix_t *result; - bfdev_matrix_t *tmp; + BFDEV_DEFINE_MATRIX(tmp, NULL); + int retval; - result = bfdev_matrix_copy(NULL, &matrix_power); - var = bfdev_matrix_copy(NULL, var); + retval = bfdev_matrix_import(result, matrix_power, 2, 2); + if (bfdev_unlikely(retval)) + return retval; + + retval = bfdev_matrix_set(&tmp, var); + if (bfdev_unlikely(retval)) + return retval; while (pow) { if (pow & 1) { - tmp = bfdev_matrix_mul(NULL, result, var); - if (bfdev_unlikely(!tmp)) - return NULL; - - bfdev_matrix_destory(NULL, result); - result = tmp; + retval = bfdev_matrix_mul(result, result, &tmp); + if (bfdev_unlikely(retval)) + return retval; } - tmp = bfdev_matrix_mul(NULL, var, var); - if (bfdev_unlikely(!tmp)) - return NULL; + retval = bfdev_matrix_mul(&tmp, &tmp, &tmp); + if (bfdev_unlikely(retval)) + return retval; - bfdev_matrix_destory(NULL, var); - var = tmp; pow >>= 1; } - bfdev_matrix_destory(NULL, var); - return result; + bfdev_matrix_release(&tmp); + return 0; } int main(int argc, const char *argv[]) { - bfdev_matrix_t *result; + BFDEV_DEFINE_MATRIX(fibonacci, NULL); + BFDEV_DEFINE_MATRIX(result, NULL); unsigned int count; + int retval; + + retval = bfdev_matrix_import(&fibonacci, matrix_fibonacci, 2, 2); + if (retval) + return retval; for (count = TEST_BASE; count <= TEST_MAXN; ++count) { - result = power(&matrix_fibonacci, count); - printf("matrix fibonacci %02u: %ld\n", count, result->values[0]); - bfdev_matrix_destory(NULL, result); + const BFDEV_MATRIX_TYPE *value; + + retval = power(&result, &fibonacci, count); + if (retval) + return retval; + + value = bfdev_matrix_data(&result, 0, 0); + if (!value) + return 1; + + printf("matrix fibonacci %02u: %ld\n", count, *value); } + bfdev_matrix_release(&fibonacci); + bfdev_matrix_release(&result); + return 0; } diff --git a/examples/mpi/fibonacci.c b/examples/mpi/fibonacci.c index 63480a5e..1afc5849 100644 --- a/examples/mpi/fibonacci.c +++ b/examples/mpi/fibonacci.c @@ -5,9 +5,11 @@ #include #include +#include "../time.h" #include "helper.h" #define TEST_LOOP 10000 +#define PRINT_RESULT 1 int main(int argc, const char *argv[]) { @@ -17,8 +19,8 @@ int main(int argc, const char *argv[]) int retval; if (!((va = bfdev_mpi_create(NULL)) && - (vb = bfdev_mpi_create(NULL)) && - (vc = bfdev_mpi_create(NULL)))) + (vb = bfdev_mpi_create(NULL)) && + (vc = bfdev_mpi_create(NULL)))) return 1; if ((retval = bfdev_mpi_seti(va, 1)) || @@ -26,19 +28,24 @@ int main(int argc, const char *argv[]) (retval = bfdev_mpi_seti(vc, 0))) return retval; - 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))) - 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))) + return retval; + } + 0; + ); + +#if PRINT_RESULT result = print_num(va, 10); if (!result) return 1; puts(result); free(result); +#endif bfdev_mpi_destory(va); bfdev_mpi_destory(vb); diff --git a/examples/mpi/helper.h b/examples/mpi/helper.h index 91ae9c44..5d025617 100644 --- a/examples/mpi/helper.h +++ b/examples/mpi/helper.h @@ -30,25 +30,24 @@ print_num(const bfdev_mpi_t *var, unsigned int base) return NULL; while (bfdev_mpi_cmpi(value, 0)) { - BFDEV_MPI_TYPE walk; - bool dummy; + const BFDEV_MPI_TYPE *walk; retval = bfdev_mpi_divi(value, taken, value, base); if (retval) return NULL; - retval = bfdev_mpi_read(taken, &walk, 1, &dummy); - if (retval) + walk = bfdev_mpi_data(taken, 0, NULL); + if (!walk) return NULL; buffer = bfdev_array_push(&stack, 1); if (!buffer) return NULL; - if (walk < 10) - *buffer = '0' + walk; + if (*walk < 10) + *buffer = '0' + *walk; else - *buffer = 'A' + walk - 10; + *buffer = 'A' + *walk - 10; } size = bfdev_array_size(&stack); diff --git a/examples/prandom/.gitignore b/examples/prandom/.gitignore new file mode 100644 index 00000000..82bc2a3b --- /dev/null +++ b/examples/prandom/.gitignore @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +/prandom-simple diff --git a/examples/prandom/CMakeLists.txt b/examples/prandom/CMakeLists.txt new file mode 100644 index 00000000..3760993e --- /dev/null +++ b/examples/prandom/CMakeLists.txt @@ -0,0 +1,22 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright(c) 2024 John Sanpe +# + +add_executable(prandom-simple simple.c) +target_link_libraries(prandom-simple bfdev) +add_test(prandom-simple prandom-simple) + +if(${CMAKE_PROJECT_NAME} STREQUAL "bfdev") + install(FILES + simple.c + DESTINATION + ${CMAKE_INSTALL_DOCDIR}/examples/prandom + ) + + install(TARGETS + prandom-simple + DESTINATION + ${CMAKE_INSTALL_DOCDIR}/bin + ) +endif() diff --git a/examples/prandom/simple.c b/examples/prandom/simple.c new file mode 100644 index 00000000..0732081b --- /dev/null +++ b/examples/prandom/simple.c @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright(c) 2024 John Sanpe + */ + +#define MODULE_NAME "prandom-simple" +#define bfdev_log_fmt(fmt) MODULE_NAME ": " fmt + +#include +#include +#include + +#define TEST_LOOP 100 + +BFDEV_DEFINE_PRANDOM(prandom); + +int main(int argc, const char *argv[]) +{ + unsigned int count; + uint64_t seed; + uint32_t value; + + seed = ((uint64_t)time(NULL) << 32) ^ time(NULL); + bfdev_log_info("prandom seed: %#018llx\n", (long long)seed); + bfdev_prandom_seed(&prandom, seed); + + for (count = 0; count < TEST_LOOP; ++count) { + value = bfdev_prandom_value(&prandom); + bfdev_log_info("prandom value: %#010x\n", value); + } + + return 0; +} diff --git a/examples/radix/benchmark.c b/examples/radix/benchmark.c index 3c26f5a4..20479dfe 100644 --- a/examples/radix/benchmark.c +++ b/examples/radix/benchmark.c @@ -80,7 +80,7 @@ int main(int argc, const char *argv[]) } bfdev_log_info("Done.\n"); - bfdev_radix_destory(&bench_root); + bfdev_radix_release(&bench_root); free(data); return 0; diff --git a/examples/radix/simple.c b/examples/radix/simple.c index 06d25372..dd8849ae 100644 --- a/examples/radix/simple.c +++ b/examples/radix/simple.c @@ -46,6 +46,6 @@ int main(int argc, const char *argv[]) printf("passed\n"); } - bfdev_radix_destory(&simple_root); + bfdev_radix_release(&simple_root); return 0; } diff --git a/examples/skiplist/benchmark.c b/examples/skiplist/benchmark.c index 22d29e95..3c81d53f 100644 --- a/examples/skiplist/benchmark.c +++ b/examples/skiplist/benchmark.c @@ -83,7 +83,7 @@ int main(int argc, const char *argv[]) 0; ); - bfdev_skiplist_destroy(head, NULL); + bfdev_skiplist_destroy(head, NULL, NULL); free(record); return 0; diff --git a/examples/skiplist/selftest.c b/examples/skiplist/selftest.c index ac7f91b7..365cda37 100644 --- a/examples/skiplist/selftest.c +++ b/examples/skiplist/selftest.c @@ -51,7 +51,7 @@ skiplist_testing(struct test_node *test) uintptr_t value; int retval; - bfdev_skiplist_reset(test->head, NULL); + bfdev_skiplist_reset(test->head, NULL, NULL); for (count = 0; count < TEST_LOOP; ++count) test->values[count] = rand() | 1; @@ -104,7 +104,7 @@ int main(int argc, const char *argv[]) } retval = skiplist_testing(test); - bfdev_skiplist_destroy(test->head, NULL); + bfdev_skiplist_destroy(test->head, NULL, NULL); free(test); return retval; diff --git a/include/bfdev/allocator.h b/include/bfdev/allocator.h index 9f13aa16..f5768d92 100644 --- a/include/bfdev/allocator.h +++ b/include/bfdev/allocator.h @@ -28,8 +28,9 @@ struct bfdev_alloc_ops { bfdev_free_t free; }; -#define BFDEV_ALLOC_OPS_STATIC(ALLOC, REALLOC, FREE) \ - {.alloc = (ALLOC), .realloc = (REALLOC), .free = (FREE)} +#define BFDEV_ALLOC_OPS_STATIC(ALLOC, REALLOC, FREE) { \ + .alloc = (ALLOC), .realloc = (REALLOC), .free = (FREE), \ +} #define BFDEV_ALLOC_OPS_INIT(alloc, realloc, free) \ (bfdev_alloc_ops_t) BFDEV_ALLOC_OPS_STATIC(alloc, realloc, free) @@ -37,8 +38,9 @@ struct bfdev_alloc_ops { #define BFDEV_DEFINE_ALLOC_OPS(name, alloc, realloc, free) \ bfdev_alloc_ops_t name = BFDEV_ALLOC_OPS_INIT(alloc, realloc, free) -#define BFDEV_ALLOC_STATIC(ALLOC, REALLOC, FREE, PDATA) \ - {.ops = &BFDEV_ALLOC_OPS_INIT(ALLOC, REALLOC, FREE), .pdata = (PDATA)} +#define BFDEV_ALLOC_STATIC(ALLOC, REALLOC, FREE, PDATA) { \ + .ops = &BFDEV_ALLOC_OPS_INIT(ALLOC, REALLOC, FREE), .pdata = (PDATA), \ +} #define BFDEV_ALLOC_INIT(alloc, realloc, free, pdata) \ (bfdev_alloc_t) BFDEV_ALLOC_STATIC(alloc, realloc, free, pdata) diff --git a/include/bfdev/allocpool.h b/include/bfdev/allocpool.h index ed9fee91..27bb98a1 100644 --- a/include/bfdev/allocpool.h +++ b/include/bfdev/allocpool.h @@ -21,8 +21,9 @@ struct bfdev_allocpool { unsigned long count; }; -#define BFDEV_ALLOCPOOL_STATIC(BLOCK, SIZE) \ - {.block = (BLOCK), .size = (SIZE)} +#define BFDEV_ALLOCPOOL_STATIC(BLOCK, SIZE) { \ + .block = (BLOCK), .size = (SIZE), \ +} #define BFDEV_ALLOCPOOL_INIT(block, size) \ (bfdev_allocpool_t) BFDEV_ALLOCPOOL_STATIC(block, size) diff --git a/include/bfdev/argv.h b/include/bfdev/argv.h index 2e1f5bef..a5935a35 100644 --- a/include/bfdev/argv.h +++ b/include/bfdev/argv.h @@ -21,8 +21,8 @@ bfdev_argv_count(const char *string); * @argcp: returned argument count. */ extern char ** -bfdev_argv_split(const bfdev_alloc_t *alloc, - const char *string, unsigned int *argcp); +bfdev_argv_split(const bfdev_alloc_t *alloc, const char *string, + unsigned int *argcp); /** * bfdev_argv_destory() - destory an argv. @@ -30,8 +30,7 @@ bfdev_argv_split(const bfdev_alloc_t *alloc, * @argv: the argument vector to be freed. */ extern void -bfdev_argv_destory(const bfdev_alloc_t *alloc, - char **argv); +bfdev_argv_destory(const bfdev_alloc_t *alloc, char **argv); BFDEV_END_DECLS diff --git a/include/bfdev/array.h b/include/bfdev/array.h index 146dd80b..1095cdaa 100644 --- a/include/bfdev/array.h +++ b/include/bfdev/array.h @@ -28,8 +28,9 @@ struct bfdev_array { void *data; }; -#define BFDEV_ARRAY_STATIC(ALLOC, CELLS) \ - {.alloc = (ALLOC), .cells = (CELLS)} +#define BFDEV_ARRAY_STATIC(ALLOC, CELLS) { \ + .alloc = (ALLOC), .cells = (CELLS), \ +} #define BFDEV_ARRAY_INIT(alloc, cells) \ (bfdev_array_t) BFDEV_ARRAY_STATIC(alloc, cells) diff --git a/include/bfdev/asm-generic/atomic.h b/include/bfdev/asm-generic/atomic.h index c1358716..dac3dfb2 100644 --- a/include/bfdev/asm-generic/atomic.h +++ b/include/bfdev/asm-generic/atomic.h @@ -12,19 +12,23 @@ BFDEV_BEGIN_DECLS -#define bfdev_arch_atomic_read bfdev_arch_atomic_read +#ifndef bfdev_arch_atomic_read +# define bfdev_arch_atomic_read bfdev_arch_atomic_read static __bfdev_always_inline bfdev_atomic_t bfdev_arch_atomic_read(const bfdev_atomic_t *atomic) { return BFDEV_READ_ONCE(*atomic); } +#endif -#define bfdev_arch_atomic_write bfdev_arch_atomic_write +#ifndef bfdev_arch_atomic_write +# define bfdev_arch_atomic_write bfdev_arch_atomic_write static __bfdev_always_inline void bfdev_arch_atomic_write(bfdev_atomic_t *atomic, bfdev_atomic_t value) { BFDEV_WRITE_ONCE(*atomic, value); } +#endif #define BFDEV_GENERIC_ATOMIC(name, func) \ static __bfdev_always_inline void \ @@ -40,41 +44,80 @@ bfdev_arch_atomic_##name(bfdev_atomic_t *atomic, bfdev_atomic_t value) \ return func(atomic, value); \ } -#define bfdev_arch_atomic_add bfdev_arch_atomic_add -#define bfdev_arch_atomic_sub bfdev_arch_atomic_sub -#define bfdev_arch_atomic_and bfdev_arch_atomic_and -#define bfdev_arch_atomic_or bfdev_arch_atomic_or -#define bfdev_arch_atomic_xor bfdev_arch_atomic_xor - +#ifndef bfdev_arch_atomic_add +# define bfdev_arch_atomic_add bfdev_arch_atomic_add BFDEV_GENERIC_ATOMIC(add, __sync_fetch_and_add) +#endif + +#ifndef bfdev_arch_atomic_sub +# define bfdev_arch_atomic_sub bfdev_arch_atomic_sub BFDEV_GENERIC_ATOMIC(sub, __sync_fetch_and_sub) +#endif + +#ifndef bfdev_arch_atomic_and +# define bfdev_arch_atomic_and bfdev_arch_atomic_and BFDEV_GENERIC_ATOMIC(and, __sync_fetch_and_and) +#endif + +#ifndef bfdev_arch_atomic_or +# define bfdev_arch_atomic_or bfdev_arch_atomic_or BFDEV_GENERIC_ATOMIC(or, __sync_fetch_and_or) -BFDEV_GENERIC_ATOMIC(xor, __sync_fetch_and_xor) +#endif -#define bfdev_arch_atomic_fetch_add bfdev_arch_atomic_fetch_add -#define bfdev_arch_atomic_fetch_sub bfdev_arch_atomic_fetch_sub -#define bfdev_arch_atomic_fetch_and bfdev_arch_atomic_fetch_and -#define bfdev_arch_atomic_fetch_or bfdev_arch_atomic_fetch_or -#define bfdev_arch_atomic_fetch_xor bfdev_arch_atomic_fetch_xor +#ifndef bfdev_arch_atomic_xor +# define bfdev_arch_atomic_xor bfdev_arch_atomic_xor +BFDEV_GENERIC_ATOMIC(xor, __sync_fetch_and_xor) +#endif +#ifndef bfdev_arch_atomic_fetch_add +# define bfdev_arch_atomic_fetch_add bfdev_arch_atomic_fetch_add BFDEV_GENERIC_ATOMIC_FETCH(fetch_add, __sync_fetch_and_add) +#endif + +#ifndef bfdev_arch_atomic_fetch_sub +# define bfdev_arch_atomic_fetch_sub bfdev_arch_atomic_fetch_sub BFDEV_GENERIC_ATOMIC_FETCH(fetch_sub, __sync_fetch_and_sub) +#endif + +#ifndef bfdev_arch_atomic_fetch_and +# define bfdev_arch_atomic_fetch_and bfdev_arch_atomic_fetch_and BFDEV_GENERIC_ATOMIC_FETCH(fetch_and, __sync_fetch_and_and) +#endif + +#ifndef bfdev_arch_atomic_fetch_or +# define bfdev_arch_atomic_fetch_or bfdev_arch_atomic_fetch_or BFDEV_GENERIC_ATOMIC_FETCH(fetch_or, __sync_fetch_and_or) -BFDEV_GENERIC_ATOMIC_FETCH(fetch_xor, __sync_fetch_and_xor) +#endif -#define bfdev_arch_atomic_add_fetch bfdev_arch_atomic_add_fetch -#define bfdev_arch_atomic_sub_fetch bfdev_arch_atomic_sub_fetch -#define bfdev_arch_atomic_and_fetch bfdev_arch_atomic_and_fetch -#define bfdev_arch_atomic_or_fetch bfdev_arch_atomic_or_fetch -#define bfdev_arch_atomic_xor_fetch bfdev_arch_atomic_xor_fetch +#ifndef bfdev_arch_atomic_fetch_xor +# define bfdev_arch_atomic_fetch_xor bfdev_arch_atomic_fetch_xor +BFDEV_GENERIC_ATOMIC_FETCH(fetch_xor, __sync_fetch_and_xor) +#endif +#ifndef bfdev_arch_atomic_add_fetch +# define bfdev_arch_atomic_add_fetch bfdev_arch_atomic_add_fetch BFDEV_GENERIC_ATOMIC_FETCH(add_fetch, __sync_add_and_fetch) +#endif + +#ifndef bfdev_arch_atomic_sub_fetch +# define bfdev_arch_atomic_sub_fetch bfdev_arch_atomic_sub_fetch BFDEV_GENERIC_ATOMIC_FETCH(sub_fetch, __sync_sub_and_fetch) +#endif + +#ifndef bfdev_arch_atomic_and_fetch +# define bfdev_arch_atomic_and_fetch bfdev_arch_atomic_and_fetch BFDEV_GENERIC_ATOMIC_FETCH(and_fetch, __sync_and_and_fetch) +#endif + +#ifndef bfdev_arch_atomic_or_fetch +# define bfdev_arch_atomic_or_fetch bfdev_arch_atomic_or_fetch BFDEV_GENERIC_ATOMIC_FETCH(or_fetch, __sync_or_and_fetch) +#endif + +#ifndef bfdev_arch_atomic_xor_fetch +# define bfdev_arch_atomic_xor_fetch bfdev_arch_atomic_xor_fetch BFDEV_GENERIC_ATOMIC_FETCH(xor_fetch, __sync_xor_and_fetch) +#endif BFDEV_END_DECLS diff --git a/include/bfdev/asm-generic/bitops.h b/include/bfdev/asm-generic/bitops.h index d13e0af4..11017b37 100644 --- a/include/bfdev/asm-generic/bitops.h +++ b/include/bfdev/asm-generic/bitops.h @@ -15,6 +15,7 @@ BFDEV_BEGIN_DECLS #ifndef bfdev_arch_bit_clr +# define bfdev_arch_bit_clr bfdev_arch_bit_clr static __bfdev_always_inline void bfdev_arch_bit_clr(volatile unsigned long *addr, unsigned int bit) { @@ -24,6 +25,7 @@ bfdev_arch_bit_clr(volatile unsigned long *addr, unsigned int bit) #endif #ifndef bfdev_arch_bit_set +# define bfdev_arch_bit_set bfdev_arch_bit_set static __bfdev_always_inline void bfdev_arch_bit_set(volatile unsigned long *addr, unsigned int bit) { @@ -33,6 +35,7 @@ bfdev_arch_bit_set(volatile unsigned long *addr, unsigned int bit) #endif #ifndef bfdev_arch_bit_flip +# define bfdev_arch_bit_flip bfdev_arch_bit_flip static __bfdev_always_inline void bfdev_arch_bit_flip(volatile unsigned long *addr, unsigned int bit) { @@ -42,6 +45,7 @@ bfdev_arch_bit_flip(volatile unsigned long *addr, unsigned int bit) #endif #ifndef bfdev_arch_bit_change +# define bfdev_arch_bit_change bfdev_arch_bit_change static __bfdev_always_inline void bfdev_arch_bit_change(volatile unsigned long *addr, unsigned int bit, bool val) { @@ -54,6 +58,7 @@ bfdev_arch_bit_change(volatile unsigned long *addr, unsigned int bit, bool val) #endif #ifndef bfdev_arch_bit_test +# define bfdev_arch_bit_test bfdev_arch_bit_test static __bfdev_always_inline bool bfdev_arch_bit_test(const volatile unsigned long *addr, unsigned int bit) { @@ -63,6 +68,7 @@ bfdev_arch_bit_test(const volatile unsigned long *addr, unsigned int bit) #endif #ifndef bfdev_arch_bit_test_clr +# define bfdev_arch_bit_test_clr bfdev_arch_bit_test_clr static __bfdev_always_inline bool bfdev_arch_bit_test_clr(volatile unsigned long *addr, unsigned int bit) { @@ -75,6 +81,7 @@ bfdev_arch_bit_test_clr(volatile unsigned long *addr, unsigned int bit) #endif #ifndef bfdev_arch_bit_test_set +# define bfdev_arch_bit_test_set bfdev_arch_bit_test_set static __bfdev_always_inline bool bfdev_arch_bit_test_set(volatile unsigned long *addr, unsigned int bit) { @@ -87,6 +94,7 @@ bfdev_arch_bit_test_set(volatile unsigned long *addr, unsigned int bit) #endif #ifndef bfdev_arch_bit_test_flip +# define bfdev_arch_bit_test_flip bfdev_arch_bit_test_flip static __bfdev_always_inline bool bfdev_arch_bit_test_flip(volatile unsigned long *addr, unsigned int bit) { @@ -99,6 +107,7 @@ bfdev_arch_bit_test_flip(volatile unsigned long *addr, unsigned int bit) #endif #ifndef bfdev_arch_bit_test_change +# define bfdev_arch_bit_test_change bfdev_arch_bit_test_change static __bfdev_always_inline bool bfdev_arch_bit_test_change(volatile unsigned long *addr, unsigned int bit, bool val) { @@ -114,6 +123,7 @@ bfdev_arch_bit_test_change(volatile unsigned long *addr, unsigned int bit, bool #endif #ifndef bfdev_arch_bit_atomic_clr +# define bfdev_arch_bit_atomic_clr bfdev_arch_bit_atomic_clr static __bfdev_always_inline void bfdev_arch_bit_atomic_clr(volatile unsigned long *addr, unsigned int bit) { @@ -123,6 +133,7 @@ bfdev_arch_bit_atomic_clr(volatile unsigned long *addr, unsigned int bit) #endif #ifndef bfdev_arch_bit_atomic_set +# define bfdev_arch_bit_atomic_set bfdev_arch_bit_atomic_set static __bfdev_always_inline void bfdev_arch_bit_atomic_set(volatile unsigned long *addr, unsigned int bit) { @@ -132,6 +143,7 @@ bfdev_arch_bit_atomic_set(volatile unsigned long *addr, unsigned int bit) #endif #ifndef bfdev_arch_bit_atomic_flip +# define bfdev_arch_bit_atomic_flip bfdev_arch_bit_atomic_flip static __bfdev_always_inline void bfdev_arch_bit_atomic_flip(volatile unsigned long *addr, unsigned int bit) { @@ -141,6 +153,7 @@ bfdev_arch_bit_atomic_flip(volatile unsigned long *addr, unsigned int bit) #endif #ifndef bfdev_arch_bit_atomic_change +# define bfdev_arch_bit_atomic_change bfdev_arch_bit_atomic_change static __bfdev_always_inline void bfdev_arch_bit_atomic_change(volatile unsigned long *addr, unsigned int bit, bool val) { @@ -153,6 +166,7 @@ bfdev_arch_bit_atomic_change(volatile unsigned long *addr, unsigned int bit, boo #endif #ifndef bfdev_arch_bit_atomic_test +# define bfdev_arch_bit_atomic_test bfdev_arch_bit_atomic_test static __bfdev_always_inline bool bfdev_arch_bit_atomic_test(const volatile unsigned long *addr, unsigned int bit) { @@ -162,6 +176,7 @@ bfdev_arch_bit_atomic_test(const volatile unsigned long *addr, unsigned int bit) #endif #ifndef bfdev_arch_bit_atomic_test_clr +# define bfdev_arch_bit_atomic_test_clr bfdev_arch_bit_atomic_test_clr static __bfdev_always_inline bool bfdev_arch_bit_atomic_test_clr(volatile unsigned long *addr, unsigned int bit) { @@ -177,6 +192,7 @@ bfdev_arch_bit_atomic_test_clr(volatile unsigned long *addr, unsigned int bit) #endif #ifndef bfdev_arch_bit_atomic_test_set +# define bfdev_arch_bit_atomic_test_set bfdev_arch_bit_atomic_test_set static __bfdev_always_inline bool bfdev_arch_bit_atomic_test_set(volatile unsigned long *addr, unsigned int bit) { @@ -192,6 +208,7 @@ bfdev_arch_bit_atomic_test_set(volatile unsigned long *addr, unsigned int bit) #endif #ifndef bfdev_arch_bit_atomic_test_flip +# define bfdev_arch_bit_atomic_test_flip bfdev_arch_bit_atomic_test_flip static __bfdev_always_inline bool bfdev_arch_bit_atomic_test_flip(volatile unsigned long *addr, unsigned int bit) { @@ -203,6 +220,7 @@ bfdev_arch_bit_atomic_test_flip(volatile unsigned long *addr, unsigned int bit) #endif #ifndef bfdev_arch_bit_atomic_test_change +# define bfdev_arch_bit_atomic_test_change bfdev_arch_bit_atomic_test_change static __bfdev_always_inline bool bfdev_arch_bit_atomic_test_change(volatile unsigned long *addr, unsigned int bit, bool val) { @@ -222,6 +240,7 @@ bfdev_arch_bit_atomic_test_change(volatile unsigned long *addr, unsigned int bit * @shift: bits to roll. */ #ifndef bfdev_arch_rol8 +# define bfdev_arch_rol8 bfdev_arch_rol8 static __bfdev_always_inline uint8_t bfdev_arch_rol8(uint8_t value, unsigned int shift) { @@ -235,6 +254,7 @@ bfdev_arch_rol8(uint8_t value, unsigned int shift) * @shift: bits to roll. */ #ifndef bfdev_arch_ror8 +# define bfdev_arch_ror8 bfdev_arch_ror8 static __bfdev_always_inline uint8_t bfdev_arch_ror8(uint8_t value, unsigned int shift) { @@ -248,6 +268,7 @@ bfdev_arch_ror8(uint8_t value, unsigned int shift) * @shift: bits to roll. */ #ifndef bfdev_arch_rol16 +# define bfdev_arch_rol16 bfdev_arch_rol16 static __bfdev_always_inline uint16_t bfdev_arch_rol16(uint16_t value, unsigned int shift) { @@ -261,6 +282,7 @@ bfdev_arch_rol16(uint16_t value, unsigned int shift) * @shift: bits to roll. */ #ifndef bfdev_arch_ror16 +# define bfdev_arch_ror16 bfdev_arch_ror16 static __bfdev_always_inline uint16_t bfdev_arch_ror16(uint16_t value, unsigned int shift) { @@ -274,6 +296,7 @@ bfdev_arch_ror16(uint16_t value, unsigned int shift) * @shift: bits to roll. */ #ifndef bfdev_arch_rol32 +# define bfdev_arch_rol32 bfdev_arch_rol32 static __bfdev_always_inline uint32_t bfdev_arch_rol32(uint32_t value, unsigned int shift) { @@ -287,6 +310,7 @@ bfdev_arch_rol32(uint32_t value, unsigned int shift) * @shift: bits to roll. */ #ifndef bfdev_arch_ror32 +# define bfdev_arch_ror32 bfdev_arch_ror32 static __bfdev_always_inline uint32_t bfdev_arch_ror32(uint32_t value, unsigned int shift) { @@ -300,6 +324,7 @@ bfdev_arch_ror32(uint32_t value, unsigned int shift) * @shift: bits to roll. */ #ifndef bfdev_arch_rol64 +# define bfdev_arch_rol64 bfdev_arch_rol64 static __bfdev_always_inline uint64_t bfdev_arch_rol64(uint64_t value, unsigned int shift) { @@ -313,6 +338,7 @@ bfdev_arch_rol64(uint64_t value, unsigned int shift) * @shift: bits to roll. */ #ifndef bfdev_arch_ror64 +# define bfdev_arch_ror64 bfdev_arch_ror64 static __bfdev_always_inline uint64_t bfdev_arch_ror64(uint64_t value, unsigned int shift) { @@ -326,6 +352,7 @@ bfdev_arch_ror64(uint64_t value, unsigned int shift) * Undefined if no bit exists, so code should check against 0 first.. */ #ifndef bfdev_arch_ffsuf +# define bfdev_arch_ffsuf bfdev_arch_ffsuf static __bfdev_always_inline unsigned int bfdev_arch_ffsuf(unsigned long value) { @@ -372,6 +399,7 @@ bfdev_arch_ffsuf(unsigned long value) * Undefined if no set bit exists, so code should check against 0 first.. */ #ifndef bfdev_arch_flsuf +# define bfdev_arch_flsuf bfdev_arch_flsuf static __bfdev_always_inline unsigned int bfdev_arch_flsuf(unsigned long value) { @@ -413,6 +441,7 @@ bfdev_arch_flsuf(unsigned long value) * Undefined if no zero exists, so code should check against ~0UL first.. */ #ifndef bfdev_arch_ffzuf +# define bfdev_arch_ffzuf bfdev_arch_ffzuf static __bfdev_always_inline unsigned int bfdev_arch_ffzuf(unsigned long value) { @@ -426,6 +455,7 @@ bfdev_arch_ffzuf(unsigned long value) * Undefined if no zero exists, so code should check against ~0UL first.. */ #ifndef bfdev_arch_flzuf +# define bfdev_arch_flzuf bfdev_arch_flzuf static __bfdev_always_inline unsigned int bfdev_arch_flzuf(unsigned long value) { @@ -438,6 +468,7 @@ bfdev_arch_flzuf(unsigned long value) * @value: the word to search. */ #ifndef bfdev_arch_ffs +# define bfdev_arch_ffs bfdev_arch_ffs static __bfdev_always_inline unsigned int bfdev_arch_ffs(unsigned long value) { @@ -452,6 +483,7 @@ bfdev_arch_ffs(unsigned long value) * @value: the word to search. */ #ifndef bfdev_arch_fls +# define bfdev_arch_fls bfdev_arch_fls static __bfdev_always_inline unsigned int bfdev_arch_fls(unsigned long value) { @@ -466,6 +498,7 @@ bfdev_arch_fls(unsigned long value) * @value: The word to search. */ #ifndef bfdev_arch_ffz +# define bfdev_arch_ffz bfdev_arch_ffz static __bfdev_always_inline unsigned int bfdev_arch_ffz(unsigned long value) { @@ -480,6 +513,7 @@ bfdev_arch_ffz(unsigned long value) * @value: The word to search. */ #ifndef bfdev_arch_flz +# define bfdev_arch_flz bfdev_arch_flz static __bfdev_always_inline unsigned int bfdev_arch_flz(unsigned long value) { @@ -494,6 +528,7 @@ bfdev_arch_flz(unsigned long value) * @value: The word to search. */ #ifndef bfdev_arch_ctz +# define bfdev_arch_ctz bfdev_arch_ctz static __bfdev_always_inline unsigned int bfdev_arch_ctz(unsigned long value) { @@ -510,6 +545,7 @@ bfdev_arch_ctz(unsigned long value) * @value: The word to search. */ #ifndef bfdev_arch_clz +# define bfdev_arch_clz bfdev_arch_clz static __bfdev_always_inline unsigned int bfdev_arch_clz(unsigned long value) { @@ -522,6 +558,7 @@ bfdev_arch_clz(unsigned long value) #endif #ifndef bfdev_arch_ffns +# define bfdev_arch_ffns bfdev_arch_ffns static __bfdev_always_inline unsigned int bfdev_arch_ffnsp(unsigned long word, unsigned int *nr) { @@ -542,6 +579,7 @@ bfdev_arch_ffnsp(unsigned long word, unsigned int *nr) #endif #ifndef bfdev_arch_flns +# define bfdev_arch_flns bfdev_arch_flns static __bfdev_always_inline unsigned int bfdev_arch_flnsp(unsigned long word, unsigned int *nr) { @@ -562,6 +600,7 @@ bfdev_arch_flnsp(unsigned long word, unsigned int *nr) #endif #ifndef bfdev_arch_ffnz +# define bfdev_arch_ffnz bfdev_arch_ffnz static __bfdev_always_inline unsigned int bfdev_arch_ffnzp(unsigned long word, unsigned int *nr) { @@ -570,6 +609,7 @@ bfdev_arch_ffnzp(unsigned long word, unsigned int *nr) #endif #ifndef bfdev_arch_flnz +# define bfdev_arch_flnz bfdev_arch_flnz static __bfdev_always_inline unsigned int bfdev_arch_flnzp(unsigned long word, unsigned int *nr) { diff --git a/include/bfdev/asm-generic/dword.h b/include/bfdev/asm-generic/dword.h index 7ec4edd1..01c58599 100644 --- a/include/bfdev/asm-generic/dword.h +++ b/include/bfdev/asm-generic/dword.h @@ -111,7 +111,7 @@ BFDEV_BEGIN_DECLS if (__r1 >= __div) { \ if (__r1 < __m) { \ __q1--; \ - __r1 += (__div); \ + __r1 += __div; \ } \ } \ } \ @@ -124,7 +124,7 @@ BFDEV_BEGIN_DECLS \ if (__r0 < __m) { \ __q0--; \ - __r0 += (__div); \ + __r0 += __div; \ \ if (__r0 >= __div) { \ if (__r0 < __m) { \ diff --git a/include/bfdev/asm-generic/rwonce.h b/include/bfdev/asm-generic/rwonce.h index befec78f..a98da8e2 100644 --- a/include/bfdev/asm-generic/rwonce.h +++ b/include/bfdev/asm-generic/rwonce.h @@ -10,13 +10,17 @@ BFDEV_BEGIN_DECLS -#define BFDEV_READ_ONCE(x) ({ \ +#ifndef BFDEV_READ_ONCE +# define BFDEV_READ_ONCE(x) ({ \ *(volatile typeof(x) *)&(x); \ }) +#endif -#define BFDEV_WRITE_ONCE(x, val) ({ \ +#ifndef BFDEV_WRITE_ONCE +# define BFDEV_WRITE_ONCE(x, val) ({ \ *(volatile typeof(x) *)&(x) = (val); \ }) +#endif BFDEV_END_DECLS diff --git a/include/bfdev/asm-generic/unaligned.h b/include/bfdev/asm-generic/unaligned.h index 659fb395..ecb744df 100644 --- a/include/bfdev/asm-generic/unaligned.h +++ b/include/bfdev/asm-generic/unaligned.h @@ -39,6 +39,7 @@ BFDEV_BEGIN_DECLS #endif #ifndef bfdev_arch_unaligned_get_uint +# define bfdev_arch_unaligned_get_uint bfdev_arch_unaligned_get_uint static __bfdev_always_inline unsigned int bfdev_arch_unaligned_get_uint(const void *p) { @@ -47,6 +48,7 @@ bfdev_arch_unaligned_get_uint(const void *p) #endif #ifndef bfdev_arch_unaligned_get_ulong +# define bfdev_arch_unaligned_get_ulong bfdev_arch_unaligned_get_ulong static __bfdev_always_inline unsigned long bfdev_arch_unaligned_get_ulong(const void *p) { @@ -55,6 +57,7 @@ bfdev_arch_unaligned_get_ulong(const void *p) #endif #ifndef bfdev_arch_unaligned_set_uint +# define bfdev_arch_unaligned_set_uint bfdev_arch_unaligned_set_uint static __bfdev_always_inline void bfdev_arch_unaligned_set_uint(void *p, unsigned int val) { @@ -63,6 +66,7 @@ bfdev_arch_unaligned_set_uint(void *p, unsigned int val) #endif #ifndef bfdev_arch_unaligned_set_ulong +# define bfdev_arch_unaligned_set_ulong bfdev_arch_unaligned_set_ulong static __bfdev_always_inline void bfdev_arch_unaligned_set_ulong(void *p, unsigned long val) { @@ -71,6 +75,7 @@ bfdev_arch_unaligned_set_ulong(void *p, unsigned long val) #endif #ifndef bfdev_arch_unaligned_get_u16 +# define bfdev_arch_unaligned_get_u16 bfdev_arch_unaligned_get_u16 static __bfdev_always_inline uint16_t bfdev_arch_unaligned_get_u16(const void *p) { @@ -79,6 +84,7 @@ bfdev_arch_unaligned_get_u16(const void *p) #endif #ifndef bfdev_arch_unaligned_get_u32 +# define bfdev_arch_unaligned_get_u32 bfdev_arch_unaligned_get_u32 static __bfdev_always_inline uint32_t bfdev_arch_unaligned_get_u32(const void *p) { @@ -87,6 +93,7 @@ bfdev_arch_unaligned_get_u32(const void *p) #endif #ifndef bfdev_arch_unaligned_get_u64 +# define bfdev_arch_unaligned_get_u64 bfdev_arch_unaligned_get_u64 static __bfdev_always_inline uint64_t bfdev_arch_unaligned_get_u64(const void *p) { @@ -95,6 +102,7 @@ bfdev_arch_unaligned_get_u64(const void *p) #endif #ifndef bfdev_arch_unaligned_set_u16 +# define bfdev_arch_unaligned_set_u16 bfdev_arch_unaligned_set_u16 static __bfdev_always_inline void bfdev_arch_unaligned_set_u16(void *p, uint16_t val) { @@ -103,6 +111,7 @@ bfdev_arch_unaligned_set_u16(void *p, uint16_t val) #endif #ifndef bfdev_arch_unaligned_set_u32 +# define bfdev_arch_unaligned_set_u32 bfdev_arch_unaligned_set_u32 static __bfdev_always_inline void bfdev_arch_unaligned_set_u32(void *p, uint32_t val) { @@ -111,6 +120,7 @@ bfdev_arch_unaligned_set_u32(void *p, uint32_t val) #endif #ifndef bfdev_arch_unaligned_set_u64 +# define bfdev_arch_unaligned_set_u64 bfdev_arch_unaligned_set_u64 static __bfdev_always_inline void bfdev_arch_unaligned_set_u64(void *p, uint64_t val) { @@ -119,6 +129,7 @@ bfdev_arch_unaligned_set_u64(void *p, uint64_t val) #endif #ifndef bfdev_arch_unaligned_get_le16 +# define bfdev_arch_unaligned_get_le16 bfdev_arch_unaligned_get_le16 static __bfdev_always_inline uint16_t bfdev_arch_unaligned_get_le16(const void *p) { @@ -127,6 +138,7 @@ bfdev_arch_unaligned_get_le16(const void *p) #endif #ifndef bfdev_arch_unaligned_get_le32 +# define bfdev_arch_unaligned_get_le32 bfdev_arch_unaligned_get_le32 static __bfdev_always_inline uint32_t bfdev_arch_unaligned_get_le32(const void *p) { @@ -135,6 +147,7 @@ bfdev_arch_unaligned_get_le32(const void *p) #endif #ifndef bfdev_arch_unaligned_get_le64 +# define bfdev_arch_unaligned_get_le64 bfdev_arch_unaligned_get_le64 static __bfdev_always_inline uint64_t bfdev_arch_unaligned_get_le64(const void *p) { @@ -143,6 +156,7 @@ bfdev_arch_unaligned_get_le64(const void *p) #endif #ifndef bfdev_arch_unaligned_set_le16 +# define bfdev_arch_unaligned_set_le16 bfdev_arch_unaligned_set_le16 static __bfdev_always_inline void bfdev_arch_unaligned_set_le16(void *p, uint16_t val) { @@ -151,6 +165,7 @@ bfdev_arch_unaligned_set_le16(void *p, uint16_t val) #endif #ifndef bfdev_arch_unaligned_set_le32 +# define bfdev_arch_unaligned_set_le32 bfdev_arch_unaligned_set_le32 static __bfdev_always_inline void bfdev_arch_unaligned_set_le32(void *p, uint32_t val) { @@ -159,6 +174,7 @@ bfdev_arch_unaligned_set_le32(void *p, uint32_t val) #endif #ifndef bfdev_arch_unaligned_set_le64 +# define bfdev_arch_unaligned_set_le64 bfdev_arch_unaligned_set_le64 static __bfdev_always_inline void bfdev_arch_unaligned_set_le64(void *p, uint64_t val) { @@ -167,6 +183,7 @@ bfdev_arch_unaligned_set_le64(void *p, uint64_t val) #endif #ifndef bfdev_arch_unaligned_get_be16 +# define bfdev_arch_unaligned_get_be16 bfdev_arch_unaligned_get_be16 static __bfdev_always_inline uint16_t bfdev_arch_unaligned_get_be16(const void *p) { @@ -175,6 +192,7 @@ bfdev_arch_unaligned_get_be16(const void *p) #endif #ifndef bfdev_arch_unaligned_get_be32 +# define bfdev_arch_unaligned_get_be32 bfdev_arch_unaligned_get_be32 static __bfdev_always_inline uint32_t bfdev_arch_unaligned_get_be32(const void *p) { @@ -183,6 +201,7 @@ bfdev_arch_unaligned_get_be32(const void *p) #endif #ifndef bfdev_arch_unaligned_get_be64 +# define bfdev_arch_unaligned_get_be64 bfdev_arch_unaligned_get_be64 static __bfdev_always_inline uint64_t bfdev_arch_unaligned_get_be64(const void *p) { @@ -191,6 +210,7 @@ bfdev_arch_unaligned_get_be64(const void *p) #endif #ifndef bfdev_arch_unaligned_set_be16 +# define bfdev_arch_unaligned_set_be16 bfdev_arch_unaligned_set_be16 static __bfdev_always_inline void bfdev_arch_unaligned_set_be16(void *p, uint16_t val) { @@ -199,6 +219,7 @@ bfdev_arch_unaligned_set_be16(void *p, uint16_t val) #endif #ifndef bfdev_arch_unaligned_set_be32 +# define bfdev_arch_unaligned_set_be32 bfdev_arch_unaligned_set_be32 static __bfdev_always_inline void bfdev_arch_unaligned_set_be32(void *p, uint32_t val) { @@ -207,6 +228,7 @@ bfdev_arch_unaligned_set_be32(void *p, uint32_t val) #endif #ifndef bfdev_arch_unaligned_set_be64 +# define bfdev_arch_unaligned_set_be64 bfdev_arch_unaligned_set_be64 static __bfdev_always_inline void bfdev_arch_unaligned_set_be64(void *p, uint64_t val) { diff --git a/include/bfdev/bits.h b/include/bfdev/bits.h index cf6fa46b..642e0d86 100644 --- a/include/bfdev/bits.h +++ b/include/bfdev/bits.h @@ -29,6 +29,7 @@ BFDEV_BEGIN_DECLS /** * BFDEV_BIT_LOW_MASK - create a low position mask. * @nbits: mask length. + * * For example: * BFDEV_BIT_LOW_MASK(8) gives us the vector 0x000000ff. */ @@ -40,6 +41,7 @@ BFDEV_BEGIN_DECLS /** * BFDEV_BIT_HIGH_MASK - create a high position mask. * @nbits: mask length. + * * For example: * BFDEV_BIT_HIGH_MASK(8) gives us the vector 0xffffff00. */ diff --git a/include/bfdev/bitwalk-comp.h b/include/bfdev/bitwalk-comp.h new file mode 100644 index 00000000..78476731 --- /dev/null +++ b/include/bfdev/bitwalk-comp.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright(c) 2024 John Sanpe + */ + +#ifndef _BFDEV_BITWALK_COMP_H_ +#define _BFDEV_BITWALK_COMP_H_ + +#include +#include +#include + +BFDEV_BEGIN_DECLS + +extern unsigned int +bfdev_comp_find_first_bit(const unsigned long *block, + unsigned int bits, 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); + +extern unsigned int +bfdev_comp_find_next_bit(const unsigned long *addr1, const unsigned long *addr2, + unsigned int bits, unsigned int start, + unsigned long invert, bool swap); + +extern unsigned int +bfdev_comp_find_prev_bit(const unsigned long *addr1, const unsigned long *addr2, + unsigned int bits, unsigned int start, + unsigned long invert, bool swap); + +BFDEV_END_DECLS + +#endif /* _BFDEV_BITWALK_COMP_H_ */ diff --git a/include/bfdev/bitwalk.h b/include/bfdev/bitwalk.h index be7eaf2b..b9ef2b46 100644 --- a/include/bfdev/bitwalk.h +++ b/include/bfdev/bitwalk.h @@ -10,61 +10,18 @@ #include #include #include +#include BFDEV_BEGIN_DECLS /** - * bfdev_comp_find_first_bit - complex find first bit in a region. + * bfdev_find_first_bit() - complex find first bit in a region. * @block: the block to find. * @bits: number of bits in the block. - * @swap: byte swap in the block. + * + * Returns the bit number of the first set bit. + * If no bits are set, returns @bits. */ -extern unsigned int -bfdev_comp_find_first_bit(const unsigned long *block, unsigned int bits, bool swap); - -/** - * bfdev_comp_find_last_bit - complex find last bit in a region. - * @block: the block to find. - * @bits: number of bits in the block. - * @swap: byte swap in the block. - */ -extern unsigned int -bfdev_comp_find_last_bit(const unsigned long *block, unsigned int bits, bool swap); - -/** - * bfdev_comp_find_first_zero - complex find first zero in a region. - * @block: the block to find. - * @bits: number of bits in the block. - * @swap: byte swap in the block. - */ -extern unsigned int -bfdev_comp_find_first_zero(const unsigned long *block, unsigned int bits, bool swap); - -/** - * bfdev_comp_find_last_zero - complex find last zero in a region. - * @block: the block to find. - * @bits: number of bits in the block. - * @swap: byte swap in the block. - */ -extern unsigned int -bfdev_comp_find_last_zero(const unsigned long *block, unsigned int bits, bool swap); - -/** - * bfdev_comp_find_last_zero - complex find last zero in a region. - * @block: the block to find. - * @bits: number of bits in the block. - * @swap: byte swap in the block. - */ -extern unsigned int -bfdev_comp_find_next_bit(const unsigned long *addr1, const unsigned long *addr2, - unsigned int bits, unsigned int start, - unsigned long invert, bool swap); - -extern unsigned int -bfdev_comp_find_prev_bit(const unsigned long *addr1, const unsigned long *addr2, - unsigned int bits, unsigned int start, - unsigned long invert, bool swap); - #ifndef bfdev_find_first_bit static inline unsigned int bfdev_find_first_bit(const unsigned long *addr, unsigned int bits) @@ -87,6 +44,14 @@ bfdev_find_last_bit(const unsigned long *addr, unsigned int bits) } #endif +/** + * bfdev_comp_find_first_zero - find first zero in a region. + * @block: the block to find. + * @bits: number of bits in the block. + * + * Returns the bit number of the first cleared bit. + * If no bits are zero, returns @bits. + */ #ifndef bfdev_find_first_zero static inline unsigned int bfdev_find_first_zero(const unsigned long *addr, unsigned int bits) @@ -109,18 +74,28 @@ bfdev_find_last_zero(const unsigned long *addr, unsigned int bits) } #endif +/** + * bfdev_find_next_bit() - find next bit in a region. + * @block: the block to find. + * @bits: number of bits in the block. + * @offset: The bitnumber to start searching at. + * + * Returns the bit number for the next set bit + * If no bits are set, returns @bits. + */ #ifndef bfdev_find_next_bit static inline unsigned int -bfdev_find_next_bit(const unsigned long *addr, unsigned int bits, unsigned int offset) +bfdev_find_next_bit(const unsigned long *addr, + unsigned int bits, unsigned int offset) { - if (bfdev_const_small_nbits(bits)) { - unsigned long val; + unsigned long value; + if (bfdev_const_small_nbits(bits)) { if (bfdev_unlikely(offset >= bits)) return bits; - val = *addr & BFDEV_BIT_RANGE(bits - 1, offset); - return val ? bfdev_ffsuf(val) : bits; + value = *addr & BFDEV_BIT_RANGE(bits - 1, offset); + return value ? bfdev_ffsuf(value) : bits; } return bfdev_comp_find_next_bit(addr, NULL, bits, offset, 0UL, false); @@ -129,34 +104,45 @@ bfdev_find_next_bit(const unsigned long *addr, unsigned int bits, unsigned int o #ifndef bfdev_find_prev_bit static inline unsigned int -bfdev_find_prev_bit(const unsigned long *addr, unsigned int bits, unsigned int offset) +bfdev_find_prev_bit(const unsigned long *addr, + unsigned int bits, unsigned int offset) { - if (bfdev_const_small_nbits(bits)) { - unsigned long val; + unsigned long value; + if (bfdev_const_small_nbits(bits)) { if (bfdev_unlikely(offset >= bits)) return bits; - val = *addr & BFDEV_BIT_RANGE(bits - 1, offset); - return val ? bfdev_flsuf(val) : bits; + value = *addr & BFDEV_BIT_RANGE(bits - 1, offset); + return value ? bfdev_flsuf(value) : bits; } return bfdev_comp_find_prev_bit(addr, NULL, bits, offset, 0UL, false); } #endif +/** + * bfdev_find_next_bit() - find next zero in a region. + * @block: the block to find. + * @bits: number of bits in the block. + * @offset: the bitnumber to start searching at. + * + * Returns the bit number for the next set bit + * If no bits are set, returns @bits. + */ #ifndef bfdev_find_next_zero static inline unsigned int -bfdev_find_next_zero(const unsigned long *addr, unsigned int bits, unsigned int offset) +bfdev_find_next_zero(const unsigned long *addr, + unsigned int bits, unsigned int offset) { - if (bfdev_const_small_nbits(bits)) { - unsigned long val; + unsigned long value; + if (bfdev_const_small_nbits(bits)) { if (bfdev_unlikely(offset >= bits)) return bits; - val = *addr | ~BFDEV_BIT_RANGE(bits - 1, offset); - return val ? bfdev_ffzuf(val) : bits; + value = *addr | ~BFDEV_BIT_RANGE(bits - 1, offset); + return value ? bfdev_ffzuf(value) : bits; } return bfdev_comp_find_next_bit(addr, NULL, bits, offset, ~0UL, false); @@ -165,35 +151,46 @@ bfdev_find_next_zero(const unsigned long *addr, unsigned int bits, unsigned int #ifndef bfdev_find_prev_zero static inline unsigned int -bfdev_find_prev_zero(const unsigned long *addr, unsigned int bits, unsigned int offset) +bfdev_find_prev_zero(const unsigned long *addr, + unsigned int bits, unsigned int offset) { - if (bfdev_const_small_nbits(bits)) { - unsigned long val; + unsigned long value; + if (bfdev_const_small_nbits(bits)) { if (bfdev_unlikely(offset >= bits)) return bits; - val = *addr | ~BFDEV_BIT_RANGE(bits - 1, offset); - return val ? bfdev_flzuf(val) : bits; + value = *addr | ~BFDEV_BIT_RANGE(bits - 1, offset); + return value ? bfdev_flzuf(value) : bits; } return bfdev_comp_find_prev_bit(addr, NULL, bits, offset, ~0UL, false); } #endif +/** + * bfdev_find_next_and_bit() - find the next set bit in both memory regions. + * @addr1: the first address to base the search on. + * @addr2: the second address to base the search on. + * @bits: number of bits in the block. + * @offset: the bitnumber to start searching at. + * + * Returns the bit number for the next set bit, or first set bit up to @offset + * If no bits are set, returns @bits. + */ #ifndef bfdev_find_next_and_bit static inline unsigned int bfdev_find_next_and_bit(const unsigned long *addr1, const unsigned long *addr2, unsigned int bits, unsigned int offset) { - if (bfdev_const_small_nbits(bits)) { - unsigned long val; + unsigned long value; + if (bfdev_const_small_nbits(bits)) { if (bfdev_unlikely(offset >= bits)) return bits; - val = *addr1 & *addr2 & BFDEV_BIT_RANGE(bits - 1, offset); - return val ? bfdev_ffsuf(val) : bits; + value = *addr1 & *addr2 & BFDEV_BIT_RANGE(bits - 1, offset); + return value ? bfdev_ffsuf(value) : bits; } return bfdev_comp_find_next_bit(addr1, addr2, bits, offset, 0UL, false); @@ -205,14 +202,14 @@ static inline unsigned int bfdev_find_prev_and_bit(const unsigned long *addr1, const unsigned long *addr2, unsigned int bits, unsigned int offset) { - if (bfdev_const_small_nbits(bits)) { - unsigned long val; + unsigned long value; + if (bfdev_const_small_nbits(bits)) { if (bfdev_unlikely(offset >= bits)) return bits; - val = *addr1 & *addr2 & BFDEV_BIT_RANGE(bits - 1, offset); - return val ? bfdev_flsuf(val) : bits; + value = *addr1 & *addr2 & BFDEV_BIT_RANGE(bits - 1, offset); + return value ? bfdev_flsuf(value) : bits; } return bfdev_comp_find_prev_bit(addr1, addr2, bits, offset, 0UL, false); diff --git a/include/bfdev/btree.h b/include/bfdev/btree.h index 8433551c..0cf037b5 100644 --- a/include/bfdev/btree.h +++ b/include/bfdev/btree.h @@ -14,6 +14,11 @@ BFDEV_BEGIN_DECLS +typedef struct bfdev_btree_layout bfdev_btree_layout_t; +typedef struct bfdev_btree_node bfdev_btree_node_t; +typedef struct bfdev_btree_root bfdev_btree_root_t; +typedef struct bfdev_btree_ops bfdev_btree_ops_t; + struct bfdev_btree_layout { unsigned int keylen; unsigned int keynum; @@ -27,95 +32,87 @@ struct bfdev_btree_node { struct bfdev_btree_root { const bfdev_alloc_t *alloc; - struct bfdev_btree_layout *layout; - struct bfdev_btree_node *node; + bfdev_btree_layout_t *layout; + bfdev_btree_node_t *node; unsigned int height; - const struct bfdev_btree_ops *ops; + const bfdev_btree_ops_t *ops; void *pdata; }; struct bfdev_btree_ops { - void *(*alloc)(struct bfdev_btree_root *root); - void (*free)(struct bfdev_btree_root *root, void *block); - long (*find)(struct bfdev_btree_root *root, uintptr_t *node, uintptr_t *key); - int (*clash)(struct bfdev_btree_root *root, void *clash, void *value); - void *(*remove)(struct bfdev_btree_root *root, void *value); + void *(*alloc)(bfdev_btree_root_t *root); + void (*free)(bfdev_btree_root_t *root, void *block); + long (*find)(bfdev_btree_root_t *root, uintptr_t *node, uintptr_t *key); + int (*clash)(bfdev_btree_root_t *root, void *clash, void *value); + void *(*remove)(bfdev_btree_root_t *root, void *value); }; -#define BFDEV_BTREE_STATIC(LAYOUT, OPS, PDATA) \ - {.layout = (LAYOUT), .ops = (OPS), .pdata = (PDATA)} +#define BFDEV_BTREE_STATIC(LAYOUT, OPS, PDATA) { \ + .layout = (LAYOUT), .ops = (OPS), .pdata = (PDATA), \ +} #define BFDEV_BTREE_INIT(layout, ops, pdata) \ - (struct bfdev_btree_root) BFDEV_BTREE_STATIC(layout, ops, pdata) + (bfdev_btree_root_t) BFDEV_BTREE_STATIC(layout, ops, pdata) #define BFDEV_BTREE_ROOT(name, layout, ops, pdata) \ - struct bfdev_btree_root name = BFDEV_BTREE_INIT(layout, ops, pdata) + bfdev_btree_root_t name = BFDEV_BTREE_INIT(layout, ops, pdata) -extern struct bfdev_btree_layout +extern bfdev_btree_layout_t bfdev_btree_layout32; -extern struct bfdev_btree_layout +extern bfdev_btree_layout_t bfdev_btree_layout64; -extern struct bfdev_btree_layout +extern bfdev_btree_layout_t bfdev_btree_layoutptr; static inline void -bfdev_btree_init(struct bfdev_btree_root *root, - struct bfdev_btree_layout *layout, - struct bfdev_btree_ops *ops, void *pdata) +bfdev_btree_init(bfdev_btree_root_t *root, bfdev_btree_layout_t *layout, + bfdev_btree_ops_t *ops, void *pdata) { *root = BFDEV_BTREE_INIT(layout, ops, pdata); } extern long -bfdev_btree_key_find(struct bfdev_btree_root *root, - uintptr_t *node, uintptr_t *key); +bfdev_btree_key_find(bfdev_btree_root_t *root, uintptr_t *node, uintptr_t *key); + +extern void +bfdev_btree_key_copy(bfdev_btree_root_t *root, uintptr_t *dest, uintptr_t *src); extern void * -bfdev_btree_alloc(struct bfdev_btree_root *root); +bfdev_btree_alloc(bfdev_btree_root_t *root); extern void -bfdev_btree_free(struct bfdev_btree_root *root, void *node); +bfdev_btree_free(bfdev_btree_root_t *root, void *node); extern void * -bfdev_btree_lookup(struct bfdev_btree_root *root, uintptr_t *key); +bfdev_btree_lookup(bfdev_btree_root_t *root, uintptr_t *key); extern int -bfdev_btree_update(struct bfdev_btree_root *root, - uintptr_t *key, void *value); +bfdev_btree_update(bfdev_btree_root_t *root, uintptr_t *key, void *value); extern int -bfdev_btree_insert(struct bfdev_btree_root *root, - uintptr_t *key, void *value); +bfdev_btree_insert(bfdev_btree_root_t *root, uintptr_t *key, void *value); extern void * -bfdev_btree_remove(struct bfdev_btree_root *root, - uintptr_t *key); - -extern void -bfdev_btree_destroy(struct bfdev_btree_root *root); +bfdev_btree_remove(bfdev_btree_root_t *root, uintptr_t *key); extern void -bfdev_btree_key_copy(struct bfdev_btree_root *root, - uintptr_t *dest, uintptr_t *src); +bfdev_btree_release(bfdev_btree_root_t *root, bfdev_release_t release, + void *pdata); extern void * -bfdev_btree_first(struct bfdev_btree_root *root, - uintptr_t *key); +bfdev_btree_first(bfdev_btree_root_t *root, uintptr_t *key); extern void * -bfdev_btree_last(struct bfdev_btree_root *root, - uintptr_t *key); +bfdev_btree_last(bfdev_btree_root_t *root, uintptr_t *key); extern void * -bfdev_btree_next(struct bfdev_btree_root *root, - uintptr_t *key); +bfdev_btree_next(bfdev_btree_root_t *root, uintptr_t *key); extern void * -bfdev_btree_prev(struct bfdev_btree_root *root, - uintptr_t *key); +bfdev_btree_prev(bfdev_btree_root_t *root, uintptr_t *key); /** * bfdev_btree_for_each - iterate over a btree. diff --git a/include/bfdev/circle.h b/include/bfdev/circle.h index e64f75db..8f399623 100644 --- a/include/bfdev/circle.h +++ b/include/bfdev/circle.h @@ -18,6 +18,16 @@ struct bfdev_circle { unsigned long tail; }; +#define BFDEV_CIRCLE_STATIC(BUFFER) { \ + .buffer = (BUFFER), \ +} + +#define BFDEV_CIRCLE_INIT(buffer) \ + (bfdev_circle_t) BFDEV_CIRCLE_STATIC(buffer) + +#define BFDEV_DEFINE_CIRCLE(name, buffer) \ + bfdev_circle_t name = BFDEV_CIRCLE_INIT(buffer) + /* Return count in buffer */ #define BFDEV_CIRCLE_CNT(head, tail, size) \ (((head) - (tail)) & ((size) - 1)) diff --git a/include/bfdev/compiler/types.h b/include/bfdev/compiler/types.h index dc95db58..fdfe5f3c 100644 --- a/include/bfdev/compiler/types.h +++ b/include/bfdev/compiler/types.h @@ -6,6 +6,10 @@ #ifndef _BFDEV_COMPILER_TYPES_H_ #define _BFDEV_COMPILER_TYPES_H_ +#include + +BFDEV_BEGIN_DECLS + /* Indirect macros required for expanded argument pasting, eg. __LINE__. */ #define ___BFDEV_PASTE(a,b) a##b #define __BFDEV_PASTE(a,b) ___BFDEV_PASTE(a,b) @@ -13,4 +17,6 @@ /* Attributes */ #include +BFDEV_END_DECLS + #endif /* _BFDEV_COMPILER_TYPES_H_ */ diff --git a/include/bfdev/container.h b/include/bfdev/container.h index ccbd7722..ba9ea8dc 100644 --- a/include/bfdev/container.h +++ b/include/bfdev/container.h @@ -7,25 +7,38 @@ #define _BFDEV_CONTAINER_H_ #include +#include BFDEV_BEGIN_DECLS /** - * bfdev_container_of - cast a member of a structure out to the containing structure. + * bfdev_container_of() - cast a member of a structure out to the containing structure. * @ptr: the pointer to the member. * @type: the type of the container struct this is embedded in. * @member: the name of the member within the struct. */ -#define bfdev_container_of(ptr, type, member) ({ \ - const typeof(((type *)0)->member) *__mptr = (ptr); \ - (type *)((char *)__mptr - offsetof(type,member)); \ + +/* 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)); \ }) -#define bfdev_container_of_safe(ptr, type, member) ({ \ - typeof(ptr) _ptr = (ptr); \ - _ptr ? bfdev_container_of(_ptr, type, member) : NULL; \ +/* If ptr is NULL, ptr is returned unchanged. */ +#define bfdev_container_of_safe(ptr, type, member) ({ \ + typeof(ptr) __ptr = (ptr); \ + __ptr ? bfdev_container_of(__ptr, type, member) : NULL; \ }) +/* Preserve the const-ness of the pointer. */ +#define bfdev_container_of_const(ptr, type, member) \ +_Generic(ptr, \ + const typeof(*(ptr)) *: \ + ((const type *)bfdev_container_of(ptr, type, member)), \ + default: \ + ((type *)bfdev_container_of(ptr, type, member)) \ +) + BFDEV_END_DECLS #endif /* _BFDEV_CONTAINER_H_ */ diff --git a/include/bfdev/fifo.h b/include/bfdev/fifo.h index 18c7e7af..a9fa1762 100644 --- a/include/bfdev/fifo.h +++ b/include/bfdev/fifo.h @@ -11,6 +11,8 @@ #include #include +BFDEV_BEGIN_DECLS + struct bfdev_fifo { const bfdev_alloc_t *alloc; unsigned long in; @@ -197,10 +199,10 @@ struct bfdev_fifo { #define bfdev_fifo_initialized(ptr) ((ptr)->fifo.mask) /** - * bfdev_fifo_recsize - get the size of the record length fie. - * @ptr: pointer of the fifo to get __recsi. + * bfdev_fifo_recsize - get the size of the record length field. + * @ptr: pointer of the fifo to get field length. */ -#define bfdev_fifo_recsize(ptr) (sizeof(*(ptr)->rectyp)) +#define bfdev_fifo_recsize(ptr) (sizeof(*(ptr)->rectype)) /** * bfdev_fifo_size - get the size of the element managed by the fifo. @@ -425,13 +427,37 @@ struct bfdev_fifo { bfdev_fifo_in_flat(__fifo, __tbuff, __tlen); \ }) -extern unsigned long bfdev_fifo_peek_flat(struct bfdev_fifo *fifo, void *buff, unsigned long len); -extern unsigned long bfdev_fifo_out_flat(struct bfdev_fifo *fifo, void *buff, unsigned long len); -extern unsigned long bfdev_fifo_in_flat(struct bfdev_fifo *fifo, const void *buff, unsigned long len); -extern unsigned long bfdev_fifo_peek_record(struct bfdev_fifo *fifo, void *buff, unsigned long len, unsigned long record); -extern unsigned long bfdev_fifo_out_record(struct bfdev_fifo *fifo, void *buff, unsigned long len, unsigned long record); -extern unsigned long bfdev_fifo_in_record(struct bfdev_fifo *fifo, const void *buff, unsigned long len, unsigned long record); -extern int bfdev_fifo_dynamic_alloc(struct bfdev_fifo *fifo, const bfdev_alloc_t *alloc, size_t esize, size_t size); -extern void bfdev_fifo_dynamic_free(struct bfdev_fifo *fifo); +extern unsigned long +bfdev_fifo_peek_flat(struct bfdev_fifo *fifo, void *buff, + unsigned long len); + +extern unsigned long +bfdev_fifo_out_flat(struct bfdev_fifo *fifo, void *buff, + unsigned long len); + +extern unsigned long +bfdev_fifo_in_flat(struct bfdev_fifo *fifo, const void *buff, + unsigned long len); + +extern unsigned long +bfdev_fifo_peek_record(struct bfdev_fifo *fifo, void *buff, + unsigned long len, unsigned long record); + +extern unsigned long +bfdev_fifo_out_record(struct bfdev_fifo *fifo, void *buff, + unsigned long len, unsigned long record); + +extern unsigned long +bfdev_fifo_in_record(struct bfdev_fifo *fifo, const void *buff, + unsigned long len, unsigned long record); + +extern int +bfdev_fifo_dynamic_alloc(struct bfdev_fifo *fifo, const bfdev_alloc_t *alloc, + size_t esize, size_t size); + +extern void +bfdev_fifo_dynamic_free(struct bfdev_fifo *fifo); + +BFDEV_END_DECLS #endif /* _BFDEV_FIFO_H_ */ diff --git a/include/bfdev/fsm.h b/include/bfdev/fsm.h index b5f61554..5b17b791 100644 --- a/include/bfdev/fsm.h +++ b/include/bfdev/fsm.h @@ -104,23 +104,76 @@ bfdev_fsm_reset(bfdev_fsm_t *fsm, const bfdev_fsm_state_t *init) bfdev_array_reset(&fsm->stack); } -static inline const bfdev_fsm_state_t * +/** + * bfdev_fsm_curr() - Get the current state. + * @fsm: the state machine to get the current state from. + * + * Return a pointer to the current state. + */ +static inline bfdev_fsm_state_t * bfdev_fsm_curr(bfdev_fsm_t *fsm) { - unsigned int count = fsm->count; - return fsm->state[count & (BFDEV_ARRAY_SIZE(fsm->state) - 1)]; + unsigned int count, index; + + count = fsm->count; + index = count & (BFDEV_ARRAY_SIZE(fsm->state) - 1); + + return (bfdev_fsm_state_t *)fsm->state[index]; } -static inline const bfdev_fsm_state_t * +/** + * bfdev_fsm_curr() - Get the previous state. + * @fsm: the state machine to get the current state from. + * + * Return a pointer to the previous state. + */ +static inline bfdev_fsm_state_t * bfdev_fsm_prev(const bfdev_fsm_t *fsm) { - unsigned int count = fsm->count - 1; - return fsm->state[count & (BFDEV_ARRAY_SIZE(fsm->state) - 1)]; + unsigned int count, index; + + count = fsm->count - 1; + index = count & (BFDEV_ARRAY_SIZE(fsm->state) - 1); + + return (bfdev_fsm_state_t *)fsm->state[index]; +} + +/** + * bfdev_fsm_finished() - Check if the state machine has stopped. + * @fsm: stateMachine the state machine to test. + * + * Return true if the state machine has reached a final state. + */ +static inline bool +bfdev_fsm_finished(bfdev_fsm_t *fsm) +{ + const bfdev_fsm_state_t *state; + bool retval; + + state = bfdev_fsm_curr(fsm); + retval = !state->tnum && !state->exception; + + return retval; } +/** + * bfdev_fsm_handle() - Pass an event to the state machine. + * @fsm: the state machine to pass an event to. + * @event: the event to be handled. + * + * Return the entry trigger return value of the error state. + */ extern int bfdev_fsm_error(bfdev_fsm_t *fsm, bfdev_fsm_event_t *event); +/** + * bfdev_fsm_handle() - Pass an event to the state machine. + * @fsm: the state machine to pass an event to. + * @event: the event to be handled. + * + * Return a positive value is bfdev_fsm_retval, + * otherwise an error has occurred. + */ extern int bfdev_fsm_handle(bfdev_fsm_t *fsm, bfdev_fsm_event_t *event); diff --git a/include/bfdev/hashtbl.h b/include/bfdev/hashtbl.h index 43ceed02..0934285f 100644 --- a/include/bfdev/hashtbl.h +++ b/include/bfdev/hashtbl.h @@ -23,7 +23,7 @@ BFDEV_BEGIN_DECLS #define BFDEV_DEFINE_HASHTBL(name, size) \ BFDEV_DECLARE_HASHTBL(name, size) = { \ [0 ... BFDEV_HASHTBL_CHECK(size) - 1] \ - = BFDEV_HLIST_HEAD_STATIC \ + = BFDEV_HLIST_HEAD_STATIC() \ } #define BFDEV_HASHTBL_BITS(size) bfdev_ilog2(size) diff --git a/include/bfdev/heap.h b/include/bfdev/heap.h index d028745a..95172cb5 100644 --- a/include/bfdev/heap.h +++ b/include/bfdev/heap.h @@ -28,14 +28,15 @@ struct bfdev_heap_root { unsigned long count; }; -#define BFDEV_HEAP_STATIC \ - {NULL, 0} +#define BFDEV_HEAP_STATIC() { \ + .node = NULL, .count = 0, \ +} -#define BFDEV_HEAP_INIT \ - (bfdev_heap_root_t) BFDEV_HEAP_STATIC +#define BFDEV_HEAP_INIT() \ + (bfdev_heap_root_t) BFDEV_HEAP_STATIC() #define BFDEV_HEAP_ROOT(name) \ - bfdev_heap_root_t name = BFDEV_HEAP_INIT + bfdev_heap_root_t name = BFDEV_HEAP_INIT() #define BFDEV_HEAP_ROOT_NODE(root) \ ((root)->node) @@ -78,7 +79,7 @@ BFDEV_CALLBACK_CMP( static inline void bfdev_heap_init(bfdev_heap_root_t *root) { - *root = BFDEV_HEAP_INIT; + *root = BFDEV_HEAP_INIT(); } static inline bool diff --git a/include/bfdev/hlist.h b/include/bfdev/hlist.h index 727f3a0f..fd7b83f5 100644 --- a/include/bfdev/hlist.h +++ b/include/bfdev/hlist.h @@ -26,20 +26,28 @@ struct bfdev_hlist_head { bfdev_hlist_node_t *node; }; -#define BFDEV_HLIST_HEAD_STATIC \ - {NULL} +#define BFDEV_HLIST_HEAD_STATIC() { \ + .node = NULL, \ +} -#define BFDEV_HLIST_HEAD_INIT \ - (bfdev_hlist_head_t) BFDEV_HLIST_HEAD_STATIC +#define BFDEV_HLIST_HEAD_INIT() \ + (bfdev_hlist_head_t) BFDEV_HLIST_HEAD_STATIC() #define BFDEV_HLIST_HEAD(name) \ - bfdev_hlist_head_t name = BFDEV_HLIST_HEAD_INIT + bfdev_hlist_head_t name = BFDEV_HLIST_HEAD_INIT() #ifdef BFDEV_DEBUG_HLIST -extern bool bfdev_hlist_check_head_add(bfdev_hlist_head_t *head, bfdev_hlist_node_t *newn); -extern bool bfdev_hlist_check_next_add(bfdev_hlist_node_t *next, bfdev_hlist_node_t *newn); -extern bool bfdev_hlist_check_prev_add(bfdev_hlist_node_t *prev, bfdev_hlist_node_t *newn); -extern bool bfdev_hlist_check_del(bfdev_hlist_node_t *node); +extern bool +bfdev_hlist_check_head_add(bfdev_hlist_head_t *head, bfdev_hlist_node_t *newn); + +extern bool +bfdev_hlist_check_next_add(bfdev_hlist_node_t *next, bfdev_hlist_node_t *newn); + +extern bool +bfdev_hlist_check_prev_add(bfdev_hlist_node_t *prev, bfdev_hlist_node_t *newn); + +extern bool +bfdev_hlist_check_del(bfdev_hlist_node_t *node); #endif /** @@ -49,7 +57,7 @@ extern bool bfdev_hlist_check_del(bfdev_hlist_node_t *node); static inline void bfdev_hlist_head_init(bfdev_hlist_head_t *head) { - head->node = NULL; + *head = BFDEV_HLIST_HEAD_INIT(); } /** diff --git a/include/bfdev/ilist.h b/include/bfdev/ilist.h index b5151fb7..2a2d293b 100644 --- a/include/bfdev/ilist.h +++ b/include/bfdev/ilist.h @@ -24,20 +24,20 @@ struct bfdev_ilist_node { bfdev_list_head_t index_list; }; -#define BFDEV_ILIST_HEAD_STATIC(name) \ - {BFDEV_LIST_HEAD_STATIC((name).node_list)} +#define BFDEV_ILIST_HEAD_STATIC(HEAD) { \ + .node_list = BFDEV_LIST_HEAD_STATIC(&(HEAD)->node_list), \ +} -#define BFDEV_ILIST_HEAD_INIT(name) \ - (bfdev_ilist_head_t) BFDEV_ILIST_HEAD_STATIC(name) +#define BFDEV_ILIST_HEAD_INIT(head) \ + (bfdev_ilist_head_t) BFDEV_ILIST_HEAD_STATIC(head) #define BFDEV_ILIST_HEAD(name) \ - bfdev_ilist_head_t name = BFDEV_ILIST_HEAD_STATIC(name) + bfdev_ilist_head_t name = BFDEV_ILIST_HEAD_STATIC(&name) -#define BFDEV_ILISI_NODE_INIT(name, index) \ - (bfdev_ilist_node_t) { \ - .node_list = BFDEV_LIST_HEAD_INIT((node).node_list), \ - .index_list = BFDEV_LIST_HEAD_INIT((node).index_list), \ - } +#define BFDEV_ILIST_NODE_INIT(node) (bfdev_ilist_node_t) { \ + .node_list = BFDEV_LIST_HEAD_INIT(&(node)->node_list), \ + .index_list = BFDEV_LIST_HEAD_INIT(&(node)->index_list), \ +} BFDEV_CALLBACK_CMP( bfdev_ilist_cmp_t, @@ -68,18 +68,17 @@ bfdev_ilist_del(bfdev_ilist_head_t *ihead, bfdev_ilist_node_t *inode); static inline void bfdev_ilist_head_init(bfdev_ilist_head_t *ihead) { - bfdev_list_head_init(&ihead->node_list); + *ihead = BFDEV_ILIST_HEAD_INIT(ihead); } /** * bfdev_ilist_node_init() - initialize a bfdev_ilist_node structure. - * @head: bfdev_ilist_node structure to be initialized. + * @inode: bfdev_ilist_node structure to be initialized. */ static inline void bfdev_ilist_node_init(bfdev_ilist_node_t *inode) { - bfdev_list_head_init(&inode->node_list); - bfdev_list_head_init(&inode->index_list); + *inode = BFDEV_ILIST_NODE_INIT(inode); } /** diff --git a/include/bfdev/list.h b/include/bfdev/list.h index 754e25e2..db48857e 100644 --- a/include/bfdev/list.h +++ b/include/bfdev/list.h @@ -21,14 +21,15 @@ struct bfdev_list_head { bfdev_list_head_t *next; }; -#define BFDEV_LIST_HEAD_STATIC(name) \ - {&(name), &(name)} +#define BFDEV_LIST_HEAD_STATIC(HEAD) { \ + .prev = (HEAD), .next = (HEAD), \ +} -#define BFDEV_LIST_HEAD_INIT(name) \ - (bfdev_list_head_t) BFDEV_LIST_HEAD_STATIC(name) +#define BFDEV_LIST_HEAD_INIT(head) \ + (bfdev_list_head_t) BFDEV_LIST_HEAD_STATIC(head) #define BFDEV_LIST_HEAD(name) \ - bfdev_list_head_t name = BFDEV_LIST_HEAD_INIT(name) + bfdev_list_head_t name = BFDEV_LIST_HEAD_INIT(&name) BFDEV_CALLBACK_CMP( bfdev_list_cmp_t, @@ -70,8 +71,7 @@ bfdev_list_insert(bfdev_list_head_t *prev, bfdev_list_head_t *next, static inline void bfdev_list_head_init(bfdev_list_head_t *head) { - head->prev = head; - head->next = head; + *head = BFDEV_LIST_HEAD_INIT(head); } /** @@ -386,9 +386,9 @@ bfdev_list_splice_tail_init(bfdev_list_head_t *head, bfdev_list_head_t *list) * @member: the name of the list head within the struct. */ #define bfdev_list_first_entry_or_null(ptr, type, member) ({ \ - bfdev_list_head_t *head__ = (ptr); \ - bfdev_list_head_t *pos__ = head__->next; \ - pos__ != head__ ? bfdev_list_entry(pos__, type, member) : NULL; \ + bfdev_list_head_t *__head = (ptr); \ + bfdev_list_head_t *__pos = __head->next; \ + __pos != __head ? bfdev_list_entry(__pos, type, member) : NULL; \ }) /** @@ -398,9 +398,9 @@ bfdev_list_splice_tail_init(bfdev_list_head_t *head, bfdev_list_head_t *list) * @member: the name of the list head within the struct. */ #define bfdev_list_last_entry_or_null(ptr, type, member) ({ \ - bfdev_list_head_t *head__ = (ptr); \ - bfdev_list_head_t *pos__ = head__->prev; \ - pos__ != head__ ? bfdev_list_entry(pos__, type, member) : NULL; \ + bfdev_list_head_t *__head = (ptr); \ + bfdev_list_head_t *__pos = __head->prev; \ + __pos != __head ? bfdev_list_entry(__pos, type, member) : NULL; \ }) /** @@ -410,9 +410,9 @@ bfdev_list_splice_tail_init(bfdev_list_head_t *head, bfdev_list_head_t *list) * @member: the name of the list head within the struct. */ #define bfdev_list_next_entry_or_null(pos, head, member) ({ \ - typeof(*(pos)) *pos__; \ - pos__ = bfdev_list_entry((pos)->member.next, typeof(*(pos)), member); \ - bfdev_list_entry_check_head(pos__, head, member) ? NULL : pos__; \ + typeof(*(pos)) *__pos; \ + __pos = bfdev_list_entry((pos)->member.next, typeof(*(pos)), member); \ + bfdev_list_entry_check_head(__pos, head, member) ? NULL : __pos; \ }) /** @@ -422,9 +422,9 @@ bfdev_list_splice_tail_init(bfdev_list_head_t *head, bfdev_list_head_t *list) * @member: the name of the list head within the struct. */ #define bfdev_list_prev_entry_or_null(pos, head, member) ({ \ - typeof(*(pos)) *pos__; \ - pos__ = bfdev_list_entry((pos)->member.prev, typeof(*(pos)), member); \ - bfdev_list_entry_check_head(pos__, head, member) ? NULL : pos__; \ + typeof(*(pos)) *__pos; \ + __pos = bfdev_list_entry((pos)->member.prev, typeof(*(pos)), member); \ + bfdev_list_entry_check_head(__pos, head, member) ? NULL : __pos; \ }) /** diff --git a/include/bfdev/macro.h b/include/bfdev/macro.h index 86914e3d..3f40eb13 100644 --- a/include/bfdev/macro.h +++ b/include/bfdev/macro.h @@ -16,16 +16,16 @@ BFDEV_BEGIN_DECLS * @b: second value. */ #define bfdev_swap(a, b) ({ \ - typeof(a) _a = (a); \ - (a) = (b); (b) = _a; \ + typeof(a) __a = (a); \ + (a) = (b); (b) = __a; \ }) /** * BFDEV_ARRAY_SIZE() - get the number of elements in array. * @arr: array to be sized. */ -#define BFDEV_ARRAY_SIZE(arr) ( \ - sizeof(arr) / sizeof((arr)[0]) \ +#define BFDEV_ARRAY_SIZE(arr) ( \ + sizeof(arr) / sizeof((arr)[0]) \ ) /* This counts to 12. Any more, it will return 13th argument. */ diff --git a/include/bfdev/matrix.h b/include/bfdev/matrix.h index cbb29764..e2ec7645 100644 --- a/include/bfdev/matrix.h +++ b/include/bfdev/matrix.h @@ -8,68 +8,102 @@ #include #include +#include BFDEV_BEGIN_DECLS +#define BFDEV_MATRIX_TYPE bfdev_uw_t +#define BFDEV_MATRIX_BITS BFDEV_BITS_PER_LONG +#define BFDEV_MATRIX_SIZE BFDEV_BYTES_PER_LONG + typedef struct bfdev_matrix bfdev_matrix_t; struct bfdev_matrix { + const bfdev_alloc_t *alloc; unsigned int row; unsigned int col; - long values[]; + bfdev_array_t value; }; +#define BFDEV_MATRIX_STATIC(ALLOC) { \ + .value = BFDEV_ARRAY_STATIC(ALLOC, BFDEV_MATRIX_SIZE), \ + .alloc = (ALLOC), \ +} + +#define BFDEV_MATRIX_INIT(alloc) \ + (bfdev_matrix_t) BFDEV_MATRIX_STATIC(alloc) + +#define BFDEV_DEFINE_MATRIX(name, alloc) \ + bfdev_matrix_t name = BFDEV_MATRIX_INIT(alloc) + +static inline void +bfdev_matrix_init(bfdev_matrix_t *matrix, const bfdev_alloc_t *alloc) +{ + *matrix = BFDEV_MATRIX_INIT(alloc); +} + /** * bfdev_matrix_add() - adding two matrices. * @va: first addend matrix. * @vb: second addend matrix. */ -extern bfdev_matrix_t * -bfdev_matrix_add(const bfdev_alloc_t *alloc, const bfdev_matrix_t *va, - const bfdev_matrix_t *vb); +extern int +bfdev_matrix_add(bfdev_matrix_t *dest, + const bfdev_matrix_t *va, const bfdev_matrix_t *vb); /** * bfdev_matrix_sub() - subtracting two matrices. * @va: minuend; matrix to subtract from. * @vb: subtrahend; matrix to subtract from @va. */ -extern bfdev_matrix_t * -bfdev_matrix_sub(const bfdev_alloc_t *alloc, const bfdev_matrix_t *va, - const bfdev_matrix_t *vb); +extern int +bfdev_matrix_sub(bfdev_matrix_t *dest, + const bfdev_matrix_t *va, const bfdev_matrix_t *vb); /** * bfdev_matrix_mul() - multiplying two matrices. * @va: first factor matrix. * @vb: second factor matrix. */ -extern bfdev_matrix_t * -bfdev_matrix_mul(const bfdev_alloc_t *alloc, const bfdev_matrix_t *va, - const bfdev_matrix_t *vb); +extern int +bfdev_matrix_mul(bfdev_matrix_t *dest, + const bfdev_matrix_t *va, const bfdev_matrix_t *vb); /** - * bfdev_matrix_copy() - copy a new matrix. - * @var: variables to copy. + * bfdev_matrix_set() - copy data form matrices. + * @dest: destination matrix. + * @src: source matrix. */ -extern bfdev_matrix_t * -bfdev_matrix_copy(const bfdev_alloc_t *alloc, - const bfdev_matrix_t *var); +extern int +bfdev_matrix_set(bfdev_matrix_t *dest, const bfdev_matrix_t *src); /** - * bfdev_matrix_create() - create a new matrix. - * @row: number of rows in the matrix. - * @col: number of columns in the matrix. + * bfdev_matrix_import() - import data to a matrix. + * @var: matrix to import data into. + * @buffer: data buffer to import data. + * @row: number of rows in the @buffer. + * @col: number of columns in the @buffer. */ -extern bfdev_matrix_t * -bfdev_matrix_create(const bfdev_alloc_t *alloc, +extern int +bfdev_matrix_import(bfdev_matrix_t *var, const BFDEV_MATRIX_TYPE *buffer, unsigned int row, unsigned int col); /** - * bfdev_matrix_destory() - destory a matrix. - * @var: variables to destory. + * bfdev_matrix_data() - indexing data form a matrix. + * @var: matrix to index data. + * @row: index of rows in the @var. + * @col: index of columns in the @var. + */ +extern const BFDEV_MATRIX_TYPE * +bfdev_matrix_data(const bfdev_matrix_t *var, + unsigned int row, unsigned int col); + +/** + * bfdev_matrix_release() - release a matrix. + * @var: matrix to release. */ extern void -bfdev_matrix_destory(const bfdev_alloc_t *alloc, - const bfdev_matrix_t *var); +bfdev_matrix_release(bfdev_matrix_t *var); BFDEV_END_DECLS diff --git a/include/bfdev/mpi.h b/include/bfdev/mpi.h index 00a61767..2c90ab3f 100644 --- a/include/bfdev/mpi.h +++ b/include/bfdev/mpi.h @@ -22,6 +22,7 @@ BFDEV_BEGIN_DECLS typedef struct bfdev_mpi bfdev_mpi_t; struct bfdev_mpi { + const bfdev_alloc_t *alloc; bfdev_array_t value; bool plus; }; @@ -120,12 +121,12 @@ extern int bfdev_mpi_set(bfdev_mpi_t *dest, const bfdev_mpi_t *src); extern int -bfdev_mpi_read(const bfdev_mpi_t *var, BFDEV_MPI_TYPE *buffer, - unsigned long length, bool *sign); +bfdev_mpi_import(bfdev_mpi_t *var, const BFDEV_MPI_TYPE *buffer, + unsigned long length, bool sign); -extern int -bfdev_mpi_write(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); diff --git a/include/bfdev/notifier.h b/include/bfdev/notifier.h index f9689bf4..aef75c6c 100644 --- a/include/bfdev/notifier.h +++ b/include/bfdev/notifier.h @@ -12,7 +12,7 @@ BFDEV_BEGIN_DECLS -typedef struct bfdev_notifier_head bfdev_notifier_head_t; +typedef struct bfdev_notifier bfdev_notifier_t; typedef struct bfdev_notifier_node bfdev_notifier_node_t; typedef enum bfdev_notifier_ret bfdev_notifier_ret_t; @@ -28,6 +28,16 @@ enum bfdev_notifier_ret { BFDEV_NOTIFI_RET_STOP = BFDEV_BIT(__BFDEV_NOTIFI_RET_STOP), }; +/** + * struct bfdev_notifier - generic notification chain header. + * @name: name of notification chain. + * @nodes: node header for managing notification chain nodes. + */ +struct bfdev_notifier { + const char *name; + bfdev_ilist_head_t nodes; +}; + /** * struct bfdev_notifier_node - describe a notification chain node. * @list: node for hanging notification chain. @@ -43,30 +53,21 @@ struct bfdev_notifier_node { void *pdata; }; -/** - * struct bfdev_notifier_head - generic notification chain header. - * @node: node header for managing notification chain nodes. - * @name: name of notification chain. - */ -struct bfdev_notifier_head { - bfdev_ilist_head_t node; - const char *name; -}; - #define BFDEV_NOTIFIER_STATIC(HEAD, NAME) { \ - BFDEV_ILIST_HEAD_STATIC((HEAD).node), .name = (NAME) \ + .name = (NAME), \ + .nodes = BFDEV_ILIST_HEAD_STATIC(&(HEAD)->nodes), \ } #define BFDEV_NOTIFIER_INIT(head, name) \ - (bfdev_notifier_head_t) BFDEV_NOTIFIER_STATIC(head, name) + (bfdev_notifier_t) BFDEV_NOTIFIER_STATIC(head, name) #define BFDEV_DEFINE_NOTIFIER(head, name) \ - bfdev_notifier_head_t head = BFDEV_NOTIFIER_INIT(head, name) + bfdev_notifier_t head = BFDEV_NOTIFIER_INIT(&head, name) static inline void -bfdev_notifier_init(bfdev_notifier_head_t *head, const char *name) +bfdev_notifier_init(bfdev_notifier_t *head, const char *name) { - *head = BFDEV_NOTIFIER_INIT(*head, name); + *head = BFDEV_NOTIFIER_INIT(head, name); } /** @@ -77,7 +78,7 @@ bfdev_notifier_init(bfdev_notifier_head_t *head, const char *name) * @called_num: number of nodes actually notified. */ extern bfdev_notifier_ret_t -bfdev_notifier_call(bfdev_notifier_head_t *head, void *args, +bfdev_notifier_call(bfdev_notifier_t *head, void *args, unsigned int call_num, unsigned int *called_num); /** @@ -86,8 +87,7 @@ bfdev_notifier_call(bfdev_notifier_head_t *head, void *args, * @node: notification chain node to register. */ extern int -bfdev_notifier_register(bfdev_notifier_head_t *head, - bfdev_notifier_node_t *node); +bfdev_notifier_register(bfdev_notifier_t *head, bfdev_notifier_node_t *node); /** * bfdev_notifier_unregister - unregister a node from the notification chain. @@ -95,8 +95,7 @@ bfdev_notifier_register(bfdev_notifier_head_t *head, * @node: notification chain node to unregister. */ extern void -bfdev_notifier_unregister(bfdev_notifier_head_t *head, - bfdev_notifier_node_t *node); +bfdev_notifier_unregister(bfdev_notifier_t *head, bfdev_notifier_node_t *node); BFDEV_BEGIN_DECLS diff --git a/include/bfdev/prandom.h b/include/bfdev/prandom.h index 89e9342c..966f91f0 100644 --- a/include/bfdev/prandom.h +++ b/include/bfdev/prandom.h @@ -13,43 +13,64 @@ BFDEV_BEGIN_DECLS -typedef struct bfdev_prandom_state bfdev_prandom_state_t; +#ifndef BFDEV_PRANDOM_SEED +# define BFDEV_PRANDOM_SEED 0x408c3c09UL +#endif + +typedef struct bfdev_prandom bfdev_prandom_t; -struct bfdev_prandom_state { +struct bfdev_prandom { uint32_t s1, s2; uint32_t s3, s4; }; +#define BFDEV_PRANDOM_STATIC() { \ + .s1 = BFDEV_PRANDOM_SEED, .s2 = BFDEV_PRANDOM_SEED, \ + .s3 = BFDEV_PRANDOM_SEED, .s4 = BFDEV_PRANDOM_SEED, \ +} + +#define BFDEV_PRANDOM_INIT() \ + (bfdev_prandom_t) BFDEV_PRANDOM_STATIC() + +#define BFDEV_DEFINE_PRANDOM(name) \ + bfdev_prandom_t name = BFDEV_PRANDOM_INIT() + /* Tausworthe generators */ #define BFDEV_TAUSWORTHE(seed, a, b, c, d) ( \ (((seed) & (c)) << (d)) ^ \ ((((seed) << (a)) ^ (seed)) >> (b)) \ ) +static inline void +bfdev_prandom_init(bfdev_prandom_t *pstate) +{ + *pstate = BFDEV_PRANDOM_INIT(); +} + /** * bfdev_prandom_seed() - set seed for prandom_state. * @state: pointer to state structure to receive the seed. * @seed: arbitrary 64-bit value to use as a seed. */ extern void -bfdev_prandom_seed(bfdev_prandom_state_t *pstate, uint64_t seed); +bfdev_prandom_seed(bfdev_prandom_t *pstate, uint64_t seed); /** * bfdev_prandom_value() - seeded pseudo-random number generator. * @state: pointer to state structure holding seeded state. */ extern uint32_t -bfdev_prandom_value(bfdev_prandom_state_t *pstate); +bfdev_prandom_value(bfdev_prandom_t *pstate); static inline uint64_t -bfdev_prandom_u64(bfdev_prandom_state_t *pstate) +bfdev_prandom_u64(bfdev_prandom_t *pstate) { uint32_t high = bfdev_prandom_value(pstate); return ((uint64_t)high << 32) + bfdev_prandom_value(pstate); } static inline unsigned long -bfdev_prandom_long(bfdev_prandom_state_t *pstate) +bfdev_prandom_long(bfdev_prandom_t *pstate) { #if BFDEV_BITS_PER_LONG == 32 return bfdev_prandom_value(pstate); diff --git a/include/bfdev/radix.h b/include/bfdev/radix.h index b1e9887a..e9a95a66 100644 --- a/include/bfdev/radix.h +++ b/include/bfdev/radix.h @@ -14,12 +14,12 @@ BFDEV_BEGIN_DECLS -#define BFDEV_RADIX_SHIFT 8 -#define BFDEV_RADIX_BLOCK BFDEV_BIT(BFDEV_RADIX_SHIFT) +#ifndef BFDEV_RADIX_SHIFT +# define BFDEV_RADIX_SHIFT 8 +#endif +#define BFDEV_RADIX_BLOCK BFDEV_BIT(BFDEV_RADIX_SHIFT) #define BFDEV_RADIX_ARY (BFDEV_RADIX_BLOCK / sizeof(bfdev_radix_node_t *)) -#define BFDEV_RADIX_ARY_MASK (BFDEV_RADIX_ARY - 1) -#define BFDEV_RADIX_ARY_SHIFT bfdev_ilog2(BFDEV_RADIX_ARY) typedef struct bfdev_radix_root bfdev_radix_root_t; typedef struct bfdev_radix_node bfdev_radix_node_t; @@ -31,13 +31,12 @@ struct bfdev_radix_root { }; struct bfdev_radix_node { - bfdev_radix_node_t *parent; union { - struct { + struct { /* branch */ bfdev_radix_node_t *child[BFDEV_RADIX_ARY]; unsigned int refcount; }; - struct { + struct { /* leaf */ uint8_t block[BFDEV_RADIX_BLOCK]; BFDEV_DEFINE_BITMAP(bitmap, BFDEV_RADIX_BLOCK); }; @@ -54,8 +53,9 @@ struct bfdev_radix_node { char check[BFDEV_RADIX_CHECK(datatype)]; \ } -#define BFDEV_RADIX_STATIC(ALLOC) \ - {.tree = {.alloc = (ALLOC)}} +#define BFDEV_RADIX_STATIC(ALLOC) { \ + .tree = {.alloc = (ALLOC)}, \ +} #define BFDEV_RADIX_INIT(name, alloc) \ (typeof(name)) BFDEV_RADIX_STATIC(alloc) @@ -77,6 +77,20 @@ bfdev_radix_offset(uintptr_t index, size_t cells) (index % num) * cells; } +static inline uintptr_t +bfdev_radix_index(uintptr_t offset, size_t cells) +{ + size_t num; + + if (bfdev_pow2_check(cells)) + return offset / cells; + + /* object per block */ + num = BFDEV_RADIX_BLOCK / cells; + return (offset / num) / BFDEV_RADIX_BLOCK + + (offset % num) / cells; +} + #define bfdev_radix_cast(radix) \ (typeof((radix)->data) *) @@ -86,32 +100,35 @@ bfdev_radix_offset(uintptr_t index, size_t cells) #define bfdev_radix_to_offset(radix, index) \ bfdev_radix_offset(index, bfdev_radix_cells(radix)) -#define bfdev_radix_find(radix, index) ({ \ - bfdev_radix_root_t *__root; \ - __root = &(radix)->tree; \ - bfdev_radix_cast(radix) ( \ - bfdev_radix_root_find(__root, \ - bfdev_radix_to_offset(radix, index) \ - ) \ - ); \ +#define bfdev_radix_to_index(radix, offset) \ + bfdev_radix_index(offset, bfdev_radix_cells(radix)) + +#define bfdev_radix_find(radix, index) ({ \ + bfdev_radix_root_t *__root; \ + __root = &(radix)->tree; \ + bfdev_radix_cast(radix) ( \ + bfdev_radix_root_find(__root, \ + bfdev_radix_to_offset(radix, index) \ + ) \ + ); \ }) -#define bfdev_radix_alloc(radix, index) ({ \ - bfdev_radix_root_t *__root; \ - __root = &(radix)->tree; \ - bfdev_radix_cast(radix) ( \ - bfdev_radix_root_alloc(__root, \ - bfdev_radix_to_offset(radix, index) \ - ) \ - ); \ +#define bfdev_radix_alloc(radix, index) ({ \ + bfdev_radix_root_t *__root; \ + __root = &(radix)->tree; \ + bfdev_radix_cast(radix) ( \ + bfdev_radix_root_alloc(__root, \ + bfdev_radix_to_offset(radix, index) \ + ) \ + ); \ }) -#define bfdev_radix_free(radix, index) ({ \ - bfdev_radix_root_t *__root; \ - __root = &(radix)->tree; \ - bfdev_radix_root_free(__root, \ - bfdev_radix_to_offset(radix, index) \ - ); \ +#define bfdev_radix_free(radix, index) ({ \ + bfdev_radix_root_t *__root; \ + __root = &(radix)->tree; \ + bfdev_radix_root_free(__root, \ + bfdev_radix_to_offset(radix, index) \ + ); \ }) #define bfdev_radix_charge(radix, index, size) ({ \ @@ -123,12 +140,108 @@ bfdev_radix_offset(uintptr_t index, size_t cells) ); \ }) -#define bfdev_radix_destory(radix) ({ \ - bfdev_radix_root_t *__root; \ - __root = &(radix)->tree; \ - bfdev_radix_root_destory(__root); \ +#define bfdev_radix_release(radix) ({ \ + bfdev_radix_root_t *__root; \ + __root = &(radix)->tree; \ + bfdev_radix_root_release(__root); \ +}) + +#define bfdev_radix_first(radix, index) ({ \ + bfdev_radix_root_t *__root; \ + uintptr_t __off; \ + void *__retval; \ + __root = &(radix)->tree; \ + __retval = bfdev_radix_root_first(__root, &__off); \ + *(index) = bfdev_radix_to_index(radix, __off); \ + __retval; \ }) +#define bfdev_radix_last(radix, index) ({ \ + bfdev_radix_root_t *__root; \ + uintptr_t __off; \ + void *__retval; \ + __root = &(radix)->tree; \ + __retval = bfdev_radix_root_last(__root, &__off); \ + *(index) = bfdev_radix_to_index(radix, __off); \ + __retval; \ +}) + +#define bfdev_radix_next(radix, index) ({ \ + bfdev_radix_root_t *__root; \ + uintptr_t __off; \ + void *__retval; \ + __root = &(radix)->tree; \ + __off = bfdev_radix_to_offset(radix, *(index)); \ + __retval = bfdev_radix_root_next(__root, &__off); \ + *(index) = bfdev_radix_to_index(radix, __off); \ + __retval; \ +}) + +#define bfdev_radix_prev(radix, index) ({ \ + bfdev_radix_root_t *__root; \ + uintptr_t __off; \ + void *__retval; \ + __root = &(radix)->tree; \ + __off = bfdev_radix_to_offset(radix, *(index)); \ + __retval = bfdev_radix_root_prev(__root, &__off); \ + *(index) = bfdev_radix_to_index(radix, __off); \ + __retval; \ +}) + +#define bfdev_radix_for_each(value, radix, index) \ + for ((value) = bfdev_radix_first(radix, index); \ + value; (value) = bfdev_radix_next(radix, index)) + +#define bfdev_radix_for_each_reverse(value, radix, index) \ + for ((value) = bfdev_radix_last(radix, index); \ + value; (value) = bfdev_radix_prev(radix, index)) + +#define bfdev_radix_for_each_form(value, radix, index) \ + for (; value; (value) = bfdev_radix_next(radix, index)) + +#define bfdev_radix_for_each_reverse_form(value, radix, index) \ + for (; value; (value) = bfdev_radix_prev(radix, index)) + +#define bfdev_radix_for_each_continue(value, radix, index) \ + for ((value) = bfdev_radix_next(radix, index); \ + value; (value) = bfdev_radix_next(radix, index)) + +#define bfdev_radix_for_each_reverse_continue(value, radix, index) \ + for ((value) = bfdev_radix_prev(radix, index); \ + value; (value) = bfdev_radix_prev(radix, index)) + +#define bfdev_radix_for_each_safe(value, radix, index, tval, tidx) \ + for ((void)(((value) = bfdev_radix_first(radix, index)) && \ + (*(tidx) = *(index), (tval) = bfdev_radix_next(radix, tidx))); value; \ + (void)((*(index) = *(tidx), (value) = (tval)) && \ + ((tval) = bfdev_radix_next(radix, tidx)))) + +#define bfdev_radix_for_each_reverse_safe(value, radix, index, tval, tidx) \ + for ((void)(((value) = bfdev_radix_last(radix, index)) && \ + (*(tidx) = *(index), (tval) = bfdev_radix_prev(radix, tidx))); value; \ + (void)((*(index) = *(tidx), (value) = (tval)) && \ + ((tval) = bfdev_radix_prev(radix, tidx)))) + +#define bfdev_radix_for_each_form_safe(value, radix, index, tval, tidx) \ + for (; value; (void)((*(index) = *(tidx), (value) = (tval)) && \ + ((tval) = bfdev_radix_next(radix, tidx)))) + +#define bfdev_radix_for_each_reverse_form_safe(value, radix, index, tval, tidx) \ + for (; value; (void)((*(index) = *(tidx), (value) = (tval)) && \ + ((tval) = bfdev_radix_prev(radix, tidx)))) + +#define bfdev_radix_for_each_continue_safe(value, radix, index, tval, tidx) \ + for ((void)((*(index) = *(tidx), (value) = (tval)) && \ + ((tval) = bfdev_radix_next(radix, tidx))); value; \ + (void)((*(index) = *(tidx), (value) = (tval)) && \ + (tval) = bfdev_radix_next(radix, tidx))) + +#define bfdev_radix_for_each_reverse_continue_safe(value, radix, index, tval, tidx) \ + for ((void)((*(index) = *(tidx), (value) = (tval)) && \ + ((tval) = bfdev_radix_prev(radix, tidx))); value; \ + (void)((*(index) = *(tidx), (value) = (tval)) && \ + ((tval) = bfdev_radix_prev(radix, tidx)))) + extern void * bfdev_radix_root_find(bfdev_radix_root_t *root, uintptr_t offset); @@ -142,7 +255,19 @@ extern int bfdev_radix_root_charge(bfdev_radix_root_t *root, uintptr_t offset, size_t size); extern void -bfdev_radix_root_destory(bfdev_radix_root_t *root); +bfdev_radix_root_release(bfdev_radix_root_t *root); + +extern void * +bfdev_radix_root_first(bfdev_radix_root_t *root, uintptr_t *offsetp); + +extern void * +bfdev_radix_root_last(bfdev_radix_root_t *root, uintptr_t *offsetp); + +extern void * +bfdev_radix_root_next(bfdev_radix_root_t *root, uintptr_t *offsetp); + +extern void * +bfdev_radix_root_prev(bfdev_radix_root_t *root, uintptr_t *offsetp); BFDEV_END_DECLS diff --git a/include/bfdev/rbtree.h b/include/bfdev/rbtree.h index c79d6de1..6f3cb8a0 100644 --- a/include/bfdev/rbtree.h +++ b/include/bfdev/rbtree.h @@ -15,13 +15,14 @@ BFDEV_BEGIN_DECLS -#define BFDEV_RB_RED (0) -#define BFDEV_RB_BLACK (1) -#define BFDEV_RB_NSET (2) +#define BFDEV_RB_RED 0 +#define BFDEV_RB_BLACK 1 +#define BFDEV_RB_NSET 2 typedef struct bfdev_rb_node bfdev_rb_node_t; typedef struct bfdev_rb_root bfdev_rb_root_t; typedef struct bfdev_rb_root_cached bfdev_rb_root_cached_t; +typedef struct bfdev_rb_callbacks bfdev_rb_callbacks_t; struct bfdev_rb_node { bfdev_rb_node_t *parent; @@ -45,23 +46,26 @@ struct bfdev_rb_callbacks { void (*propagate)(bfdev_rb_node_t *node, bfdev_rb_node_t *stop); }; -#define BFDEV_RB_STATIC \ - {NULL} +#define BFDEV_RB_STATIC() { \ + .node = NULL, \ +} -#define BFDEV_RB_CACHED_STATIC \ - {{NULL}, NULL} +#define BFDEV_RB_CACHED_STATIC() { \ + .root = BFDEV_RB_STATIC(), \ + .leftmost = NULL, \ +} -#define BFDEV_RB_INIT \ - (bfdev_rb_root_t) BFDEV_RB_STATIC +#define BFDEV_RB_INIT() \ + (bfdev_rb_root_t) BFDEV_RB_STATIC() -#define BFDEV_RB_CACHED_INIT \ - (bfdev_rb_root_cached_t) BFDEV_RB_CACHED_STATIC +#define BFDEV_RB_CACHED_INIT() \ + (bfdev_rb_root_cached_t) BFDEV_RB_CACHED_STATIC() #define BFDEV_RB_ROOT(name) \ - bfdev_rb_root_t name = BFDEV_RB_INIT + bfdev_rb_root_t name = BFDEV_RB_INIT() #define BFDEV_RB_ROOT_CACHED(name) \ - bfdev_rb_root_cached_t name = BFDEV_RB_CACHED_INIT + bfdev_rb_root_cached_t name = BFDEV_RB_CACHED_INIT() #define BFDEV_RB_EMPTY_ROOT(root) \ ((root)->node == NULL) @@ -109,7 +113,13 @@ BFDEV_CALLBACK_CMP( static inline void bfdev_rb_init(bfdev_rb_root_t *root) { - *root = BFDEV_RB_INIT; + *root = BFDEV_RB_INIT(); +} + +static inline void +bfdev_rb_cache_init(bfdev_rb_root_cached_t *root) +{ + *root = BFDEV_RB_CACHED_INIT(); } /** @@ -120,7 +130,7 @@ bfdev_rb_init(bfdev_rb_root_t *root) */ extern void bfdev_rb_fixup_augmented(bfdev_rb_root_t *root, bfdev_rb_node_t *node, - const struct bfdev_rb_callbacks *callbacks); + const bfdev_rb_callbacks_t *callbacks); /** * bfdev_rb_erase_augmented() - augmented balance after remove node. @@ -130,7 +140,7 @@ bfdev_rb_fixup_augmented(bfdev_rb_root_t *root, bfdev_rb_node_t *node, */ extern void bfdev_rb_erase_augmented(bfdev_rb_root_t *root, bfdev_rb_node_t *parent, - const struct bfdev_rb_callbacks *callbacks); + const bfdev_rb_callbacks_t *callbacks); /** * bfdev_rb_remove_augmented() - augmented remove node form rbtree. @@ -140,7 +150,7 @@ bfdev_rb_erase_augmented(bfdev_rb_root_t *root, bfdev_rb_node_t *parent, */ extern bfdev_rb_node_t * bfdev_rb_remove_augmented(bfdev_rb_root_t *root, bfdev_rb_node_t *node, - const struct bfdev_rb_callbacks *callbacks); + const bfdev_rb_callbacks_t *callbacks); /** * bfdev_rb_fixup() - balance after insert node. @@ -183,7 +193,7 @@ bfdev_rb_replace(bfdev_rb_root_t *root, bfdev_rb_node_t *oldn, * @cmp: operator defining the node order. */ extern bfdev_rb_node_t * -bfdev_rb_find(const bfdev_rb_root_t *root, void *key, bfdev_rb_find_t cmp); +bfdev_rb_find(const bfdev_rb_root_t *root, void *key, bfdev_rb_find_t find); /** * bfdev_rb_find_last() - find @key in tree @root and return parent. @@ -192,10 +202,12 @@ bfdev_rb_find(const bfdev_rb_root_t *root, void *key, bfdev_rb_find_t cmp); * @cmp: operator defining the node order. * @parentp: pointer used to modify the parent node pointer. * @linkp: pointer used to modify the point to pointer to child node. + * @leftmostp: return whether it is the leftmost node. */ extern bfdev_rb_node_t * -bfdev_rb_find_last(bfdev_rb_root_t *root, void *key, bfdev_rb_find_t cmp, - bfdev_rb_node_t **parentp, bfdev_rb_node_t ***linkp); +bfdev_rb_find_last(bfdev_rb_root_t *root, void *key, bfdev_rb_find_t find, + bfdev_rb_node_t **parentp, bfdev_rb_node_t ***linkp, + bool *leftmostp); /** * bfdev_rb_parent() - find the parent node. @@ -637,14 +649,18 @@ bfdev_rb_insert_node(bfdev_rb_root_t *root, bfdev_rb_node_t *parent, * @node: new node to insert. * @cmp: operator defining the node order. */ -static inline void +static inline bool bfdev_rb_insert(bfdev_rb_root_t *root, bfdev_rb_node_t *node, bfdev_rb_cmp_t cmp, void *pdata) { bfdev_rb_node_t *parent, **link; link = bfdev_rb_parent(root, &parent, node, cmp, pdata, NULL); + if (bfdev_unlikely(!link)) + return false; + bfdev_rb_insert_node(root, parent, link, node); + return true; } /** @@ -681,7 +697,7 @@ bfdev_rb_delete(bfdev_rb_root_t *root, bfdev_rb_node_t *node) static inline void bfdev_rb_insert_node_augmented(bfdev_rb_root_t *root, bfdev_rb_node_t *parent, bfdev_rb_node_t **link, bfdev_rb_node_t *node, - const struct bfdev_rb_callbacks *callbacks) + const bfdev_rb_callbacks_t *callbacks) { bfdev_rb_link(parent, link, node); bfdev_rb_fixup_augmented(root, node, callbacks); @@ -694,15 +710,19 @@ bfdev_rb_insert_node_augmented(bfdev_rb_root_t *root, bfdev_rb_node_t *parent, * @cmp: operator defining the node order. * @callbacks: augmented callback function. */ -static inline void +static inline bool bfdev_rb_insert_augmented(bfdev_rb_root_t *root, bfdev_rb_node_t *node, bfdev_rb_cmp_t cmp, void *pdata, - const struct bfdev_rb_callbacks *callbacks) + const bfdev_rb_callbacks_t *callbacks) { bfdev_rb_node_t *parent, **link; link = bfdev_rb_parent(root, &parent, node, cmp, pdata, NULL); + if (bfdev_unlikely(!link)) + return false; + bfdev_rb_insert_node_augmented(root, parent, link, node, callbacks); + return true; } /** @@ -713,7 +733,7 @@ bfdev_rb_insert_augmented(bfdev_rb_root_t *root, bfdev_rb_node_t *node, */ static inline void bfdev_rb_delete_augmented(bfdev_rb_root_t *root, bfdev_rb_node_t *node, - const struct bfdev_rb_callbacks *callbacks) + const bfdev_rb_callbacks_t *callbacks) { bfdev_rb_node_t *rebalance; @@ -872,7 +892,7 @@ bfdev_rb_cached_insert_node(bfdev_rb_root_cached_t *cached, bfdev_rb_node_t *par * @node: new node to insert. * @cmp: operator defining the node order. */ -static inline void +static inline bool bfdev_rb_cached_insert(bfdev_rb_root_cached_t *cached, bfdev_rb_node_t *node, bfdev_rb_cmp_t cmp, void *pdata) { @@ -880,7 +900,11 @@ bfdev_rb_cached_insert(bfdev_rb_root_cached_t *cached, bfdev_rb_node_t *node, bool leftmost; link = bfdev_rb_cached_parent(cached, &parent, node, cmp, pdata, &leftmost); + if (bfdev_unlikely(!link)) + return false; + bfdev_rb_cached_insert_node(cached, parent, link, node, leftmost); + return true; } /** @@ -913,7 +937,7 @@ bfdev_rb_cached_delete(bfdev_rb_root_cached_t *cached, bfdev_rb_node_t *node) */ static inline void bfdev_rb_cached_fixup_augmented(bfdev_rb_root_cached_t *cached, bfdev_rb_node_t *node, - bool leftmost, const struct bfdev_rb_callbacks *callbacks) + bool leftmost, const bfdev_rb_callbacks_t *callbacks) { if (leftmost) cached->leftmost = node; @@ -933,7 +957,7 @@ bfdev_rb_cached_fixup_augmented(bfdev_rb_root_cached_t *cached, bfdev_rb_node_t static inline void bfdev_rb_cached_insert_node_augmented(bfdev_rb_root_cached_t *cached, bfdev_rb_node_t *parent, bfdev_rb_node_t **link, bfdev_rb_node_t *node, - bool leftmost, const struct bfdev_rb_callbacks *callbacks) + bool leftmost, const bfdev_rb_callbacks_t *callbacks) { bfdev_rb_link(parent, link, node); bfdev_rb_cached_fixup_augmented(cached, node, leftmost, callbacks); @@ -946,16 +970,20 @@ bfdev_rb_cached_insert_node_augmented(bfdev_rb_root_cached_t *cached, bfdev_rb_n * @cmp: operator defining the node order. * @callbacks: augmented callback function. */ -static inline void +static inline bool bfdev_rb_cached_insert_augmented(bfdev_rb_root_cached_t *cached, bfdev_rb_node_t *node, bfdev_rb_cmp_t cmp, void *pdata, - const struct bfdev_rb_callbacks *callbacks) + const bfdev_rb_callbacks_t *callbacks) { bfdev_rb_node_t *parent, **link; bool leftmost; link = bfdev_rb_cached_parent(cached, &parent, node, cmp, pdata, &leftmost); + if (bfdev_unlikely(!link)) + return false; + bfdev_rb_cached_insert_node_augmented(cached, parent, link, node, leftmost, callbacks); + return true; } /** @@ -966,7 +994,7 @@ bfdev_rb_cached_insert_augmented(bfdev_rb_root_cached_t *cached, bfdev_rb_node_t */ static inline bfdev_rb_node_t * bfdev_rb_cached_delete_augmented(bfdev_rb_root_cached_t *cached, bfdev_rb_node_t *node, - const struct bfdev_rb_callbacks *callbacks) + const bfdev_rb_callbacks_t *callbacks) { bfdev_rb_node_t *leftmost; @@ -997,59 +1025,81 @@ bfdev_rb_cached_replace(bfdev_rb_root_cached_t *cached, bfdev_rb_node_t *oldn, bfdev_rb_replace(&cached->root, oldn, newn); } -#define BFDEV_RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, RBAUGMENTED, RBCOMPUTE) \ -static void RBNAME##_rotate(bfdev_rb_node_t *rb_node, bfdev_rb_node_t *rb_successor) \ -{ \ - RBSTRUCT *node = bfdev_rb_entry(rb_node, RBSTRUCT, RBFIELD); \ - RBSTRUCT *successor = bfdev_rb_entry(rb_successor, RBSTRUCT, RBFIELD); \ - successor->RBAUGMENTED = node->RBAUGMENTED; \ - RBCOMPUTE(node, false); \ -} \ - \ -static void RBNAME##_copy(bfdev_rb_node_t *rb_node, bfdev_rb_node_t *rb_successor) \ -{ \ - RBSTRUCT *node = bfdev_rb_entry(rb_node, RBSTRUCT, RBFIELD); \ - RBSTRUCT *successor = bfdev_rb_entry(rb_successor, RBSTRUCT, RBFIELD); \ - successor->RBAUGMENTED = node->RBAUGMENTED; \ -} \ - \ -static void RBNAME##_propagate(bfdev_rb_node_t *rb_node, bfdev_rb_node_t *rb_stop) \ -{ \ - while (rb_node != rb_stop) { \ - RBSTRUCT *node = bfdev_rb_entry(rb_node, RBSTRUCT, RBFIELD); \ - if (RBCOMPUTE(node, true)) \ - break; \ - rb_node = node->RBFIELD.parent; \ - } \ -} \ - \ -RBSTATIC struct bfdev_rb_callbacks RBNAME = { \ - .rotate = RBNAME##_rotate, \ - .copy = RBNAME##_copy, \ - .propagate = RBNAME##_propagate, \ +#define BFDEV_RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, RBSTRUCT, \ + RBFIELD, RBAUGMENTED, RBCOMPUTE) \ +static void \ +RBNAME##_rotate(bfdev_rb_node_t *rb_node, bfdev_rb_node_t *rb_successor) \ +{ \ + RBSTRUCT *node, *successor; \ + \ + node = bfdev_rb_entry(rb_node, RBSTRUCT, RBFIELD); \ + successor = bfdev_rb_entry(rb_successor, RBSTRUCT, RBFIELD); \ + \ + successor->RBAUGMENTED = node->RBAUGMENTED; \ + RBCOMPUTE(node, false); \ +} \ + \ +static void \ +RBNAME##_copy(bfdev_rb_node_t *rb_node, bfdev_rb_node_t *rb_successor) \ +{ \ + RBSTRUCT *node, *successor; \ + \ + node = bfdev_rb_entry(rb_node, RBSTRUCT, RBFIELD); \ + successor = bfdev_rb_entry(rb_successor, RBSTRUCT, RBFIELD); \ + \ + successor->RBAUGMENTED = node->RBAUGMENTED; \ +} \ + \ +static void \ +RBNAME##_propagate(bfdev_rb_node_t *rb_node, bfdev_rb_node_t *rb_stop) \ +{ \ + RBSTRUCT *node; \ + \ + while (rb_node != rb_stop) { \ + node = bfdev_rb_entry(rb_node, RBSTRUCT, RBFIELD); \ + if (RBCOMPUTE(node, true)) \ + break; \ + rb_node = node->RBFIELD.parent; \ + } \ +} \ + \ +RBSTATIC bfdev_rb_callbacks_t RBNAME = { \ + .rotate = RBNAME##_rotate, \ + .copy = RBNAME##_copy, \ + .propagate = RBNAME##_propagate, \ } -#define BFDEV_RB_DECLARE_CALLBACKS_MAX(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, RBTYPE, RBAUGMENTED, RBCOMPUTE) \ -static inline bool RBNAME##_compute_max(RBSTRUCT *node, bool exit) \ -{ \ - RBSTRUCT *child; \ - RBTYPE max = RBCOMPUTE(node); \ - if (node->RBFIELD.left) { \ - child = bfdev_rb_entry(node->RBFIELD.left, RBSTRUCT, RBFIELD); \ - if (child->RBAUGMENTED > max) \ - max = child->RBAUGMENTED; \ - } \ - if (node->RBFIELD.right) { \ - child = bfdev_rb_entry(node->RBFIELD.right, RBSTRUCT, RBFIELD); \ - if (child->RBAUGMENTED > max) \ - max = child->RBAUGMENTED; \ - } \ - if (exit && node->RBAUGMENTED == max) \ - return true; \ - node->RBAUGMENTED = max; \ - return false; \ -} \ -BFDEV_RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, RBAUGMENTED, RBNAME##_compute_max) +#define BFDEV_RB_DECLARE_CALLBACKS_MAX(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, \ + RBTYPE, RBAUGMENTED, RBCOMPUTE) \ +static inline bool \ +RBNAME##_compute_max(RBSTRUCT *node, bool exit) \ +{ \ + RBSTRUCT *child; \ + RBTYPE max; \ + \ + max = RBCOMPUTE(node); \ + if (node->RBFIELD.left) { \ + child = bfdev_rb_entry(node->RBFIELD.left, RBSTRUCT, RBFIELD); \ + if (child->RBAUGMENTED > max) \ + max = child->RBAUGMENTED; \ + } \ + if (node->RBFIELD.right) { \ + child = bfdev_rb_entry(node->RBFIELD.right, RBSTRUCT, RBFIELD); \ + if (child->RBAUGMENTED > max) \ + max = child->RBAUGMENTED; \ + } \ + \ + if (exit && node->RBAUGMENTED == max) \ + return true; \ + node->RBAUGMENTED = max; \ + \ + return false; \ +} \ + \ +BFDEV_RB_DECLARE_CALLBACKS( \ + RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, \ + RBAUGMENTED, RBNAME##_compute_max \ +) BFDEV_END_DECLS diff --git a/include/bfdev/refcount.h b/include/bfdev/refcount.h index 1e232a28..fde5cbe3 100644 --- a/include/bfdev/refcount.h +++ b/include/bfdev/refcount.h @@ -14,9 +14,12 @@ BFDEV_BEGIN_DECLS -typedef struct bfdev_refcnt { +typedef struct bfdev_refcnt bfdev_refcnt_t; +typedef enum bfdev_refcnt_saturation bfdev_refcnt_saturation_t; + +struct bfdev_refcnt { bfdev_atomic_t count; -} bfdev_refcnt_t; +}; enum bfdev_refcnt_saturation { BFDEV_REFCNT_ADD_UAF, @@ -29,18 +32,19 @@ enum bfdev_refcnt_saturation { BFDEV_REFCNT_ADDNZ_OVF, }; -#define BFDEV_REFCNT_STATIC \ - { 1 } +#define BFDEV_REFCNT_STATIC() { \ + .count = 1, \ +} #define BFDEV_REFCNT_INIT \ - (bfdev_refcnt_t)BFDEV_REFCNT_STATIC + (bfdev_refcnt_t) BFDEV_REFCNT_STATIC() #define BFDEV_DEFINE_REFCNT(name) \ bfdev_refcnt_t name = BFDEV_REFCNT_INIT #ifdef BFDEV_DEBUG_REFCNT extern void -bfdev_refcnt_report(bfdev_refcnt_t *ref, enum bfdev_refcnt_saturation type); +bfdev_refcnt_report(bfdev_refcnt_t *ref, bfdev_refcnt_saturation_t type); #endif static inline bfdev_atomic_t diff --git a/include/bfdev/respool.h b/include/bfdev/respool.h index 17e34226..34cfe05c 100644 --- a/include/bfdev/respool.h +++ b/include/bfdev/respool.h @@ -11,73 +11,82 @@ BFDEV_BEGIN_DECLS -typedef struct bfdev_resnode bfdev_resnode_t; typedef struct bfdev_respool bfdev_respool_t; +typedef struct bfdev_respool_node bfdev_respool_node_t; -typedef void (*bfdev_respool_release_t) -(bfdev_respool_t *pool, bfdev_resnode_t *res); +BFDEV_CALLBACK_FIND( + bfdev_respool_find_t, + bfdev_respool_node_t * +); -typedef long (*bfdev_respool_find_t) -(bfdev_respool_t *pool, bfdev_resnode_t *res, const void *data); +BFDEV_CALLBACK_RELEASE( + bfdev_respool_release_t, + bfdev_respool_node_t * +); -struct bfdev_resnode { - const char *name; - bfdev_list_head_t list; - bfdev_respool_release_t release; +struct bfdev_respool { + bfdev_list_head_t nodes; }; -struct bfdev_respool { - const char *name; - bfdev_list_head_t node; +struct bfdev_respool_node { + bfdev_list_head_t list; + bfdev_respool_release_t release; }; -#define BFDEV_RESPOOL_STATIC(name) { \ - .name = __bfdev_stringify(name), \ - .node = BFDEV_LIST_HEAD_STATIC((name).list), \ +#define BFDEV_RESPOOL_STATIC(HEAD) { \ + .nodes = BFDEV_LIST_HEAD_STATIC(&(HEAD)->nodes), \ } -#define BFDEV_RESPOOL_INIT(name) \ - (bfdev_respool_t) BFDEV_RESPOOL_STATIC(name) +#define BFDEV_RESPOOL_INIT(head) \ + (bfdev_respool_t) BFDEV_RESPOOL_STATIC(head) #define BFDEV_DEFINE_RESPOOL(name) \ - bfdev_respool_t name = BFDEV_RESPOOL_INIT(name) + bfdev_respool_t head = BFDEV_RESPOOL_INIT(name) static inline void -bfdev_respool_init(bfdev_respool_t *pool, const char *name) +bfdev_respool_init(bfdev_respool_t *pool) { - pool->name = name; - bfdev_list_head_init(&pool->node); + *pool = BFDEV_RESPOOL_INIT(pool); } static inline bool bfdev_respool_check_empty(bfdev_respool_t *pool) { - return bfdev_list_check_empty(&pool->node); + return bfdev_list_check_empty(&pool->nodes); } -extern bfdev_resnode_t * -bfdev_respool_find(bfdev_respool_t *pool, bfdev_respool_find_t find, - const void *data); +static inline void +bfdev_respool_insert(bfdev_respool_t *pool, + bfdev_respool_node_t *node) +{ + bfdev_list_add_prev(&pool->nodes, &node->list); +} -extern void -bfdev_respool_insert(bfdev_respool_t *pool, bfdev_resnode_t *res); +static inline void +bfdev_respool_remove(bfdev_respool_t *pool, + bfdev_respool_node_t *node) +{ + bfdev_list_del(&node->list); +} -extern void -bfdev_respool_remove(bfdev_respool_t *pool, bfdev_resnode_t *res); +extern bfdev_respool_node_t * +bfdev_respool_find(bfdev_respool_t *pool, + bfdev_respool_find_t find, void *pdata); extern void -bfdev_respool_release(bfdev_respool_t *pool, bfdev_resnode_t *res); +bfdev_respool_release(bfdev_respool_t *pool, + bfdev_respool_node_t *node, void *pdata); -extern bfdev_resnode_t * -bfdev_respool_find_remove(bfdev_respool_t *pool, bfdev_respool_find_t find, - const void *data); +extern bfdev_respool_node_t * +bfdev_respool_find_remove(bfdev_respool_t *pool, + bfdev_respool_find_t find, void *pdata); -extern bfdev_resnode_t * -bfdev_respool_find_release(bfdev_respool_t *pool, bfdev_respool_find_t find, - const void *data); +extern bfdev_respool_node_t * +bfdev_respool_find_release(bfdev_respool_t *pool, + bfdev_respool_find_t find, void *pdata); extern void -bfdev_respool_release_all(bfdev_respool_t *pool); +bfdev_respool_release_all(bfdev_respool_t *pool, void *pdata); BFDEV_END_DECLS diff --git a/include/bfdev/ringbuf.h b/include/bfdev/ringbuf.h index 358770ab..733e68a3 100644 --- a/include/bfdev/ringbuf.h +++ b/include/bfdev/ringbuf.h @@ -11,6 +11,10 @@ #include #include +BFDEV_BEGIN_DECLS + +typedef struct bfdev_ringbuf bfdev_ringbuf_t; + struct bfdev_ringbuf { const bfdev_alloc_t *alloc; unsigned long in; @@ -197,10 +201,10 @@ struct bfdev_ringbuf { #define bfdev_ringbuf_initialized(ptr) ((ptr)->ringbuf.mask) /** - * bfdev_ringbuf_recsize - get the size of the record length fie. - * @ptr: pointer of the ringbuf to get __recsi. + * bfdev_ringbuf_recsize - returns the size of the record length field. + * @ptr: pointer of the ringbuf to get field length. */ -#define bfdev_ringbuf_recsize(ptr) (sizeof(*(ptr)->rectyp)) +#define bfdev_ringbuf_recsize(ptr) (sizeof(*(ptr)->rectype)) /** * bfdev_ringbuf_size - get the size of the element managed by the ringbuf. @@ -425,13 +429,37 @@ struct bfdev_ringbuf { bfdev_ringbuf_in_flat(__ringbuf, __tbuff, __tlen); \ }) -extern unsigned long bfdev_ringbuf_peek_flat(struct bfdev_ringbuf *ringbuf, void *buff, unsigned long len); -extern unsigned long bfdev_ringbuf_out_flat(struct bfdev_ringbuf *ringbuf, void *buff, unsigned long len); -extern unsigned long bfdev_ringbuf_in_flat(struct bfdev_ringbuf *ringbuf, const void *buff, unsigned long len); -extern unsigned long bfdev_ringbuf_peek_record(struct bfdev_ringbuf *ringbuf, void *buff, unsigned long len, unsigned long record); -extern unsigned long bfdev_ringbuf_out_record(struct bfdev_ringbuf *ringbuf, void *buff, unsigned long len, unsigned long record); -extern unsigned long bfdev_ringbuf_in_record(struct bfdev_ringbuf *ringbuf, const void *buff, unsigned long len, unsigned long record); -extern int bfdev_ringbuf_dynamic_alloc(struct bfdev_ringbuf *ringbuf, const bfdev_alloc_t *alloc, size_t esize, size_t size); -extern void bfdev_ringbuf_dynamic_free(struct bfdev_ringbuf *ringbuf); +extern unsigned long +bfdev_ringbuf_peek_flat(struct bfdev_ringbuf *ringbuf, void *buff, + unsigned long len); + +extern unsigned long +bfdev_ringbuf_out_flat(struct bfdev_ringbuf *ringbuf, void *buff, + unsigned long len); + +extern unsigned long +bfdev_ringbuf_in_flat(struct bfdev_ringbuf *ringbuf, const void *buff, + unsigned long len); + +extern unsigned long +bfdev_ringbuf_peek_record(struct bfdev_ringbuf *ringbuf, void *buff, + unsigned long len, unsigned long record); + +extern unsigned long +bfdev_ringbuf_out_record(struct bfdev_ringbuf *ringbuf, void *buff, + unsigned long len, unsigned long record); + +extern unsigned long +bfdev_ringbuf_in_record(struct bfdev_ringbuf *ringbuf, const void *buff, + unsigned long len, unsigned long record); + +extern int +bfdev_ringbuf_dynamic_alloc(struct bfdev_ringbuf *ringbuf, const bfdev_alloc_t *alloc, + size_t esize, size_t size); + +extern void +bfdev_ringbuf_dynamic_free(struct bfdev_ringbuf *ringbuf); + +BFDEV_END_DECLS #endif /* _BFDEV_RINGBUF_H_ */ diff --git a/include/bfdev/segtree.h b/include/bfdev/segtree.h index 468f4e14..63fe06db 100644 --- a/include/bfdev/segtree.h +++ b/include/bfdev/segtree.h @@ -3,8 +3,8 @@ * Copyright(c) 2023 John Sanpe */ -#ifndef _BFDEV_SEGTREE_ -#define _BFDEV_SEGTREE_ +#ifndef _BFDEV_SEGTREE_H_ +#define _BFDEV_SEGTREE_H_ #include #include @@ -37,11 +37,23 @@ struct bfdev_segtree_node { #define bfdev_segtree_entry_safe(ptr, type, member) \ bfdev_container_of_safe(ptr, type, member) -extern void bfdev_segtree_insert(bfdev_rb_root_cached_t *root, bfdev_segtree_node_t *node); -extern void bfdev_segtree_delete(bfdev_rb_root_cached_t *root, bfdev_segtree_node_t *node); -extern bfdev_segtree_node_t *bfdev_segtree_search(bfdev_segtree_node_t *node, unsigned long start, unsigned long end); -extern bfdev_segtree_node_t *bfdev_segtree_first(bfdev_rb_root_cached_t *root, unsigned long start, unsigned long end); -extern bfdev_segtree_node_t *bfdev_segtree_next(bfdev_segtree_node_t *node, unsigned long start, unsigned long end); +extern void +bfdev_segtree_insert(bfdev_rb_root_cached_t *root, bfdev_segtree_node_t *node); + +extern void +bfdev_segtree_delete(bfdev_rb_root_cached_t *root, bfdev_segtree_node_t *node); + +extern bfdev_segtree_node_t * +bfdev_segtree_search(bfdev_segtree_node_t *node, unsigned long start, + unsigned long end); + +extern bfdev_segtree_node_t * +bfdev_segtree_first(bfdev_rb_root_cached_t *root, unsigned long start, + unsigned long end); + +extern bfdev_segtree_node_t * +bfdev_segtree_next(bfdev_segtree_node_t *node, unsigned long start, + unsigned long end); /** * bfdev_segtree_first_entry - get the first element from a segtree. @@ -127,107 +139,128 @@ extern bfdev_segtree_node_t *bfdev_segtree_next(bfdev_segtree_node_t *node, unsi for ((void)(pos && (pos = bfdev_segtree_next_entry(pos, start, end, member))); \ pos; pos = bfdev_segtree_next_entry(pos, start, end, member)) -#define BFDEV_SEGTREE_DEFINE(STSTATIC, STNAME, STSTRUCT, STRB, STTYPE, STSUBTREE, STSTART, STEND) \ -BFDEV_RB_DECLARE_CALLBACKS_MAX(static, STNAME##_callbacks, STSTRUCT, STRB, STTYPE, STSUBTREE, STEND); \ -STSTATIC void STNAME##_insert(bfdev_rb_root_cached_t *cached, STSTRUCT *node) \ -{ \ - bfdev_rb_node_t **link = &cached->root.node; \ - STSTRUCT *parent = NULL; \ - STTYPE start, end; \ - bool leftmost = true; \ - \ - start = STSTART(node); \ - end = STEND(node); \ - \ - while (*link) { \ - parent = bfdev_rb_entry(*link, STSTRUCT, STRB); \ - if (parent->STSUBTREE < end) \ - parent->STSUBTREE = end; \ - if (start < STSTART(parent)) \ - link = &parent->STRB.left; \ - else { \ - link = &parent->STRB.right; \ - leftmost = false; \ - } \ - } \ - \ - bfdev_rb_cached_insert_node_augmented(cached, parent ? &parent->STRB : NULL, \ - link, &node->STRB, leftmost, &STNAME##_callbacks); \ - node->STSUBTREE = end; \ -} \ - \ -STSTATIC void STNAME##_delete(bfdev_rb_root_cached_t *cached, STSTRUCT *node) \ -{ \ - bfdev_rb_cached_delete_augmented(cached, &node->STRB, &STNAME##_callbacks); \ -} \ - \ -STSTATIC STSTRUCT *STNAME##_search(STSTRUCT *node, STTYPE start, STTYPE end) \ -{ \ - STSTRUCT *walk; \ - \ - for (;;) { \ - if (node->STRB.left) { \ - walk = bfdev_rb_entry(node->STRB.left, STSTRUCT, STRB); \ - if (walk->STSUBTREE >= start) { \ - node = walk; \ - continue; \ - } \ - } \ - if (STSTART(node) <= end) { \ - if (start <= STEND(node)) \ - return node; \ - else if (node->STRB.right) { \ - node = bfdev_rb_entry(node->STRB.right, STSTRUCT, STRB); \ - if (node->STSUBTREE >= start) \ - continue; \ - } \ - } \ - return NULL; \ - } \ -} \ - \ -STSTATIC STSTRUCT *STNAME##_first(bfdev_rb_root_cached_t *cached, STTYPE start, STTYPE end) \ -{ \ - STSTRUCT *node, *leftmost; \ - \ - if (!(node = bfdev_rb_entry_safe(cached->root.node, STSTRUCT, STRB))) \ - return NULL; \ - \ - if (node->STSUBTREE < start) \ - return NULL; \ - \ - leftmost = bfdev_rb_cached_first_entry(cached, STSTRUCT, STRB); \ - if (STSTART(leftmost) > end) \ - return NULL; \ - \ - return STNAME##_search(node, start, end); \ -} \ - \ -STSTATIC STSTRUCT *STNAME##_next(STSTRUCT *node, STTYPE start, STTYPE end) \ -{ \ - bfdev_rb_node_t *prev, *walk = node->STRB.right; \ - STSTRUCT *right; \ - \ - for (;;) { \ - if ((right = bfdev_rb_entry_safe(walk, STSTRUCT, STRB)) && right->STSUBTREE >= start) \ - return STNAME##_search(right, start, end); \ - \ - do { \ - walk = node->STRB.parent; \ - if (!walk) \ - return NULL; \ - prev = &node->STRB; \ - node = bfdev_rb_entry(walk, STSTRUCT, STRB); \ - walk = node->STRB.right; \ - } while (walk == prev); \ - \ - if (end < STSTART(node)) \ - return NULL; \ - else if (start <= STEND(node)) \ - return node; \ - } \ +#define BFDEV_SEGTREE_DEFINE(STSTATIC, STNAME, STSTRUCT, STRB, STTYPE, \ + STSUBTREE, STSTART, STEND) \ +BFDEV_RB_DECLARE_CALLBACKS_MAX( \ + static, STNAME##_callbacks, STSTRUCT, \ + STRB, STTYPE, STSUBTREE, STEND \ +); \ + \ +STSTATIC void \ +STNAME##_insert(bfdev_rb_root_cached_t *cached, STSTRUCT *node) \ +{ \ + bfdev_rb_node_t **link; \ + STSTRUCT *parent; \ + STTYPE start, end; \ + bool leftmost; \ + \ + link = &cached->root.node; \ + start = STSTART(node); \ + end = STEND(node); \ + \ + parent = NULL; \ + leftmost = true; \ + \ + while (*link) { \ + parent = bfdev_rb_entry(*link, STSTRUCT, STRB); \ + if (parent->STSUBTREE < end) \ + parent->STSUBTREE = end; \ + if (start < STSTART(parent)) \ + link = &parent->STRB.left; \ + else { \ + link = &parent->STRB.right; \ + leftmost = false; \ + } \ + } \ + \ + bfdev_rb_cached_insert_node_augmented( \ + cached, parent ? &parent->STRB : NULL, \ + link, &node->STRB, leftmost, &STNAME##_callbacks \ + ); \ + node->STSUBTREE = end; \ +} \ + \ +STSTATIC void \ +STNAME##_delete(bfdev_rb_root_cached_t *cached, STSTRUCT *node) \ +{ \ + bfdev_rb_cached_delete_augmented( \ + cached, &node->STRB, &STNAME##_callbacks \ + ); \ +} \ + \ +STSTATIC STSTRUCT * \ +STNAME##_search(STSTRUCT *node, STTYPE start, STTYPE end) \ +{ \ + STSTRUCT *walk; \ + \ + for (;;) { \ + if (node->STRB.left) { \ + walk = bfdev_rb_entry(node->STRB.left, STSTRUCT, STRB); \ + if (walk->STSUBTREE >= start) { \ + node = walk; \ + continue; \ + } \ + } \ + if (STSTART(node) <= end) { \ + if (start <= STEND(node)) \ + return node; \ + else if (node->STRB.right) { \ + node = bfdev_rb_entry(node->STRB.right, STSTRUCT, STRB); \ + if (node->STSUBTREE >= start) \ + continue; \ + } \ + } \ + return NULL; \ + } \ +} \ + \ +STSTATIC STSTRUCT * \ +STNAME##_first(bfdev_rb_root_cached_t *cached, STTYPE start, STTYPE end) \ +{ \ + STSTRUCT *node, *leftmost; \ + \ + node = bfdev_rb_entry_safe(cached->root.node, STSTRUCT, STRB); \ + if (!node) \ + return NULL; \ + \ + if (node->STSUBTREE < start) \ + return NULL; \ + \ + leftmost = bfdev_rb_cached_first_entry(cached, STSTRUCT, STRB); \ + if (STSTART(leftmost) > end) \ + return NULL; \ + \ + return STNAME##_search(node, start, end); \ +} \ + \ +STSTATIC STSTRUCT * \ +STNAME##_next(STSTRUCT *node, STTYPE start, STTYPE end) \ +{ \ + bfdev_rb_node_t *prev, *walk; \ + STSTRUCT *right; \ + \ + walk = node->STRB.right; \ + for (;;) { \ + right = bfdev_rb_entry_safe(walk, STSTRUCT, STRB); \ + if (right && right->STSUBTREE >= start) \ + return STNAME##_search(right, start, end); \ + \ + do { \ + walk = node->STRB.parent; \ + if (!walk) \ + return NULL; \ + prev = &node->STRB; \ + node = bfdev_rb_entry(walk, STSTRUCT, STRB); \ + walk = node->STRB.right; \ + } while (walk == prev); \ + \ + if (end < STSTART(node)) \ + return NULL; \ + else if (start <= STEND(node)) \ + return node; \ + } \ } BFDEV_END_DECLS -#endif /* _BFDEV_SEGTREE_ */ +#endif /* _BFDEV_SEGTREE_H_ */ diff --git a/include/bfdev/skiplist.h b/include/bfdev/skiplist.h index c98c9f87..b845da1b 100644 --- a/include/bfdev/skiplist.h +++ b/include/bfdev/skiplist.h @@ -30,8 +30,8 @@ struct bfdev_skip_head { }; extern int -bfdev_skiplist_insert(bfdev_skip_head_t *head, void *key, - bfdev_cmp_t cmp, void *pdata); +bfdev_skiplist_insert(bfdev_skip_head_t *head, void *key, bfdev_cmp_t cmp, + void *pdata); extern void bfdev_skiplist_delete(bfdev_skip_head_t *head, bfdev_find_t find, void *pdata); @@ -40,14 +40,16 @@ extern bfdev_skip_node_t * bfdev_skiplist_find(bfdev_skip_head_t *head, bfdev_find_t find, void *pdata); extern void -bfdev_skiplist_reset(bfdev_skip_head_t *head, bfdev_release_t relse); - -extern void -bfdev_skiplist_destroy(bfdev_skip_head_t *head, bfdev_release_t relse); +bfdev_skiplist_reset(bfdev_skip_head_t *head, bfdev_release_t release, + void *pdata); extern bfdev_skip_head_t * bfdev_skiplist_create(const bfdev_alloc_t *alloc, unsigned int levels); +extern void +bfdev_skiplist_destroy(bfdev_skip_head_t *head, bfdev_release_t release, + void *pdata); + /** * bfdev_skiplist_for_each - iterate over list of given type. * @pos: the type * to use as a loop cursor. diff --git a/include/bfdev/slist.h b/include/bfdev/slist.h index c5a87bbc..48516def 100644 --- a/include/bfdev/slist.h +++ b/include/bfdev/slist.h @@ -20,18 +20,22 @@ struct bfdev_slist_head { bfdev_slist_head_t *next; }; -#define BFDEV_SLIST_HEAD_STATIC \ - {NULL} +#define BFDEV_SLIST_HEAD_STATIC() { \ + .next = NULL, \ +} -#define BFDEV_SLIST_HEAD_INIT \ - (bfdev_slist_head_t) BFDEV_SLIST_HEAD_STATIC +#define BFDEV_SLIST_HEAD_INIT() \ + (bfdev_slist_head_t) BFDEV_SLIST_HEAD_STATIC() #define BFDEV_SLIST_HEAD(name) \ - bfdev_slist_head_t name = BFDEV_SLIST_HEAD_INIT + bfdev_slist_head_t name = BFDEV_SLIST_HEAD_INIT() #ifdef BFDEV_DEBUG_SLIST -extern bool bfdev_slist_check_add(bfdev_slist_head_t *node, bfdev_slist_head_t *newn); -extern bool bfdev_slist_check_del(bfdev_slist_head_t *node); +extern bool +bfdev_slist_check_add(bfdev_slist_head_t *node, bfdev_slist_head_t *newn); + +extern bool +bfdev_slist_check_del(bfdev_slist_head_t *node); #endif /** @@ -41,7 +45,7 @@ extern bool bfdev_slist_check_del(bfdev_slist_head_t *node); static inline void bfdev_slist_head_init(bfdev_slist_head_t *head) { - head->next = NULL; + *head = BFDEV_SLIST_HEAD_INIT(); } /** @@ -64,7 +68,7 @@ bfdev_slist_add(bfdev_slist_head_t *node, bfdev_slist_head_t *newn) /** * bfdev_slist_del - delete a node from slist. * @head: the head of the slist. - * @entry: the element to delete from the slist. + * @node: the element to delete from the slist. */ static inline void bfdev_slist_del(bfdev_slist_head_t *head, bfdev_slist_head_t *node) diff --git a/include/bfdev/types.h b/include/bfdev/types.h index ac71a647..cd3402c0 100644 --- a/include/bfdev/types.h +++ b/include/bfdev/types.h @@ -26,25 +26,33 @@ typedef uint16_t __bfdev_bitwise bfdev_be16; typedef uint32_t __bfdev_bitwise bfdev_be32; typedef uint64_t __bfdev_bitwise bfdev_be64; -typedef int bfdev_qi_t __bfdev_mode(QI); -typedef int bfdev_hi_t __bfdev_mode(HI); -typedef int bfdev_si_t __bfdev_mode(SI); -typedef int bfdev_di_t __bfdev_mode(DI); +typedef int bfdev_sqi_t __bfdev_mode(QI); +typedef int bfdev_shi_t __bfdev_mode(HI); +typedef int bfdev_ssi_t __bfdev_mode(SI); +typedef int bfdev_sdi_t __bfdev_mode(DI); typedef unsigned bfdev_uqi_t __bfdev_mode(QI); typedef unsigned bfdev_uhi_t __bfdev_mode(HI); typedef unsigned bfdev_usi_t __bfdev_mode(SI); typedef unsigned bfdev_udi_t __bfdev_mode(DI); + +typedef long bfdev_sw_t; typedef unsigned long bfdev_uw_t; #if BFDEV_BITS_PER_LONG == 32 +typedef bfdev_shi_t bfdev_shw_t; typedef bfdev_uhi_t bfdev_uhw_t; #else /* BFDEV_BITS_PER_LONG == 64 */ +typedef bfdev_ssi_t bfdev_shw_t; typedef bfdev_usi_t bfdev_uhw_t; #endif typedef int bfdev_state_t; typedef intptr_t bfdev_atomic_t; +#define BFDEV_EQ 0 +#define BFDEV_BT 1 +#define BFDEV_LT -1 + #define BFDEV_BYTES_PER_CHAR sizeof(char) #define BFDEV_BYTES_PER_SHORT sizeof(short) #define BFDEV_BYTES_PER_INT sizeof(int) @@ -65,12 +73,12 @@ typedef intptr_t bfdev_atomic_t; #define BFDEV_CALLBACK_CMP(name, type) \ typedef long (*name)(type key1, type key2, void *pdata) -#define BFDEV_CALLBACK_RELEASE(name) \ - typedef void (*name)(void *pdata) +#define BFDEV_CALLBACK_RELEASE(name, type) \ + typedef void (*name)(type value, void *pdata) BFDEV_CALLBACK_FIND(bfdev_find_t, const void *); BFDEV_CALLBACK_CMP(bfdev_cmp_t, const void *); -BFDEV_CALLBACK_RELEASE(bfdev_release_t); +BFDEV_CALLBACK_RELEASE(bfdev_release_t, void *); typedef void *(*bfdev_malloc_t)(size_t size, void *pdata); typedef void *(*bfdev_realloc_t)(void *block, size_t resize, void *pdata); diff --git a/include/port/allocator.h b/include/port/allocator.h new file mode 100644 index 00000000..cce3a01e --- /dev/null +++ b/include/port/allocator.h @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright(c) 2024 John Sanpe + */ + +#ifndef _LOCAL_PORT_ALLOCATOR_H_ +#define _LOCAL_PORT_ALLOCATOR_H_ + +#include +#include + +#ifndef __INSIDE_ALLOCATOR__ +# error "please don't include this file directly" +#endif + +static __bfdev_always_inline void * +generic_alloc(size_t size, void *pdata) +{ + void *retval; + + if (bfdev_alloc_default.alloc) { + retval = bfdev_alloc_default.alloc(size, pdata); + return retval; + } + + return malloc(size); +} + +static __bfdev_always_inline void * +generic_zalloc(size_t size, void *pdata) +{ + void *retval; + + if (bfdev_alloc_default.zalloc) { + retval = bfdev_alloc_default.zalloc(size, pdata); + return retval; + } + + return calloc(1, size); +} + +static __bfdev_always_inline void * +generic_realloc(void *block, size_t resize, void *pdata) +{ + void *retval; + + if (bfdev_alloc_default.realloc) { + retval = bfdev_alloc_default.realloc(block, resize, pdata); + return retval; + } + + return realloc(block, resize); +} + +static __bfdev_always_inline void +generic_free(void *block, void *pdata) +{ + if (bfdev_alloc_default.free) { + bfdev_alloc_default.free(block, pdata); + return; + } + + free((void *)block); +} + +#endif /* _LOCAL_PORT_ALLOCATOR_H_ */ diff --git a/scripts/gen-crc.c b/scripts/gen-crc.c index 9ee71397..06ae2546 100644 --- a/scripts/gen-crc.c +++ b/scripts/gen-crc.c @@ -28,9 +28,9 @@ table_generic(unsigned int rows, GENCRC_TYPE poly, GENCRC_TYPE (*table)[CRC_TABLE_SIZE]) { unsigned int count, index; - GENCRC_TYPE crc = 1; + GENCRC_TYPE crc; - table[0][0] = 0; + crc = 1; for (count = CRC_TABLE_SIZE >> 1; count; count >>= 1) { crc = (crc >> 1) ^ ((crc & 1) ? poly : 0); for (index = 0; index < CRC_TABLE_SIZE; index += 2 * count) @@ -51,9 +51,9 @@ table_generic(unsigned int rows, GENCRC_TYPE poly, GENCRC_TYPE (*table)[CRC_TABLE_SIZE]) { unsigned int count, index; - GENCRC_TYPE crc = 1ULL << (GENCRC_BITS - 1); + GENCRC_TYPE crc; - table[0][0] = 0; + crc = 1ULL << (GENCRC_BITS - 1); for (count = 1; count < CRC_TABLE_SIZE; count <<= 1) { crc = (crc << 1) ^ ((crc & (1ULL << (GENCRC_BITS - 1))) ? poly : 0); for (index = 0; index < count; ++index) @@ -81,8 +81,16 @@ table_dump(unsigned int rows, const char *trans, for (count = 0; count < CRC_TABLE_SIZE; ++count) { if (count % ENTRIES_PER_LINE == 0) printf("\n\t\t"); - printf("%s((" TYPE_STRING ")0x%" WIDE_STRING "." WIDE_STRING "llxULL), ", - trans, (unsigned long long)table[index][count]); + + if (trans) { + printf("%s((" TYPE_STRING ")0x%" WIDE_STRING "." + WIDE_STRING "llxULL), ", trans, + (unsigned long long)table[index][count]); + } else { + printf("(" TYPE_STRING ")0x%" WIDE_STRING + "." WIDE_STRING "llxULL, ", + (unsigned long long)table[index][count]); + } } printf("\n\t},\n"); } @@ -90,33 +98,48 @@ table_dump(unsigned int rows, const char *trans, int main(int argc, char *argv[]) { - GENCRC_TYPE poly, table[8][256]; - const char *trans = ""; + const char *trans, *name; unsigned int rows; + GENCRC_TYPE poly; + void *table; - if (argc < 4) { - printf("gen-" NAME_STRING ": name rows poly trans\n"); + if (argc != 4 && argc != 5) { + printf("usage: %s name rows poly [trans]\n", argv[0]); return -1; } - if (argc > 4) + trans = NULL; + if (argc == 5) trans = argv[4]; + name = argv[1]; rows = (unsigned int)strtoul(argv[2], NULL, 0); poly = (GENCRC_TYPE)strtoull(argv[3], NULL, 0); + if (!rows) { + fprintf(stderr, "error: rows cannot be zero\n"); + return -1; + } + + table = calloc(1, sizeof(GENCRC_TYPE) * CRC_TABLE_SIZE * rows); + if (!table) + return -1; + printf("/*\n"); printf(" * Automatically generated file; DO NOT EDIT.\n"); printf(" * bfdev scripts/gen-" NAME_STRING "\n"); printf(" */\n\n"); printf("/* The poly is 0x%" WIDE_STRING "." WIDE_STRING "llx */\n", - (unsigned long long)poly); + (unsigned long long)poly); printf("static const " TYPE_STRING " %s[%d][%d] = {\n", - argv[1], rows, CRC_TABLE_SIZE); + name, rows, CRC_TABLE_SIZE); + table_generic(rows, poly, table); table_dump(rows, trans, table); + printf("};\n"); + free(table); return 0; } diff --git a/scripts/sanitize.cmake b/scripts/sanitize.cmake new file mode 100644 index 00000000..a9cda3cf --- /dev/null +++ b/scripts/sanitize.cmake @@ -0,0 +1,43 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright(c) 2024 John Sanpe +# + +if(BFDEV_ASAN) + set(CMAKE_C_FLAGS + "${CMAKE_C_FLAGS} \ + -fsanitize=address \ + -fsanitize=undefined \ + -fsanitize-recover=all \ + -fno-omit-frame-pointer \ + -fno-stack-protector" + ) + if(NOT APPLE) + set(CMAKE_C_FLAGS + "${CMAKE_C_FLAGS} \ + -fsanitize=leak" + ) + endif() +endif() + +if(BFDEV_UBSAN) + set(CMAKE_C_FLAGS + "${CMAKE_C_FLAGS} \ + -fsanitize=alignment \ + -fsanitize=bounds \ + -fsanitize=shift \ + -fsanitize=integer-divide-by-zero \ + -fsanitize=unreachable \ + -fsanitize=bool \ + -fsanitize=enum \ + -fsanitize-undefined-trap-on-error" + ) +endif() + +if(BFDEV_GCOV) + set(CMAKE_C_FLAGS + "${CMAKE_C_FLAGS} \ + -fprofile-arcs \ + -ftest-coverage" + ) +endif() diff --git a/src/allocator.c b/src/allocator.c index dc7b7cfa..ca48e929 100644 --- a/src/allocator.c +++ b/src/allocator.c @@ -10,41 +10,8 @@ export bfdev_alloc_ops_t bfdev_alloc_default; -static __bfdev_always_inline void * -generic_alloc(size_t size, void *pdata) -{ - if (!bfdev_alloc_default.alloc) - return malloc(size); - - return bfdev_alloc_default.alloc(size, pdata); -} - -static __bfdev_always_inline void * -generic_zalloc(size_t size, void *pdata) -{ - if (!bfdev_alloc_default.zalloc) - return calloc(1, size); - - return bfdev_alloc_default.zalloc(size, pdata); -} - -static __bfdev_always_inline void * -generic_realloc(void *block, size_t resize, void *pdata) -{ - if (!bfdev_alloc_default.realloc) - return realloc(block, resize); - - return bfdev_alloc_default.realloc(block, resize, pdata); -} - -static __bfdev_always_inline void -generic_free(void *block, void *pdata) -{ - if (!bfdev_alloc_default.free) - return free((void *)block); - - return bfdev_alloc_default.free(block, pdata); -} +#define __INSIDE_ALLOCATOR__ +#include static inline const bfdev_alloc_ops_t * alloc_check(const bfdev_alloc_t *alloc, void **pdata) @@ -87,7 +54,7 @@ bfdev_zalloc(const bfdev_alloc_t *alloc, size_t size) ops = alloc_check(alloc, &pdata); if (!ops || !ops->zalloc) - return generic_zalloc(size, pdata); + retval = generic_zalloc(size, pdata); else retval = ops->zalloc(size, pdata); diff --git a/src/argv.c b/src/argv.c index a83d0a93..01763745 100644 --- a/src/argv.c +++ b/src/argv.c @@ -12,9 +12,10 @@ export unsigned int bfdev_argv_count(const char *args) { - unsigned int argc = 0; + unsigned int argc; size_t offset; + argc = 0; for (;;) { offset = strspn(args, ARGV_SEPARA); if (!args[offset]) diff --git a/src/array.c b/src/array.c index b5f41561..0633b6db 100644 --- a/src/array.c +++ b/src/array.c @@ -12,7 +12,7 @@ static inline int array_resize(bfdev_array_t *array, unsigned long count) { - const bfdev_alloc_t *alloc = array->alloc; + const bfdev_alloc_t *alloc; unsigned long nalloc; size_t size; void *data; @@ -20,6 +20,7 @@ array_resize(bfdev_array_t *array, unsigned long count) nalloc = bfdev_max(count, BFDEV_ARRAY_MSIZE); size = nalloc * array->cells; + alloc = array->alloc; data = bfdev_realloc(alloc, array->data, size); if (bfdev_unlikely(!data)) return -BFDEV_ENOMEM; @@ -123,11 +124,12 @@ bfdev_array_reserve(bfdev_array_t *array, unsigned long num) export void bfdev_array_release(bfdev_array_t *array) { - const bfdev_alloc_t *alloc = array->alloc; + const bfdev_alloc_t *alloc; array->capacity = 0; array->index = 0; + alloc = array->alloc; bfdev_free(alloc, array->data); array->data = NULL; } diff --git a/src/bitmap.c b/src/bitmap.c index fb0c3260..19298cdb 100644 --- a/src/bitmap.c +++ b/src/bitmap.c @@ -78,9 +78,11 @@ bfdev_bitmap_comp_and(unsigned long *dest, const unsigned long *src1, const unsigned long *src2, unsigned int bits) { unsigned int index, length; - unsigned long value, result = 0; + unsigned long value, result; + result = 0; length = BFDEV_BITS_DIV_LONG(bits); + for (index = 0; index < length; ++index) { value = src1[index] & src2[index]; result |= (dest[index] = value); @@ -99,9 +101,11 @@ bfdev_bitmap_comp_andnot(unsigned long *dest, const unsigned long *src1, const unsigned long *src2, unsigned int bits) { unsigned int index, length; - unsigned long value, result = 0; + unsigned long value, result; + result = 0; length = BFDEV_BITS_DIV_LONG(bits); + for (index = 0; index < length; ++index) { value = src1[index] & ~src2[index]; result |= (dest[index] = value); diff --git a/src/bitwalk.c b/src/bitwalk.c index bb96528a..3a169fea 100644 --- a/src/bitwalk.c +++ b/src/bitwalk.c @@ -4,12 +4,13 @@ */ #include -#include +#include #include #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, bool swap) { unsigned int base; @@ -30,7 +31,8 @@ bfdev_comp_find_first_bit(const unsigned long *block, unsigned int bits, bool sw } export unsigned int -bfdev_comp_find_last_bit(const unsigned long *block, unsigned int bits, bool swap) +bfdev_comp_find_last_bit(const unsigned long *block, + unsigned int bits, bool swap) { if (bits) { unsigned long val = BFDEV_BIT_LOW_MASK(bits); @@ -54,7 +56,8 @@ bfdev_comp_find_last_bit(const unsigned long *block, unsigned int bits, bool swa } export unsigned int -bfdev_comp_find_first_zero(const unsigned long *block, unsigned int bits, bool swap) +bfdev_comp_find_first_zero(const unsigned long *block, + unsigned int bits, bool swap) { unsigned int base; @@ -75,7 +78,8 @@ bfdev_comp_find_first_zero(const unsigned long *block, unsigned int bits, bool s } export unsigned int -bfdev_comp_find_last_zero(const unsigned long *block, unsigned int bits, bool swap) +bfdev_comp_find_last_zero(const unsigned long *block, + unsigned int bits, bool swap) { if (bits) { unsigned long val = BFDEV_BIT_LOW_MASK(bits); @@ -152,7 +156,7 @@ bfdev_comp_find_prev_bit(const unsigned long *addr1, const unsigned long *addr2, value &= addr2[BFDEV_BITS_DIV_LONG(start)]; value ^= invert; - mask = BFDEV_BIT_HIGH_MASK(start); + mask = BFDEV_BIT_LOW_MASK(start + 1); if (swap) mask = bfdev_swab(mask); diff --git a/src/bloom.c b/src/bloom.c index c31be65e..3f7bc14c 100644 --- a/src/bloom.c +++ b/src/bloom.c @@ -24,8 +24,9 @@ export bool bfdev_bloom_peek(bfdev_bloom_t *bloom, void *key) { unsigned int index, func; - bool retval = true; + bool retval; + retval = true; for (func = 0; func < bloom->funcs; ++func) { index = bloom_index(bloom, func, key); if (!bfdev_bit_test(bloom->bitmap, index)) @@ -39,8 +40,9 @@ export bool bfdev_bloom_push(bfdev_bloom_t *bloom, void *key) { unsigned int index, func; - bool retval = true; + bool retval; + retval = true; for (func = 0; func < bloom->funcs; ++func) { index = bloom_index(bloom, func, key); if (!bfdev_bit_test_set(bloom->bitmap, index)) @@ -83,6 +85,8 @@ bfdev_bloom_create(const bfdev_alloc_t *alloc, unsigned int capacity, export void bfdev_bloom_destory(bfdev_bloom_t *bloom) { - const bfdev_alloc_t *alloc = bloom->alloc; + const bfdev_alloc_t *alloc; + + alloc = bloom->alloc; bfdev_free(alloc, bloom); } diff --git a/src/btree-utils.c b/src/btree-utils.c index 24f07fa3..c2b1ab72 100644 --- a/src/btree-utils.c +++ b/src/btree-utils.c @@ -8,11 +8,11 @@ #include #define BLOCK_SIZE 128 -#define NODE_SIZE (BLOCK_SIZE - sizeof(struct bfdev_btree_node)) +#define NODE_SIZE (BLOCK_SIZE - sizeof(bfdev_btree_node_t)) #define UINTPTR_PER_U32 BFDEV_DIV_ROUND_UP(BFDEV_BYTES_PER_U32, BFDEV_BYTES_PER_UINTPTR) #define UINTPTR_PER_U64 BFDEV_DIV_ROUND_UP(BFDEV_BYTES_PER_U64, BFDEV_BYTES_PER_UINTPTR) -export struct bfdev_btree_layout +export bfdev_btree_layout_t bfdev_btree_layout32 = { .keylen = UINTPTR_PER_U32, .keynum = NODE_SIZE / sizeof(uintptr_t) / (UINTPTR_PER_U32 + 1), @@ -20,7 +20,7 @@ bfdev_btree_layout32 = { .nodesize = NODE_SIZE, }; -export struct bfdev_btree_layout +export bfdev_btree_layout_t bfdev_btree_layout64 = { .keylen = UINTPTR_PER_U64, .keynum = NODE_SIZE / sizeof(uintptr_t) / (UINTPTR_PER_U64 + 1), @@ -28,7 +28,7 @@ bfdev_btree_layout64 = { .nodesize = NODE_SIZE, }; -export struct bfdev_btree_layout +export bfdev_btree_layout_t bfdev_btree_layoutptr = { .keylen = 1, .keynum = NODE_SIZE / sizeof(uintptr_t) / 2, @@ -37,9 +37,9 @@ bfdev_btree_layoutptr = { }; export long -bfdev_btree_key_find(struct bfdev_btree_root *root, uintptr_t *node, uintptr_t *key) +bfdev_btree_key_find(bfdev_btree_root_t *root, uintptr_t *node, uintptr_t *key) { - struct bfdev_btree_layout *layout; + bfdev_btree_layout_t *layout; unsigned int index; layout = root->layout; @@ -54,10 +54,10 @@ bfdev_btree_key_find(struct bfdev_btree_root *root, uintptr_t *node, uintptr_t * } export void * -bfdev_btree_alloc(struct bfdev_btree_root *root) +bfdev_btree_alloc(bfdev_btree_root_t *root) { const bfdev_alloc_t *alloc; - struct bfdev_btree_layout *layout; + bfdev_btree_layout_t *layout; alloc = root->alloc; layout = root->layout; @@ -66,9 +66,10 @@ bfdev_btree_alloc(struct bfdev_btree_root *root) } export void -bfdev_btree_free(struct bfdev_btree_root *root, void *node) +bfdev_btree_free(bfdev_btree_root_t *root, void *node) { const bfdev_alloc_t *alloc; + alloc = root->alloc; bfdev_free(alloc, node); } diff --git a/src/btree.c b/src/btree.c index dcc85a49..32ba524b 100644 --- a/src/btree.c +++ b/src/btree.c @@ -8,10 +8,10 @@ #include static __bfdev_always_inline void * -bnode_get_value(struct bfdev_btree_root *root, struct bfdev_btree_node *node, +bnode_get_value(bfdev_btree_root_t *root, bfdev_btree_node_t *node, unsigned int index) { - struct bfdev_btree_layout *layout; + bfdev_btree_layout_t *layout; unsigned int offset; layout = root->layout; @@ -21,10 +21,10 @@ bnode_get_value(struct bfdev_btree_root *root, struct bfdev_btree_node *node, } static __bfdev_always_inline void -bnode_set_value(struct bfdev_btree_root *root, struct bfdev_btree_node *node, +bnode_set_value(bfdev_btree_root_t *root, bfdev_btree_node_t *node, unsigned int index, void *value) { - struct bfdev_btree_layout *layout; + bfdev_btree_layout_t *layout; unsigned int offset; layout = root->layout; @@ -34,10 +34,10 @@ bnode_set_value(struct bfdev_btree_root *root, struct bfdev_btree_node *node, } static __bfdev_always_inline uintptr_t * -bnode_get_key(struct bfdev_btree_root *root, struct bfdev_btree_node *node, +bnode_get_key(bfdev_btree_root_t *root, bfdev_btree_node_t *node, unsigned int index) { - struct bfdev_btree_layout *layout; + bfdev_btree_layout_t *layout; unsigned int offset; layout = root->layout; @@ -47,10 +47,10 @@ bnode_get_key(struct bfdev_btree_root *root, struct bfdev_btree_node *node, } static __bfdev_always_inline void -bnode_set_key(struct bfdev_btree_root *root, struct bfdev_btree_node *node, +bnode_set_key(bfdev_btree_root_t *root, bfdev_btree_node_t *node, unsigned int index, uintptr_t *key) { - struct bfdev_btree_layout *layout; + bfdev_btree_layout_t *layout; uintptr_t *slot; size_t size; @@ -62,10 +62,10 @@ bnode_set_key(struct bfdev_btree_root *root, struct bfdev_btree_node *node, } static inline long -bnode_cmp_key(struct bfdev_btree_root *root, struct bfdev_btree_node *node, +bnode_cmp_key(bfdev_btree_root_t *root, bfdev_btree_node_t *node, unsigned int index, uintptr_t *key) { - const struct bfdev_btree_ops *ops; + const bfdev_btree_ops_t *ops; uintptr_t *slot; ops = root->ops; @@ -75,10 +75,10 @@ bnode_cmp_key(struct bfdev_btree_root *root, struct bfdev_btree_node *node, } static inline void -bnode_takeout_key(struct bfdev_btree_root *root, struct bfdev_btree_node *node, +bnode_takeout_key(bfdev_btree_root_t *root, bfdev_btree_node_t *node, unsigned int index, uintptr_t *key) { - struct bfdev_btree_layout *layout; + bfdev_btree_layout_t *layout; uintptr_t *slot; size_t size; @@ -90,10 +90,10 @@ bnode_takeout_key(struct bfdev_btree_root *root, struct bfdev_btree_node *node, } static inline void -bnode_clear_index(struct bfdev_btree_root *root, struct bfdev_btree_node *node, +bnode_clear_index(bfdev_btree_root_t *root, bfdev_btree_node_t *node, unsigned int index) { - struct bfdev_btree_layout *layout; + bfdev_btree_layout_t *layout; uintptr_t *slot; size_t size; @@ -106,9 +106,9 @@ bnode_clear_index(struct bfdev_btree_root *root, struct bfdev_btree_node *node, } static inline bool -btree_empty_key(struct bfdev_btree_root *root, uintptr_t *key) +btree_empty_key(bfdev_btree_root_t *root, uintptr_t *key) { - struct bfdev_btree_layout *layout; + bfdev_btree_layout_t *layout; unsigned int count; layout = root->layout; @@ -121,9 +121,9 @@ btree_empty_key(struct bfdev_btree_root *root, uintptr_t *key) } static inline void -bnode_migrate(struct bfdev_btree_root *root, - struct bfdev_btree_node *nnode, unsigned nindex, - struct bfdev_btree_node *onode, unsigned oindex) +bnode_migrate(bfdev_btree_root_t *root, + bfdev_btree_node_t *nnode, unsigned nindex, + bfdev_btree_node_t *onode, unsigned oindex) { void *slot; @@ -134,12 +134,12 @@ bnode_migrate(struct bfdev_btree_root *root, bnode_set_value(root, nnode, nindex, slot); } -static inline struct bfdev_btree_node * -bnode_alloc(struct bfdev_btree_root *root) +static inline bfdev_btree_node_t * +bnode_alloc(bfdev_btree_root_t *root) { - const struct bfdev_btree_ops *ops; - struct bfdev_btree_layout *layout; - struct bfdev_btree_node *node; + const bfdev_btree_ops_t *ops; + bfdev_btree_layout_t *layout; + bfdev_btree_node_t *node; layout = root->layout; ops = root->ops; @@ -152,18 +152,20 @@ bnode_alloc(struct bfdev_btree_root *root) } static inline void -bnode_free(struct bfdev_btree_root *root, struct bfdev_btree_node *node) +bnode_free(bfdev_btree_root_t *root, bfdev_btree_node_t *node) { - const struct bfdev_btree_ops *ops; + const bfdev_btree_ops_t *ops; + ops = root->ops; + return ops->free(root, node); } static unsigned int -bnode_fill_index(struct bfdev_btree_root *root, struct bfdev_btree_node *node, +bnode_fill_index(bfdev_btree_root_t *root, bfdev_btree_node_t *node, unsigned int start) { - struct bfdev_btree_layout *layout; + bfdev_btree_layout_t *layout; unsigned int index; layout = root->layout; @@ -176,10 +178,10 @@ bnode_fill_index(struct bfdev_btree_root *root, struct bfdev_btree_node *node, } static unsigned int -bnode_key_index(struct bfdev_btree_root *root, struct bfdev_btree_node *node, +bnode_key_index(bfdev_btree_root_t *root, bfdev_btree_node_t *node, uintptr_t *key) { - struct bfdev_btree_layout *layout; + bfdev_btree_layout_t *layout; unsigned int index; long retval; @@ -195,12 +197,11 @@ bnode_key_index(struct bfdev_btree_root *root, struct bfdev_btree_node *node, return layout->keynum; } -static struct bfdev_btree_node * -bnode_find_parent(struct bfdev_btree_root *root, uintptr_t *key, - unsigned int level) +static bfdev_btree_node_t * +bnode_find_parent(bfdev_btree_root_t *root, uintptr_t *key, unsigned int level) { - struct bfdev_btree_layout *layout; - struct bfdev_btree_node *node; + bfdev_btree_layout_t *layout; + bfdev_btree_node_t *node; unsigned int height, index; layout = root->layout; @@ -222,10 +223,10 @@ bnode_find_parent(struct bfdev_btree_root *root, uintptr_t *key, } static unsigned int -bnode_find_index(struct bfdev_btree_root *root, struct bfdev_btree_node *node, +bnode_find_index(bfdev_btree_root_t *root, bfdev_btree_node_t *node, uintptr_t *key) { - struct bfdev_btree_layout *layout; + bfdev_btree_layout_t *layout; unsigned int index; layout = root->layout; @@ -237,11 +238,11 @@ bnode_find_index(struct bfdev_btree_root *root, struct bfdev_btree_node *node, return index; } -static struct bfdev_btree_node * -bnode_lookup(struct bfdev_btree_root *root, uintptr_t *key) +static bfdev_btree_node_t * +bnode_lookup(bfdev_btree_root_t *root, uintptr_t *key) { - struct bfdev_btree_layout *layout; - struct bfdev_btree_node *node; + bfdev_btree_layout_t *layout; + bfdev_btree_node_t *node; unsigned int height, index; height = root->height; @@ -269,10 +270,10 @@ bnode_lookup(struct bfdev_btree_root *root, uintptr_t *key) } export void * -bfdev_btree_lookup(struct bfdev_btree_root *root, uintptr_t *key) +bfdev_btree_lookup(bfdev_btree_root_t *root, uintptr_t *key) { - struct bfdev_btree_layout *layout; - struct bfdev_btree_node *node; + bfdev_btree_layout_t *layout; + bfdev_btree_node_t *node; unsigned int index; node = bnode_lookup(root, key); @@ -289,10 +290,10 @@ bfdev_btree_lookup(struct bfdev_btree_root *root, uintptr_t *key) } export int -bfdev_btree_update(struct bfdev_btree_root *root, uintptr_t *key, void *value) +bfdev_btree_update(bfdev_btree_root_t *root, uintptr_t *key, void *value) { - struct bfdev_btree_layout *layout; - struct bfdev_btree_node *node; + bfdev_btree_layout_t *layout; + bfdev_btree_node_t *node; unsigned int index; node = bnode_lookup(root, key); @@ -310,9 +311,9 @@ bfdev_btree_update(struct bfdev_btree_root *root, uintptr_t *key, void *value) } static int -btree_extend(struct bfdev_btree_root *root) +btree_extend(bfdev_btree_root_t *root) { - struct bfdev_btree_node *node; + bfdev_btree_node_t *node; unsigned int index; uintptr_t *slot; @@ -334,9 +335,9 @@ btree_extend(struct bfdev_btree_root *root) } static void -btree_shrink(struct bfdev_btree_root *root) +btree_shrink(bfdev_btree_root_t *root) { - struct bfdev_btree_node *node; + bfdev_btree_node_t *node; if (root->height < 2) return; @@ -349,12 +350,12 @@ btree_shrink(struct bfdev_btree_root *root) } static int -insert_level(struct bfdev_btree_root *root, unsigned int level, +insert_level(bfdev_btree_root_t *root, unsigned int level, uintptr_t *key, void *value) { - const struct bfdev_btree_ops *ops; - struct bfdev_btree_layout *layout; - struct bfdev_btree_node *node, *newn; + const bfdev_btree_ops_t *ops; + bfdev_btree_layout_t *layout; + bfdev_btree_node_t *node, *newn; unsigned int index, fill, count; uintptr_t *halfkey; int retval; @@ -420,13 +421,13 @@ insert_level(struct bfdev_btree_root *root, unsigned int level, } static void * -remove_level(struct bfdev_btree_root *root, unsigned int level, uintptr_t *key); +remove_level(bfdev_btree_root_t *root, unsigned int level, uintptr_t *key); static void -rebalance_merge(struct bfdev_btree_root *root, unsigned int level, - struct bfdev_btree_node *lnode, unsigned int lfill, - struct bfdev_btree_node *rnode, unsigned int rfill, - struct bfdev_btree_node *parent, unsigned int index) +rebalance_merge(bfdev_btree_root_t *root, unsigned int level, + bfdev_btree_node_t *lnode, unsigned int lfill, + bfdev_btree_node_t *rnode, unsigned int rfill, + bfdev_btree_node_t *parent, unsigned int index) { unsigned int count; @@ -441,12 +442,11 @@ rebalance_merge(struct bfdev_btree_root *root, unsigned int level, } static void -remove_rebalance(struct bfdev_btree_root *root, unsigned int level, - uintptr_t *key, struct bfdev_btree_node *child, - unsigned int fill) +remove_rebalance(bfdev_btree_root_t *root, unsigned int level, uintptr_t *key, + bfdev_btree_node_t *child, unsigned int fill) { - struct bfdev_btree_layout *layout; - struct bfdev_btree_node *parent, *node; + bfdev_btree_layout_t *layout; + bfdev_btree_node_t *parent, *node; unsigned int index, nfill; if (!fill) { @@ -485,14 +485,13 @@ remove_rebalance(struct bfdev_btree_root *root, unsigned int level, } static void * -remove_level(struct bfdev_btree_root *root, unsigned int level, - uintptr_t *key) +remove_level(bfdev_btree_root_t *root, unsigned int level, uintptr_t *key) { - const struct bfdev_btree_ops *ops; - struct bfdev_btree_layout *layout; - struct bfdev_btree_node *node; + const bfdev_btree_ops_t *ops; + bfdev_btree_layout_t *layout; + bfdev_btree_node_t *node; unsigned int index, last, count; - void *clash, *value = NULL; + void *clash, *value; if (level > root->height) { root->height = 0; @@ -507,6 +506,7 @@ remove_level(struct bfdev_btree_root *root, unsigned int level, index = bnode_find_index(root, node, key); last = bnode_fill_index(root, node, index) - 1; + value = NULL; if (level == 1) { if (bnode_cmp_key(root, node, index, key)) return NULL; @@ -536,25 +536,28 @@ remove_level(struct bfdev_btree_root *root, unsigned int level, } export int -bfdev_btree_insert(struct bfdev_btree_root *root, uintptr_t *key, void *value) +bfdev_btree_insert(bfdev_btree_root_t *root, uintptr_t *key, void *value) { if (bfdev_unlikely(!value)) return -BFDEV_EINVAL; + return insert_level(root, 1, key, value); } export void * -bfdev_btree_remove(struct bfdev_btree_root *root, uintptr_t *key) +bfdev_btree_remove(bfdev_btree_root_t *root, uintptr_t *key) { if (bfdev_unlikely(!root->height)) return NULL; + return remove_level(root, 1, key); } export void -bfdev_btree_destroy(struct bfdev_btree_root *root) +bfdev_btree_release(bfdev_btree_root_t *root, bfdev_release_t release, + void *pdata) { - struct bfdev_btree_layout *layout; + bfdev_btree_layout_t *layout; uintptr_t *key, *tkey; void *value, *tval; @@ -562,8 +565,11 @@ bfdev_btree_destroy(struct bfdev_btree_root *root) key = bfdev_alloca(sizeof(uintptr_t) * layout->keylen); tkey = bfdev_alloca(sizeof(uintptr_t) * layout->keylen); - bfdev_btree_for_each_safe(root, key, value, tkey, tval) + bfdev_btree_for_each_safe(root, key, value, tkey, tval) { + if (release) + release(value, pdata); bfdev_btree_remove(root, key); + } bnode_free(root, root->node); root->node = NULL; @@ -571,18 +577,18 @@ bfdev_btree_destroy(struct bfdev_btree_root *root) } export void -bfdev_btree_key_copy(struct bfdev_btree_root *root, - uintptr_t *dest, uintptr_t *src) +bfdev_btree_key_copy(bfdev_btree_root_t *root, uintptr_t *dest, uintptr_t *src) { - struct bfdev_btree_layout *layout; + bfdev_btree_layout_t *layout; + layout = root->layout; memcpy(dest, src, layout->keylen * sizeof(uintptr_t)); } export void * -bfdev_btree_first(struct bfdev_btree_root *root, uintptr_t *key) +bfdev_btree_first(bfdev_btree_root_t *root, uintptr_t *key) { - struct bfdev_btree_node *node; + bfdev_btree_node_t *node; unsigned int height; height = root->height; @@ -598,9 +604,9 @@ bfdev_btree_first(struct bfdev_btree_root *root, uintptr_t *key) } export void * -bfdev_btree_last(struct bfdev_btree_root *root, uintptr_t *key) +bfdev_btree_last(bfdev_btree_root_t *root, uintptr_t *key) { - struct bfdev_btree_node *node; + bfdev_btree_node_t *node; unsigned int last, height; height = root->height; @@ -619,15 +625,20 @@ bfdev_btree_last(struct bfdev_btree_root *root, uintptr_t *key) } export void * -bfdev_btree_next(struct bfdev_btree_root *root, uintptr_t *key) +bfdev_btree_next(bfdev_btree_root_t *root, uintptr_t *key) { - struct bfdev_btree_node *node; + bfdev_btree_node_t *node; unsigned int depth, index, fill; + unsigned int height; + + height = root->height; + if (bfdev_unlikely(!height)) + return NULL; if (btree_empty_key(root, key)) return NULL; - for (depth = 1; depth <= root->height; ++depth) { + for (depth = 1; depth <= height; ++depth) { node = bnode_find_parent(root, key, depth); index = bnode_find_index(root, node, key); fill = bnode_fill_index(root, node, index); @@ -635,7 +646,7 @@ bfdev_btree_next(struct bfdev_btree_root *root, uintptr_t *key) break; } - if (depth > root->height) + if (depth > height) return NULL; while (--depth) { @@ -648,22 +659,27 @@ bfdev_btree_next(struct bfdev_btree_root *root, uintptr_t *key) } export void * -bfdev_btree_prev(struct bfdev_btree_root *root, uintptr_t *key) +bfdev_btree_prev(bfdev_btree_root_t *root, uintptr_t *key) { - struct bfdev_btree_node *node; + bfdev_btree_node_t *node; unsigned int depth, index; + unsigned int height; + + height = root->height; + if (bfdev_unlikely(!height)) + return NULL; if (btree_empty_key(root, key)) return NULL; - for (depth = 1; depth <= root->height; ++depth) { + for (depth = 1; depth <= height; ++depth) { node = bnode_find_parent(root, key, depth); index = bnode_find_index(root, node, key); if (index--) break; } - if (depth > root->height) + if (depth > height) return NULL; while (--depth) { diff --git a/src/dword.c b/src/dword.c index 74e6868e..55a9169b 100644 --- a/src/dword.c +++ b/src/dword.c @@ -3,9 +3,13 @@ * Copyright(c) 2024 John Sanpe */ +#define MODULE_NAME "bfdev-dword" +#define bfdev_log_fmt(fmt) MODULE_NAME ": " fmt + #include #include #include +#include #include export void @@ -33,8 +37,7 @@ bfdev_dword_generic_udiv(bfdev_uw_t *quot, bfdev_uw_t *rem, q1 = 0; } else { /* divide by zero */ - if (!div) - div = 1 / div; + BFDEV_BUG_ON(!div); bm = bfdev_clz(div); if (bm == 0) { diff --git a/src/fifo.c b/src/fifo.c index 6d254e64..8d8e1b6e 100644 --- a/src/fifo.c +++ b/src/fifo.c @@ -10,11 +10,12 @@ #include #define FIFO_GENERIC_COPY(copy1, copy2, fold1, fold2) do { \ - unsigned long size = fifo->mask + 1; \ - unsigned long esize = fifo->esize; \ - unsigned long llen; \ + unsigned long size, esize, llen; \ \ + size = fifo->mask + 1; \ + esize = fifo->esize; \ offset &= fifo->mask; \ + \ if (esize != 1) { \ offset *= esize; \ size *= esize; \ @@ -47,10 +48,13 @@ fifo_in_copy(struct bfdev_fifo *fifo, const void *buff, unsigned long len, unsig static __bfdev_always_inline unsigned long fifo_record_peek(struct bfdev_fifo *fifo, unsigned long recsize) { - unsigned long mask = fifo->mask; - unsigned long offset = fifo->out; - unsigned long length = 0; - uint8_t *data = fifo->data; + unsigned long mask, offset, length; + uint8_t *data; + + mask = fifo->mask; + offset = fifo->out; + data = fifo->data; + length = 0; if (fifo->esize != 1) { offset *= fifo->esize; @@ -71,9 +75,12 @@ static __bfdev_always_inline void fifo_record_poke(struct bfdev_fifo *fifo, unsigned long len, unsigned long recsize) { - unsigned long mask = fifo->mask; - unsigned long offset = fifo->out; - uint8_t *data = fifo->data; + unsigned long mask, offset; + uint8_t *data; + + mask = fifo->mask; + offset = fifo->out; + data = fifo->data; if (fifo->esize != 1) { offset *= fifo->esize; @@ -216,13 +223,14 @@ bfdev_fifo_dynamic_alloc(struct bfdev_fifo *fifo, const bfdev_alloc_t *alloc, export void bfdev_fifo_dynamic_free(struct bfdev_fifo *fifo) { - const bfdev_alloc_t *alloc = fifo->alloc; + const bfdev_alloc_t *alloc; fifo->in = 0; fifo->out = 0; fifo->mask = 0; fifo->esize = 0; + alloc = fifo->alloc; bfdev_free(alloc, fifo->data); fifo->data = NULL; } diff --git a/src/fsm.c b/src/fsm.c index 87098be3..51564146 100644 --- a/src/fsm.c +++ b/src/fsm.c @@ -10,8 +10,12 @@ static inline void fsm_push_state(bfdev_fsm_t *fsm, const bfdev_fsm_state_t *state) { - unsigned int count = ++fsm->count; - fsm->state[count & (BFDEV_ARRAY_SIZE(fsm->state) - 1)] = state; + unsigned int count, index; + + count = ++fsm->count; + index = count & (BFDEV_ARRAY_SIZE(fsm->state) - 1); + + fsm->state[index] = state; } static const bfdev_fsm_transition_t * @@ -42,8 +46,11 @@ fsm_find_transition(const bfdev_fsm_state_t *state, bfdev_fsm_event_t *event) export int bfdev_fsm_error(bfdev_fsm_t *fsm, bfdev_fsm_event_t *event) { - const bfdev_fsm_state_t *error = fsm->error; - int retval = 0; + const bfdev_fsm_state_t *error; + int retval; + + error = fsm->error; + retval = 0; fsm_push_state(fsm, error); if (error && error->enter) @@ -55,9 +62,9 @@ bfdev_fsm_error(bfdev_fsm_t *fsm, bfdev_fsm_event_t *event) export int bfdev_fsm_handle(bfdev_fsm_t *fsm, bfdev_fsm_event_t *event) { - const bfdev_fsm_state_t *curr = bfdev_fsm_curr(fsm); - const bfdev_fsm_state_t *next; + const bfdev_fsm_state_t *curr, *next; + curr = bfdev_fsm_curr(fsm); if (bfdev_unlikely(!curr)) return -BFDEV_EINVAL; @@ -81,7 +88,8 @@ bfdev_fsm_handle(bfdev_fsm_t *fsm, bfdev_fsm_event_t *event) * Pop the stack as the new state, if popping is required * and there have no next state. */ - if (!(next = tran->next) && tran->stack < 0) { + next = tran->next; + if (!next && tran->stack < 0) { pstate = bfdev_array_pop(&fsm->stack, -tran->stack); if (bfdev_unlikely(!pstate)) return -BFDEV_EOVERFLOW; diff --git a/src/hashmap.c b/src/hashmap.c index b503f062..6670c8ec 100644 --- a/src/hashmap.c +++ b/src/hashmap.c @@ -129,12 +129,14 @@ hashmap_find_key(bfdev_hashmap_t *hashmap, const void *key, static inline int hashmap_rehash(bfdev_hashmap_t *hashmap, unsigned int nbits) { - const bfdev_alloc_t *alloc = hashmap->alloc; + const bfdev_alloc_t *alloc; bfdev_hlist_node_t *walk, *tmp; bfdev_hlist_head_t *nbuckets; unsigned long value, index, ncapacity; ncapacity = BFDEV_BIT(nbits); + alloc = hashmap->alloc; + nbuckets = bfdev_malloc_array(alloc, ncapacity, sizeof(*nbuckets)); if (!nbuckets) return -BFDEV_ENOMEM; @@ -255,8 +257,9 @@ bfdev_hashmap_find(bfdev_hashmap_t *hashmap, const void *key) export void bfdev_hashmap_release(bfdev_hashmap_t *hashmap) { - const bfdev_alloc_t *alloc = hashmap->alloc; + const bfdev_alloc_t *alloc; + alloc = hashmap->alloc; bfdev_free(alloc, hashmap->buckets); hashmap->buckets = NULL; diff --git a/src/ilist.c b/src/ilist.c index 9d955519..c3874a74 100644 --- a/src/ilist.c +++ b/src/ilist.c @@ -70,8 +70,8 @@ export void bfdev_ilist_add(bfdev_ilist_head_t *ihead, bfdev_ilist_node_t *inode, bfdev_ilist_cmp_t cmp, void *pdata) { - bfdev_ilist_node_t *walk, *first, *prev = NULL; - bfdev_list_head_t *next = &ihead->node_list; + bfdev_ilist_node_t *walk, *first, *prev; + bfdev_list_head_t *next; #ifdef BFDEV_DEBUG_ILIST if (bfdev_unlikely(!ilist_head_check(ihead))) @@ -84,11 +84,14 @@ bfdev_ilist_add(bfdev_ilist_head_t *ihead, bfdev_ilist_node_t *inode, return; /* Direct insertion of new nodes */ + next = &ihead->node_list; if (bfdev_ilist_head_empty(ihead)) goto finish; /* Traverse to find a suitable insertion point */ first = walk = bfdev_ilist_first(ihead); + prev = NULL; + do { if (cmp(inode, walk, pdata) < 0) { next = &walk->node_list; diff --git a/src/levenshtein.c b/src/levenshtein.c index 75d4deac..e57bba80 100644 --- a/src/levenshtein.c +++ b/src/levenshtein.c @@ -22,7 +22,7 @@ bfdev_levenshtein_len(const bfdev_alloc_t *alloc, return len2 * a; if (bfdev_unlikely(!len2)) - return len1 * a; + return len1 * d; cache = bfdev_malloc(alloc, BFDEV_BYTES_PER_INT * (len1 + 1) * 3); if (bfdev_unlikely(!cache)) diff --git a/src/list-sort.c b/src/list-sort.c index c7401fe8..66929eb0 100644 --- a/src/list-sort.c +++ b/src/list-sort.c @@ -10,8 +10,9 @@ static inline bfdev_list_head_t * list_merge(bfdev_list_cmp_t cmp, void *pdata, bfdev_list_head_t *node1, bfdev_list_head_t *node2) { - bfdev_list_head_t *node, **tail = &node; + bfdev_list_head_t *node, **tail; + tail = &node; for (;;) { if (cmp(node1, node2, pdata) <= 0) { *tail = node1; @@ -39,8 +40,9 @@ static inline void list_finish(bfdev_list_cmp_t cmp, void *pdata, bfdev_list_head_t *head, bfdev_list_head_t *node1, bfdev_list_head_t *node2) { - bfdev_list_head_t *tail = head; + bfdev_list_head_t *tail; + tail = head; for (;;) { if (cmp(node1, node2, pdata) <= 0) { tail->next = node1; @@ -86,14 +88,19 @@ bfdev_list_sort(bfdev_list_head_t *head, bfdev_list_cmp_t cmp, void *pdata) pending = NULL; for (count = 0; node; ++count) { - bfdev_list_head_t **tail = &pending; + bfdev_list_head_t **tail; size_t bits; + tail = &pending; for (bits = count; bits & 1; bits >>= 1) tail = &(*tail)->prev; if (bfdev_likely(bits)) { - bfdev_list_head_t *node2 = *tail, *node1 = node2->prev; + bfdev_list_head_t *node1, *node2; + + node2 = *tail; + node1 = node2->prev; + node2 = list_merge(cmp, pdata, node1, node2); node2->prev = node1->prev; *tail = node2; diff --git a/src/log.c b/src/log.c index 012304a1..37c6c04d 100644 --- a/src/log.c +++ b/src/log.c @@ -56,16 +56,17 @@ log_get_level(const char *str) extern unsigned int bfdev_log_level(const char *str, const char **endptr) { - char value, klevel; + unsigned int level; + char value; - for (klevel = BFDEV_LEVEL_DEFAULT; *str; str += 2) { + for (level = BFDEV_LEVEL_DEFAULT; *str; str += 2) { value = log_get_level(str); if (!value) break; switch (value) { case '0' ... '9': - klevel = value - '0'; + level = value - '0'; break; default: @@ -76,7 +77,7 @@ bfdev_log_level(const char *str, const char **endptr) if (*endptr) *endptr = str; - return klevel; + return level; } export int @@ -85,16 +86,17 @@ bfdev_log_state_vprint(struct bfdev_log *log, const char *fmt, va_list args) char buff[BFDEV_LOG_BUFF_SIZE]; bfdev_log_message_t msg; unsigned int level; - size_t offset = 0; + size_t offset; int retval; level = bfdev_log_level(fmt, &fmt); if (level >= BFDEV_LEVEL_DEFAULT) level = log->default_level; - if (bfdev_unlikely(level > log->record_level)) + if (level > log->record_level) return 0; + offset = 0; if (bfdev_log_test_commit(log)) { retval = bfdev_scnprintf( buff + offset, BFDEV_LOG_BUFF_SIZE - offset, diff --git a/src/matrix.c b/src/matrix.c index 59804c71..ca4f189c 100644 --- a/src/matrix.c +++ b/src/matrix.c @@ -7,61 +7,98 @@ #include #include -#define GENERIC_MATRIX_ADDSUB(name, operate) \ -export bfdev_matrix_t * \ -bfdev_matrix_##name(const bfdev_alloc_t *alloc, \ - const bfdev_matrix_t *va, \ - const bfdev_matrix_t *vb) \ -{ \ - bfdev_matrix_t *result; \ - unsigned int row, col; \ - unsigned int size, count; \ - \ - row = va->row; \ - col = va->col; \ - \ - if (row != vb->row || col != vb->col) \ - return NULL; \ - \ - result = bfdev_matrix_create(alloc, row, col); \ - if (bfdev_unlikely(!result)) \ - return NULL; \ - \ - size = row * col; \ - for (count = 0; count < size; ++count) { \ - result->values[count] \ - = va->values[count] operate \ - vb->values[count]; \ - } \ - \ - return result; \ +static inline void +matrix_zero(BFDEV_MATRIX_TYPE *var, unsigned int size) +{ + 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); +} + +#define GENERIC_MATRIX_ADDSUB(name, operate) \ +export int \ +bfdev_matrix_##name(bfdev_matrix_t *dest, \ + const bfdev_matrix_t *va, \ + const bfdev_matrix_t *vb) \ +{ \ + unsigned int row, col; \ + unsigned int size, count; \ + int retval; \ + \ + row = va->row; \ + col = va->col; \ + \ + if (row != vb->row || col != vb->col) \ + return -BFDEV_EINVAL; \ + \ + size = row * col; \ + retval = bfdev_array_resize(&dest->value, size); \ + if (bfdev_unlikely(retval)) \ + return retval; \ + \ + dest->row = row; \ + dest->col = col; \ + \ + const BFDEV_MATRIX_TYPE *ada; \ + const BFDEV_MATRIX_TYPE *adb; \ + BFDEV_MATRIX_TYPE *adr; \ + \ + ada = bfdev_array_data(&va->value, 0); \ + adb = bfdev_array_data(&vb->value, 0); \ + adr = bfdev_array_data(&dest->value, 0); \ + \ + for (count = 0; count < size; ++count) \ + adr[count] = ada[count] operate adb[count]; \ + \ + return -BFDEV_ENOERR; \ } GENERIC_MATRIX_ADDSUB(add, +) GENERIC_MATRIX_ADDSUB(sub, -) -export bfdev_matrix_t * -bfdev_matrix_mul(const bfdev_alloc_t *alloc, - const bfdev_matrix_t *va, - const bfdev_matrix_t *vb) +export int +bfdev_matrix_mul(bfdev_matrix_t *dest, + const bfdev_matrix_t *va, const bfdev_matrix_t *vb) { - bfdev_matrix_t *result; + BFDEV_DEFINE_MATRIX(buffer, dest->alloc); + bfdev_matrix_t *rename; unsigned int row, col; - unsigned int count; + unsigned int size, count; long value; + int retval; if (va->col != vb->row) - return NULL; + return -BFDEV_EINVAL; - result = bfdev_matrix_create(alloc, va->row, vb->col); - if (bfdev_unlikely(!result)) - return NULL; + rename = NULL; + if (dest == va || dest == vb) { + rename = dest; + dest = &buffer; + } + + size = va->row * vb->col; + retval = bfdev_array_resize(&dest->value, size); + if (bfdev_unlikely(retval)) + return retval; - const long (*ada)[va->col] = (void *)va->values; - const long (*adb)[vb->col] = (void *)vb->values; - long (*adr)[vb->col] = (void *)result->values; + dest->row = va->row; + dest->col = vb->col; + + const BFDEV_MATRIX_TYPE (*ada)[va->col]; + const BFDEV_MATRIX_TYPE (*adb)[vb->col]; + BFDEV_MATRIX_TYPE (*adr)[vb->col]; + + ada = bfdev_array_data(&va->value, 0); + adb = bfdev_array_data(&vb->value, 0); + adr = bfdev_array_data(&dest->value, 0); /* Reordering optimize */ + matrix_zero((void *)adr, size); for (row = 0; row < va->row; ++row) { for (col = 0; col < va->col; ++col) { value = ada[row][col]; @@ -70,48 +107,82 @@ bfdev_matrix_mul(const bfdev_alloc_t *alloc, } } - return result; + if (rename) { + retval = bfdev_matrix_set(rename, dest); + bfdev_matrix_release(dest); + } + + return retval; } -export bfdev_matrix_t * -bfdev_matrix_copy(const bfdev_alloc_t *alloc, - const bfdev_matrix_t *var) +export int +bfdev_matrix_set(bfdev_matrix_t *dest, const bfdev_matrix_t *src) { - bfdev_matrix_t *result; unsigned int row, col; + unsigned int size; + void *dbuf, *sbuf; + int retval; - row = var->row; - col = var->col; + row = src->row; + col = src->col; - result = bfdev_matrix_create(alloc, row, col); - if (bfdev_unlikely(!result)) - return NULL; + size = row * col; + retval = bfdev_array_resize(&dest->value, size); + if (bfdev_unlikely(retval)) + return retval; + + dest->row = row; + dest->col = col; - memcpy(result->values, var->values, - sizeof(*var->values) * row * col); + sbuf = bfdev_array_data(&src->value, 0); + dbuf = bfdev_array_data(&dest->value, 0); + matrix_copy(dbuf, sbuf, size); - return result; + return -BFDEV_ENOERR; } -export bfdev_matrix_t * -bfdev_matrix_create(const bfdev_alloc_t *alloc, +export int +bfdev_matrix_import(bfdev_matrix_t *var, const BFDEV_MATRIX_TYPE *buffer, unsigned int row, unsigned int col) { - bfdev_matrix_t *var; + unsigned int size; + void *dbuf; + int retval; - var = bfdev_zalloc(alloc, sizeof(*var) + sizeof(*var->values) * row * col); - if (bfdev_unlikely(!var)) - return NULL; + size = row * col; + retval = bfdev_array_resize(&var->value, size); + if (bfdev_unlikely(retval)) + return retval; var->row = row; var->col = col; - return var; + dbuf = bfdev_array_data(&var->value, 0); + matrix_copy(dbuf, buffer, size); + + return -BFDEV_ENOERR; +} + +export const BFDEV_MATRIX_TYPE * +bfdev_matrix_data(const bfdev_matrix_t *var, + unsigned int row, unsigned int col) +{ + BFDEV_MATRIX_TYPE *data; + unsigned int offset; + + if (var->col < row || var->col < col) + return NULL; + + offset = row * col; + data = bfdev_array_data(&var->value, offset); + + return data; } export void -bfdev_matrix_destory(const bfdev_alloc_t *alloc, - const bfdev_matrix_t *var) +bfdev_matrix_release(bfdev_matrix_t *var) { - bfdev_free(alloc, var); + bfdev_array_release(&var->value); + var->row = 0; + var->col = 0; } diff --git a/src/minpool.c b/src/minpool.c index 8dda296e..30b40627 100644 --- a/src/minpool.c +++ b/src/minpool.c @@ -261,12 +261,13 @@ export void bfdev_minpool_setup(struct bfdev_minpool_head *head, bfdev_minpool_find_t find, void *array, size_t size) { - struct bfdev_minpool_node *node = array; + struct bfdev_minpool_node *node; bfdev_list_head_init(&head->block_list); bfdev_list_head_init(&head->free_list); head->find = find; + node = array; minnode_set_used(node, false); minnode_set_size(node, size - sizeof(*node)); head->avail = size - sizeof(*node); diff --git a/src/mpi.c b/src/mpi.c index 5424bd41..fa8a5cb6 100644 --- a/src/mpi.c +++ b/src/mpi.c @@ -27,14 +27,14 @@ static inline void mpa_zero(BFDEV_MPI_TYPE *dest, unsigned long length) { - memset(dest, 0, length * sizeof(*dest)); + 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 * sizeof(*dest)); + memcpy(dest, src, length * BFDEV_MPI_SIZE); } static inline int @@ -572,8 +572,8 @@ mpi_add(bfdev_mpi_t *dest, if (bfdev_unlikely(retval)) return retval; - ptrs = mpi_val(dest); ptra = mpi_val(va); + ptrs = mpi_val(dest); carry = mpa_add(ptrs, ptra, ptrb, cnta, cntb, false); *(ptrs + length) = carry; @@ -601,8 +601,7 @@ mpi_subi(bfdev_mpi_t *dest, ptra = mpi_val(va); borrow = mpa_subi(ptrs, ptra, vi, length, false); - if (bfdev_unlikely(borrow)) - return -BFDEV_EOVERFLOW; + BFDEV_BUG_ON(borrow); mpi_relocation(dest); return -BFDEV_ENOERR; @@ -625,8 +624,7 @@ mpi_sub(bfdev_mpi_t *dest, return mpi_subi(dest, va, *ptrb); cnta = mpi_len(va); - if (bfdev_unlikely(cnta < cntb)) - return -BFDEV_EOVERFLOW; + BFDEV_BUG_ON(cnta < cntb); retval = mpi_resize(dest, cnta); if (bfdev_unlikely(retval)) @@ -636,8 +634,7 @@ mpi_sub(bfdev_mpi_t *dest, ptra = mpi_val(va); borrow = mpa_sub(ptrs, ptra, ptrb, cnta, cntb, false); - if (bfdev_unlikely(borrow)) - return -BFDEV_EOVERFLOW; + BFDEV_BUG_ON(borrow); mpi_relocation(dest); return -BFDEV_ENOERR; @@ -689,7 +686,7 @@ mpi_mul(bfdev_mpi_t *dest, if (dest != va && dest != vb) buffer = &dest->value; else { - bfdev_array_init(&array, dest->value.alloc, sizeof(*ptrs)); + bfdev_array_init(&array, dest->value.alloc, BFDEV_MPI_SIZE); buffer = &array; nval = true; } @@ -701,10 +698,11 @@ mpi_mul(bfdev_mpi_t *dest, if (bfdev_unlikely(retval)) return retval; - ptrs = bfdev_array_data(buffer, 0); ptra = mpi_val(va); + ptrs = bfdev_array_data(buffer, 0); mpa_mul(ptrs, ptra, ptrb, cnta, cntb); + if (nval) { bfdev_array_release(&dest->value); dest->value = array; @@ -794,7 +792,7 @@ mpi_div(bfdev_mpi_t *quot, bfdev_mpi_t *rem, if (quot != va) buffer = "->value; else { - bfdev_array_init(&array, va->value.alloc, sizeof(*ptrs)); + bfdev_array_init(&array, va->value.alloc, BFDEV_MPI_SIZE); buffer = &array; nval = true; } @@ -822,7 +820,9 @@ mpi_div(bfdev_mpi_t *quot, bfdev_mpi_t *rem, quot->value = array; } + BFDEV_BUG_ON(mpi_resize(quot, length)); BFDEV_BUG_ON(mpi_resize(rem, cntb)); + mpi_relocation(quot); mpi_relocation(rem); @@ -1064,8 +1064,16 @@ export int bfdev_mpi_add(bfdev_mpi_t *dest, const bfdev_mpi_t *va, const bfdev_mpi_t *vb) { + unsigned long cnta, cntb; int diff, retval; + cnta = mpi_len(va); + cntb = mpi_len(vb); + + /* satisfy commutative law */ + if (cnta < cntb) + bfdev_swap(va, vb); + if (va->plus == vb->plus) { retval = mpi_add(dest, va, vb); if (bfdev_unlikely(retval)) @@ -1254,10 +1262,9 @@ bfdev_mpi_mul(bfdev_mpi_t *dest, cnta = mpi_len(va); cntb = mpi_len(vb); - if (cnta < cntb) { + /* satisfy commutative law */ + if (cnta < cntb) bfdev_swap(va, vb); - bfdev_swap(cnta, cntb); - } retval = mpi_mul(dest, va, vb); if (bfdev_unlikely(retval)) @@ -1624,61 +1631,59 @@ bfdev_mpi_set(bfdev_mpi_t *dest, const bfdev_mpi_t *src) } export int -bfdev_mpi_read(const bfdev_mpi_t *var, BFDEV_MPI_TYPE *buffer, - unsigned long length, bool *sign) +bfdev_mpi_import(bfdev_mpi_t *var, const BFDEV_MPI_TYPE *buffer, + unsigned long length, bool sign) { BFDEV_MPI_TYPE *data; - unsigned long index; + int retval; - index = mpi_len(var); - if (bfdev_unlikely(length > index)) - return -BFDEV_EFBIG; + retval = mpi_resize(var, length); + if (bfdev_unlikely(retval)) + return retval; data = mpi_val(var); - mpa_copy(buffer, data, length); - *sign = var->plus; + mpa_copy(data, buffer, length); + var->plus = sign; return -BFDEV_ENOERR; } -export int -bfdev_mpi_write(bfdev_mpi_t *var, const BFDEV_MPI_TYPE *buffer, - unsigned long length, bool sign) +export const BFDEV_MPI_TYPE * +bfdev_mpi_data(const bfdev_mpi_t *var, + unsigned long index, bool *sign) { BFDEV_MPI_TYPE *data; - int retval; - retval = mpi_resize(var, length); - if (bfdev_unlikely(retval)) - return retval; + data = bfdev_array_data(&var->value, index); + if (bfdev_unlikely(!data)) + return NULL; - data = mpi_val(var); - mpa_copy(data, buffer, length); - var->plus = sign; + if (sign) + *sign = var->plus; - return -BFDEV_ENOERR; + return data; } export bfdev_mpi_t * bfdev_mpi_create(const bfdev_alloc_t *alloc) { - bfdev_mpi_t *result; - BFDEV_MPI_TYPE *array; + bfdev_mpi_t *var; int retval; - result = bfdev_malloc(alloc, sizeof(*result)); - if (bfdev_unlikely(!result)) + var = bfdev_malloc(alloc, sizeof(*var)); + if (bfdev_unlikely(!var)) return NULL; - bfdev_array_init(&result->value, alloc, sizeof(*array)); - retval = bfdev_mpi_seti(result, 0); + 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, result); + bfdev_free(alloc, var); return NULL; } - return result; + return var; } export void @@ -1686,8 +1691,7 @@ bfdev_mpi_destory(bfdev_mpi_t *var) { const bfdev_alloc_t *alloc; - alloc = var->value.alloc; + alloc = var->alloc; bfdev_array_release(&var->value); - bfdev_free(alloc, var); } diff --git a/src/notifier.c b/src/notifier.c index 25f4e462..7d236f6f 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -11,7 +11,7 @@ #include #include -#define bfdev_ilist_to_notifier(ptr) \ +#define ilist_to_notifier(ptr) \ bfdev_ilist_entry(ptr, bfdev_notifier_node_t, list) static long @@ -20,8 +20,8 @@ notifier_chain_cmp(const bfdev_ilist_node_t *node1, { bfdev_notifier_node_t *nnode1, *nnode2; - nnode1 = bfdev_ilist_to_notifier(node1); - nnode2 = bfdev_ilist_to_notifier(node2); + nnode1 = ilist_to_notifier(node1); + nnode2 = ilist_to_notifier(node2); if (nnode1->priority == nnode2->priority) return 0; @@ -30,14 +30,14 @@ notifier_chain_cmp(const bfdev_ilist_node_t *node1, } export bfdev_notifier_ret_t -bfdev_notifier_call(bfdev_notifier_head_t *head, void *arg, +bfdev_notifier_call(bfdev_notifier_t *head, void *arg, unsigned int call_num, unsigned int *called_num) { bfdev_notifier_node_t *node, *tmp; bfdev_notifier_ret_t retval; retval = BFDEV_NOTIFI_RET_DONE; - bfdev_ilist_for_each_entry_safe(node, tmp, &head->node, list) { + bfdev_ilist_for_each_entry_safe(node, tmp, &head->nodes, list) { if (!call_num--) break; @@ -48,7 +48,7 @@ bfdev_notifier_call(bfdev_notifier_head_t *head, void *arg, (*called_num)++; if (retval & BFDEV_NOTIFI_RET_REMOVE) { - bfdev_ilist_del(&head->node, &node->list); + bfdev_ilist_del(&head->nodes, &node->list); retval &= ~BFDEV_NOTIFI_RET_REMOVE; } @@ -60,23 +60,21 @@ bfdev_notifier_call(bfdev_notifier_head_t *head, void *arg, } export int -bfdev_notifier_register(bfdev_notifier_head_t *head, - bfdev_notifier_node_t *node) +bfdev_notifier_register(bfdev_notifier_t *head, bfdev_notifier_node_t *node) { - if (!node->entry) + if (bfdev_unlikely(!node->entry)) return -BFDEV_EINVAL; bfdev_ilist_node_init(&node->list); - bfdev_ilist_add(&head->node, &node->list, notifier_chain_cmp, NULL); + bfdev_ilist_add(&head->nodes, &node->list, notifier_chain_cmp, NULL); bfdev_log_debug("chain '%s' register (%p)\n", head->name, node); return -BFDEV_ENOERR; } export void -bfdev_notifier_unregister(bfdev_notifier_head_t *head, - bfdev_notifier_node_t *node) +bfdev_notifier_unregister(bfdev_notifier_t *head, bfdev_notifier_node_t *node) { - bfdev_ilist_del(&head->node, &node->list); + bfdev_ilist_del(&head->nodes, &node->list); bfdev_log_debug("chain '%s' unregister (%p)\n", head->name, node); } diff --git a/src/prandom.c b/src/prandom.c index 33879cbe..5f98b716 100644 --- a/src/prandom.c +++ b/src/prandom.c @@ -14,25 +14,33 @@ seed_minimum(uint32_t x, uint32_t m) } static void -prandom_setup(bfdev_prandom_state_t *pstate, uint64_t seed) +prandom_setup(bfdev_prandom_t *pstate, uint64_t seed) { + uint32_t s1, s2, s3, s4; + seed = bfdev_lower_32_bits((seed >> 32) ^ (seed << 10) ^ seed); - pstate->s1 = seed_minimum(seed, 2U); - pstate->s2 = seed_minimum(seed, 8U); - pstate->s3 = seed_minimum(seed, 16U); - pstate->s4 = seed_minimum(seed, 128U); + s1 = seed_minimum(seed, 2U); + s2 = seed_minimum(seed, 8U); + s3 = seed_minimum(seed, 16U); + s4 = seed_minimum(seed, 128U); + + pstate->s1 = s1; + pstate->s2 = s2; + pstate->s3 = s3; + pstate->s4 = s4; } static __bfdev_always_inline void -prandom_warmup(bfdev_prandom_state_t *pstate) +prandom_warmup(bfdev_prandom_t *pstate) { unsigned int count; + for (count = 0; count < 10; ++count) bfdev_prandom_value(pstate); } export uint32_t -bfdev_prandom_value(bfdev_prandom_state_t *pstate) +bfdev_prandom_value(bfdev_prandom_t *pstate) { uint32_t s1, s2, s3, s4; @@ -50,7 +58,7 @@ bfdev_prandom_value(bfdev_prandom_state_t *pstate) } export void -bfdev_prandom_seed(bfdev_prandom_state_t *pstate, uint64_t seed) +bfdev_prandom_seed(bfdev_prandom_t *pstate, uint64_t seed) { prandom_setup(pstate, seed); prandom_warmup(pstate); diff --git a/src/radix.c b/src/radix.c index 7b6d3416..ba3ef190 100644 --- a/src/radix.c +++ b/src/radix.c @@ -6,58 +6,94 @@ #include #include #include +#include #include +#define RADIX_BLOCK_MASK (BFDEV_RADIX_BLOCK - 1) +#define RADIX_ARY_MASK (BFDEV_RADIX_ARY - 1) + +#define RADIX_ARY_SHIFT bfdev_ilog2(BFDEV_RADIX_ARY) +#define RADIX_LEVEL_MAX (BFDEV_BITS_PER_LONG / RADIX_ARY_SHIFT) + +struct radix_parent { + bfdev_radix_node_t *node; + unsigned int index; +}; + static __bfdev_always_inline unsigned int radix_depth_shift(unsigned int level) { - return BFDEV_RADIX_SHIFT + BFDEV_RADIX_ARY_SHIFT * level; + return RADIX_ARY_SHIFT * level + BFDEV_RADIX_SHIFT; } static __bfdev_always_inline unsigned int radix_depth_index(unsigned int level, uintptr_t offset) { - return offset >> radix_depth_shift(level) & BFDEV_RADIX_ARY_MASK; + return (offset >> radix_depth_shift(level)) & RADIX_ARY_MASK; } -static bfdev_radix_node_t * -radix_parent(bfdev_radix_root_t *root, uintptr_t offset, uintptr_t *index) +static bool +radix_parent(bfdev_radix_root_t *root, uintptr_t offset, + struct radix_parent *parent) { - unsigned int level = root->level; bfdev_radix_node_t *node; + unsigned int level, index; + + level = root->level; + BFDEV_BUG_ON(level > RADIX_LEVEL_MAX); + /* Directly check capacity overflow */ if (bfdev_ilog2(offset) > radix_depth_shift(level)) - return NULL; + return false; + + node = root->node; + parent[root->level].node = node; - for (node = root->node; node && level--;) { - node = node->child[radix_depth_index(level, offset)]; + if (bfdev_unlikely(!node)) + return false; + + while (level--) { + index = radix_depth_index(level, offset); + node = node->child[index]; offset &= BFDEV_BIT_LOW_MASK(radix_depth_shift(level)); + + if (bfdev_unlikely(!node)) + return false; + + parent[level].node = node; + parent[level + 1].index = index; } - *index = offset; - return node; + parent[0].index = offset; + return true; } export void * bfdev_radix_root_find(bfdev_radix_root_t *root, uintptr_t offset) { + struct radix_parent parents[RADIX_LEVEL_MAX]; bfdev_radix_node_t *node; - uintptr_t index; + unsigned int index; + bool contain; - node = radix_parent(root, offset, &index); - if (bfdev_unlikely(!node)) + contain = radix_parent(root, offset, parents); + if (bfdev_unlikely(!contain)) return NULL; + node = parents[0].node; + index = parents[0].index; + return &node->block[index]; } static inline bfdev_radix_node_t * radix_extend(bfdev_radix_root_t *root, uintptr_t offset) { - const bfdev_alloc_t *alloc = root->alloc; + const bfdev_alloc_t *alloc; bfdev_radix_node_t *node, *successor; unsigned int level; + alloc = root->alloc; for (;;) { node = root->node; level = root->level; @@ -70,7 +106,6 @@ radix_extend(bfdev_radix_root_t *root, uintptr_t offset) return NULL; if (node) { - node->parent = successor; successor->refcount++; root->level++; } @@ -85,9 +120,10 @@ radix_extend(bfdev_radix_root_t *root, uintptr_t offset) static inline void radix_shrink(bfdev_radix_root_t *root) { - const bfdev_alloc_t *alloc = root->alloc; + const bfdev_alloc_t *alloc; bfdev_radix_node_t *node, *successor; + alloc = root->alloc; while (root->level) { node = root->node; @@ -95,7 +131,6 @@ radix_shrink(bfdev_radix_root_t *root) break; successor = *node->child; - successor->parent = node->parent; bfdev_free(alloc, node); root->node = successor; @@ -106,7 +141,7 @@ radix_shrink(bfdev_radix_root_t *root) export void * bfdev_radix_root_alloc(bfdev_radix_root_t *root, uintptr_t offset) { - const bfdev_alloc_t *alloc = root->alloc; + const bfdev_alloc_t *alloc; bfdev_radix_node_t *node; unsigned int level; @@ -114,6 +149,7 @@ bfdev_radix_root_alloc(bfdev_radix_root_t *root, uintptr_t offset) if (bfdev_unlikely(!node)) return NULL; + alloc = root->alloc; for (level = root->level; level--;) { bfdev_radix_node_t **slot, *newn; @@ -126,7 +162,6 @@ bfdev_radix_root_alloc(bfdev_radix_root_t *root, uintptr_t offset) return NULL; *slot = newn; - newn->parent = node; node->refcount++; } @@ -140,34 +175,44 @@ bfdev_radix_root_alloc(bfdev_radix_root_t *root, uintptr_t offset) export int bfdev_radix_root_free(bfdev_radix_root_t *root, uintptr_t offset) { - const bfdev_alloc_t *alloc = root->alloc; + struct radix_parent parents[RADIX_LEVEL_MAX]; + const bfdev_alloc_t *alloc; bfdev_radix_node_t *node; - unsigned int level; - uintptr_t index; + unsigned int level, index; + bool contain; - node = radix_parent(root, offset, &index); - if (bfdev_unlikely(!node)) + contain = radix_parent(root, offset, parents); + if (bfdev_unlikely(!contain)) return -BFDEV_ENOENT; + node = parents[0].node; + index = parents[0].index; + bfdev_bit_clr(node->bitmap, index); if (!bfdev_bitmap_empty(node->bitmap, BFDEV_RADIX_BLOCK)) return -BFDEV_ENOERR; + alloc = root->alloc; for (level = 0; level <= root->level; ++level) { - bfdev_radix_node_t *parent = node->parent; + bfdev_radix_node_t *parent; if (level && --node->refcount) break; + /* Do not prune the left most branch */ offset &= BFDEV_BIT_HIGH_MASK(radix_depth_shift(level)); if (offset < BFDEV_RADIX_BLOCK) break; - parent->child[radix_depth_index(level, offset)] = NULL; + parent = parents[level + 1].node; + index = parents[level + 1].index; + + parent->child[index] = NULL; bfdev_free(alloc, node); node = parent; } + /* Prune the leftmost branch */ if (level == root->level) radix_shrink(root); @@ -214,11 +259,224 @@ radix_destory_recurse(const bfdev_alloc_t *alloc, } export void -bfdev_radix_root_destory(bfdev_radix_root_t *root) +bfdev_radix_root_release(bfdev_radix_root_t *root) { - const bfdev_alloc_t *alloc = root->alloc; + const bfdev_alloc_t *alloc; + alloc = root->alloc; radix_destory_recurse(alloc, root->node, root->level); + root->level = 0; root->node = NULL; } + +static inline bfdev_radix_node_t * +radix_left_most(bfdev_radix_node_t *node, unsigned int level, + uintptr_t *offset) +{ + unsigned int walk; + + while (level--) { + for (walk = 0; walk < BFDEV_RADIX_ARY; ++walk) { + if (!node->child[walk]) + continue; + + node = node->child[walk]; + *offset |= (uintptr_t)walk << radix_depth_shift(level); + break; + } + + if (walk == BFDEV_RADIX_ARY) + return NULL; + } + + return node; +} + +static inline bfdev_radix_node_t * +radix_right_most(bfdev_radix_node_t *node, unsigned int level, + uintptr_t *offset) +{ + unsigned int walk; + + while (level--) { + walk = BFDEV_RADIX_ARY; + while (walk--) { + if (!node->child[walk]) + continue; + + node = node->child[walk]; + *offset |= (uintptr_t)walk << radix_depth_shift(level); + break; + } + + if (walk > BFDEV_RADIX_ARY) + return NULL; + } + + return node; +} + +export void * +bfdev_radix_root_first(bfdev_radix_root_t *root, uintptr_t *offsetp) +{ + unsigned int count, level; + bfdev_radix_node_t *node; + uintptr_t offset; + + node = root->node; + level = root->level; + + if (!node) + return NULL; + + offset = 0; + node = radix_left_most(node, level, &offset); + BFDEV_BUG_ON(!node); + + count = bfdev_find_first_bit(node->bitmap, BFDEV_RADIX_BLOCK); + if (count == BFDEV_RADIX_BLOCK) + return NULL; + + offset |= count; + *offsetp = offset; + + return &node->block[count]; +} + +export void * +bfdev_radix_root_last(bfdev_radix_root_t *root, uintptr_t *offsetp) +{ + unsigned int count, level; + bfdev_radix_node_t *node; + uintptr_t offset; + + node = root->node; + level = root->level; + + if (!node) + return NULL; + + offset = 0; + node = radix_right_most(node, level, &offset); + BFDEV_BUG_ON(!node); + + count = bfdev_find_last_bit(node->bitmap, BFDEV_RADIX_BLOCK); + if (count == BFDEV_RADIX_BLOCK) + return NULL; + + offset |= count; + *offsetp = offset; + + return &node->block[count]; +} + +export void * +bfdev_radix_root_next(bfdev_radix_root_t *root, uintptr_t *offsetp) +{ + struct radix_parent parents[RADIX_LEVEL_MAX]; + bfdev_radix_node_t *node; + unsigned int count, index, level; + bool contain; + + contain = radix_parent(root, *offsetp, parents); + if (bfdev_unlikely(!contain)) + return NULL; + + node = parents[0].node; + index = parents[0].index; + + /* Check for safety */ + contain = bfdev_bit_test(node->bitmap, index); + if (bfdev_unlikely(!contain)) + return NULL; + + count = bfdev_find_next_bit(node->bitmap, BFDEV_RADIX_BLOCK, index + 1); + if (count < BFDEV_RADIX_BLOCK) + goto finish; + + for (level = 1; level <= root->level; ++level) { + node = parents[level].node; + index = parents[level].index; + + while (++index < BFDEV_RADIX_ARY) { + if (!node->child[index]) + continue; + + count = radix_depth_shift(level - 1); + *offsetp &= ~((uintptr_t)RADIX_ARY_MASK << count); + *offsetp |= (uintptr_t)index << count; + + node = node->child[index]; + goto downward; + } + } + + return NULL; + +downward: + node = radix_left_most(node, level - 1, offsetp); + BFDEV_BUG_ON(!node); + count = bfdev_find_first_bit(node->bitmap, BFDEV_RADIX_BLOCK); + +finish: + *offsetp &= ~(uintptr_t)RADIX_BLOCK_MASK; + *offsetp |= count; + + return &node->block[count]; +} + +export void * +bfdev_radix_root_prev(bfdev_radix_root_t *root, uintptr_t *offsetp) +{ + struct radix_parent parents[RADIX_LEVEL_MAX]; + bfdev_radix_node_t *node; + unsigned int count, index, level; + bool contain; + + contain = radix_parent(root, *offsetp, parents); + if (bfdev_unlikely(!contain)) + return NULL; + + node = parents[0].node; + index = parents[0].index; + + /* Check for safety */ + contain = bfdev_bit_test(node->bitmap, index); + if (bfdev_unlikely(!contain)) + return NULL; + + count = bfdev_find_prev_bit(node->bitmap, BFDEV_RADIX_BLOCK, index - 1); + if (count < BFDEV_RADIX_BLOCK) + goto finish; + + for (level = 1; level <= root->level; ++level) { + node = parents[level].node; + index = parents[level].index; + + while (index--) { + if (!node->child[index]) + continue; + + count = radix_depth_shift(level - 1); + *offsetp &= ~((uintptr_t)RADIX_ARY_MASK << count); + *offsetp |= (uintptr_t)index << count; + + node = node->child[index]; + goto downward; + } + } + + return NULL; + +downward: + node = radix_right_most(node, level - 1, offsetp); + BFDEV_BUG_ON(!node); + count = bfdev_find_last_bit(node->bitmap, BFDEV_RADIX_BLOCK); + +finish: + *offsetp &= ~(uintptr_t)RADIX_BLOCK_MASK; + *offsetp |= count; + + return &node->block[count]; +} diff --git a/src/rbtree.c b/src/rbtree.c index 906d5b95..ee827d8d 100644 --- a/src/rbtree.c +++ b/src/rbtree.c @@ -40,7 +40,7 @@ child_change(bfdev_rb_root_t *root, bfdev_rb_node_t *parent, static __bfdev_always_inline void rotate_set(bfdev_rb_root_t *root, bfdev_rb_node_t *node, bfdev_rb_node_t *newn, bfdev_rb_node_t *child, unsigned int color, unsigned int ccolor, - const struct bfdev_rb_callbacks *callbacks) + const bfdev_rb_callbacks_t *callbacks) { bfdev_rb_node_t *parent; @@ -74,7 +74,7 @@ rotate_set(bfdev_rb_root_t *root, bfdev_rb_node_t *node, bfdev_rb_node_t *newn, static __bfdev_always_inline bfdev_rb_node_t * left_rotate(bfdev_rb_root_t *root, bfdev_rb_node_t *node, unsigned int color, unsigned int ccolor, - const struct bfdev_rb_callbacks *callbacks) + const bfdev_rb_callbacks_t *callbacks) { bfdev_rb_node_t *child, *successor; @@ -100,7 +100,7 @@ left_rotate(bfdev_rb_root_t *root, bfdev_rb_node_t *node, static __bfdev_always_inline bfdev_rb_node_t * right_rotate(bfdev_rb_root_t *root, bfdev_rb_node_t *node, unsigned int color, unsigned int ccolor, - const struct bfdev_rb_callbacks *callbacks) + const bfdev_rb_callbacks_t *callbacks) { bfdev_rb_node_t *child, *successor; @@ -117,7 +117,7 @@ right_rotate(bfdev_rb_root_t *root, bfdev_rb_node_t *node, export void bfdev_rb_fixup_augmented(bfdev_rb_root_t *root, bfdev_rb_node_t *node, - const struct bfdev_rb_callbacks *callbacks) + const bfdev_rb_callbacks_t *callbacks) { bfdev_rb_node_t *parent, *gparent, *tmp; @@ -227,7 +227,7 @@ bfdev_rb_fixup_augmented(bfdev_rb_root_t *root, bfdev_rb_node_t *node, export void bfdev_rb_erase_augmented(bfdev_rb_root_t *root, bfdev_rb_node_t *parent, - const struct bfdev_rb_callbacks *callbacks) + const bfdev_rb_callbacks_t *callbacks) { bfdev_rb_node_t *sibling, *node = NULL; bfdev_rb_node_t *tmp1, *tmp2; @@ -377,7 +377,7 @@ bfdev_rb_erase_augmented(bfdev_rb_root_t *root, bfdev_rb_node_t *parent, export bfdev_rb_node_t * bfdev_rb_remove_augmented(bfdev_rb_root_t *root, bfdev_rb_node_t *node, - const struct bfdev_rb_callbacks *callbacks) + const bfdev_rb_callbacks_t *callbacks) { bfdev_rb_node_t *parent, *rebalance = NULL; bfdev_rb_node_t *child1, *child2; @@ -499,7 +499,8 @@ bfdev_rb_remove_augmented(bfdev_rb_root_t *root, bfdev_rb_node_t *node, return rebalance; } -static const struct bfdev_rb_callbacks dummy_callbacks = { +static const bfdev_rb_callbacks_t +dummy_callbacks = { .rotate = bfdev_dummy_noop, .copy = bfdev_dummy_noop, .propagate = bfdev_dummy_noop, @@ -542,53 +543,60 @@ bfdev_rb_replace(bfdev_rb_root_t *root, bfdev_rb_node_t *oldn, export bfdev_rb_node_t * bfdev_rb_find(const bfdev_rb_root_t *root, void *key, - bfdev_rb_find_t cmp) + bfdev_rb_find_t find) { bfdev_rb_node_t *node; long retval; node = root->node; while (node) { - retval = cmp(node, key); - if (retval == LONG_MIN) - return NULL; + retval = find(node, key); + if (!retval) + return node; if (retval > 0) node = node->left; - else if (retval < 0) + else /* retval < 0 */ node = node->right; - else - return node; } return NULL; } export bfdev_rb_node_t * -bfdev_rb_find_last(bfdev_rb_root_t *root, void *key, bfdev_rb_find_t cmp, - bfdev_rb_node_t **parentp, bfdev_rb_node_t ***linkp) +bfdev_rb_find_last(bfdev_rb_root_t *root, void *key, bfdev_rb_find_t find, + bfdev_rb_node_t **parentp, bfdev_rb_node_t ***linkp, + bool *leftmostp) { + bool leftmost; long retval; *linkp = &root->node; + leftmost = true; + if (bfdev_unlikely(!**linkp)) { *parentp = NULL; - return NULL; + goto finish; } do { - retval = cmp((*parentp = **linkp), key); - if (retval == LONG_MIN) - return NULL; + *parentp = **linkp; + retval = find(**linkp, key); + if (!retval) + return **linkp; if (retval > 0) *linkp = &(**linkp)->left; - else if (retval < 0) + else /* retval < 0 */ { *linkp = &(**linkp)->right; - else - return **linkp; + leftmost = false; + } } while (**linkp); +finish: + if (leftmostp) + *leftmostp = leftmost; + return NULL; } @@ -610,13 +618,14 @@ bfdev_rb_parent(bfdev_rb_root_t *root, bfdev_rb_node_t **parentp, } do { - retval = cmp(node, (*parentp = *link), pdata); + retval = cmp(node, *link, pdata); if (bfdev_unlikely(!retval)) return NULL; + *parentp = *link; if (retval < 0) link = &(*link)->left; - else { + else /* retval > 0 */ { link = &(*link)->right; leftmost = false; } diff --git a/src/refcount.c b/src/refcount.c index acc1618d..7d6584b0 100644 --- a/src/refcount.c +++ b/src/refcount.c @@ -12,7 +12,7 @@ #include export void -bfdev_refcnt_report(bfdev_refcnt_t *ref, enum bfdev_refcnt_saturation type) +bfdev_refcnt_report(bfdev_refcnt_t *ref, bfdev_refcnt_saturation_t type) { switch (type) { case BFDEV_REFCNT_ADD_UAF: diff --git a/src/respool.c b/src/respool.c index 1148ea42..b7fbd530 100644 --- a/src/respool.c +++ b/src/respool.c @@ -3,22 +3,18 @@ * Copyright(c) 2023 John Sanpe */ -#define MODULE_NAME "bfdev-respool" -#define bfdev_log_fmt(fmt) MODULE_NAME ": " fmt - #include #include -#include #include -export bfdev_resnode_t * -bfdev_respool_find(bfdev_respool_t *pool, bfdev_respool_find_t find, - const void *data) +export bfdev_respool_node_t * +bfdev_respool_find(bfdev_respool_t *pool, + bfdev_respool_find_t find, void *data) { - bfdev_resnode_t *walk; + bfdev_respool_node_t *walk; - bfdev_list_for_each_entry(walk, &pool->node, list) { - if (!find(pool, walk, data)) + bfdev_list_for_each_entry(walk, &pool->nodes, list) { + if (!find(walk, data)) return walk; } @@ -26,76 +22,46 @@ bfdev_respool_find(bfdev_respool_t *pool, bfdev_respool_find_t find, } export void -bfdev_respool_insert(bfdev_respool_t *pool, bfdev_resnode_t *node) -{ - bfdev_list_add_prev(&pool->node, &node->list); - bfdev_log_debug("%s: insert %p '%s'\n", - pool->name, node, node->name); -} - -export void -bfdev_respool_remove(bfdev_respool_t *pool, bfdev_resnode_t *node) -{ - bfdev_list_del(&node->list); - bfdev_log_debug("%s: remove %p '%s'\n", - pool->name, node, node->name); -} - -export void -bfdev_respool_release(bfdev_respool_t *pool, bfdev_resnode_t *node) +bfdev_respool_release(bfdev_respool_t *pool, + bfdev_respool_node_t *node, void *pdata) { bfdev_list_del(&node->list); - node->release(pool, node); - bfdev_log_debug("%s: release %p '%s'\n", - pool->name, node, node->name); + node->release(node, pdata); } -export bfdev_resnode_t * -bfdev_respool_find_remove(bfdev_respool_t *pool, bfdev_respool_find_t find, - const void *data) +export bfdev_respool_node_t * +bfdev_respool_find_remove(bfdev_respool_t *pool, + bfdev_respool_find_t find, void *data) { - bfdev_resnode_t *match; + bfdev_respool_node_t *match; match = bfdev_respool_find(pool, find, data); if (bfdev_likely(match)) bfdev_list_del(&match->list); - if (bfdev_likely(match)) { - bfdev_log_debug("%s: find-remove %p '%s'\n", - pool->name, match, match->name); - } - return match; } -export bfdev_resnode_t * -bfdev_respool_find_release(bfdev_respool_t *pool, bfdev_respool_find_t find, - const void *data) +export bfdev_respool_node_t * +bfdev_respool_find_release(bfdev_respool_t *pool, + bfdev_respool_find_t find, void *pdata) { - bfdev_resnode_t *match; + bfdev_respool_node_t *match; - match = bfdev_respool_find(pool, find, data); + match = bfdev_respool_find(pool, find, pdata); if (bfdev_likely(match)) { bfdev_list_del(&match->list); - match->release(pool, match); - } - - if (bfdev_likely(match)) { - bfdev_log_debug("%s: find-release %p '%s'\n", - pool->name, match, match->name); + match->release(match, pdata); } return match; } export void -bfdev_respool_release_all(bfdev_respool_t *pool) +bfdev_respool_release_all(bfdev_respool_t *pool, void *pdata) { - bfdev_resnode_t *node; + bfdev_respool_node_t *node; - bfdev_list_for_each_entry(node, &pool->node, list) { - node->release(pool, node); - bfdev_log_debug("%s: release-all %p '%s'\n", - pool->name, node, node->name); - } + bfdev_list_for_each_entry(node, &pool->nodes, list) + node->release(node, pdata); } diff --git a/src/ringbuf.c b/src/ringbuf.c index 81ee0740..8cae1183 100644 --- a/src/ringbuf.c +++ b/src/ringbuf.c @@ -10,11 +10,12 @@ #include #define RINGBUF_GENERIC_COPY(copy1, copy2, fold1, fold2) do { \ - unsigned long size = ringbuf->mask + 1; \ - unsigned long esize = ringbuf->esize; \ - unsigned long llen; \ + unsigned long size, esize, llen; \ \ + size = ringbuf->mask + 1; \ + esize = ringbuf->esize; \ offset &= ringbuf->mask; \ + \ if (esize != 1) { \ offset *= esize; \ size *= esize; \ @@ -49,10 +50,13 @@ ringbuf_in_copy(struct bfdev_ringbuf *ringbuf, const void *buff, static __bfdev_always_inline unsigned long ringbuf_record_peek(struct bfdev_ringbuf *ringbuf, unsigned long recsize) { - unsigned long mask = ringbuf->mask; - unsigned long offset = ringbuf->out; - unsigned long length = 0; - uint8_t *data = ringbuf->data; + unsigned long mask, offset, length; + uint8_t *data; + + mask = ringbuf->mask; + offset = ringbuf->out; + data = ringbuf->data; + length = 0; if (ringbuf->esize != 1) { offset *= ringbuf->esize; @@ -73,9 +77,12 @@ static __bfdev_always_inline void ringbuf_record_poke(struct bfdev_ringbuf *ringbuf, unsigned long len, unsigned long recsize) { - unsigned long mask = ringbuf->mask; - unsigned long offset = ringbuf->out; - uint8_t *data = ringbuf->data; + unsigned long mask, offset; + uint8_t *data; + + mask = ringbuf->mask; + offset = ringbuf->out; + data = ringbuf->data; if (ringbuf->esize != 1) { offset *= ringbuf->esize; @@ -105,10 +112,11 @@ ringbuf_valid(struct bfdev_ringbuf *ringbuf) static inline unsigned long ringbuf_overflow(struct bfdev_ringbuf *ringbuf) { - unsigned long size = ringbuf->mask + 1; - unsigned long used; + unsigned long size, used; + size = ringbuf->mask + 1; used = ringbuf->in - ringbuf->out; + if (used > size) return used - size; @@ -144,10 +152,11 @@ export unsigned long bfdev_ringbuf_in_flat(struct bfdev_ringbuf *ringbuf, const void *buff, unsigned long len) { - unsigned long size = ringbuf->mask + 1; - unsigned long overflow; + unsigned long size, overflow; + size = ringbuf->mask + 1; bfdev_min_adj(len, size); + ringbuf_in_copy(ringbuf, buff, len, ringbuf->in); ringbuf->in += len; @@ -195,10 +204,12 @@ export unsigned long bfdev_ringbuf_in_record(struct bfdev_ringbuf *ringbuf, const void *buff, unsigned long len, unsigned long record) { - unsigned long size = ringbuf->mask + 1; - unsigned long offset, overflow, datalen; + unsigned long size, offset; + unsigned long overflow, datalen; + size = ringbuf->mask + 1; bfdev_min_adj(len, size); + offset = ringbuf->in + record; ringbuf->in = offset + len; @@ -239,13 +250,14 @@ bfdev_ringbuf_dynamic_alloc(struct bfdev_ringbuf *ringbuf, const bfdev_alloc_t * export void bfdev_ringbuf_dynamic_free(struct bfdev_ringbuf *ringbuf) { - const bfdev_alloc_t *alloc = ringbuf->alloc; + const bfdev_alloc_t *alloc; ringbuf->in = 0; ringbuf->out = 0; ringbuf->mask = 0; ringbuf->esize = 0; + alloc = ringbuf->alloc; bfdev_free(alloc, ringbuf->data); ringbuf->data = NULL; } diff --git a/src/skiplist.c b/src/skiplist.c index d2cdb7bf..842be087 100644 --- a/src/skiplist.c +++ b/src/skiplist.c @@ -10,8 +10,9 @@ static unsigned int random_level(bfdev_skip_head_t *head) { - unsigned int level = 1; + unsigned int level; + level = 1; while (level < head->levels) { if (rand() > RAND_MAX >> 2) break; @@ -25,11 +26,12 @@ static bfdev_skip_node_t * skipnode_find(bfdev_skip_head_t *head, bfdev_find_t find, void *pdata, unsigned int *plev) { - unsigned int level = head->curr; bfdev_list_head_t *list, *end; bfdev_skip_node_t *walk; + unsigned int level; long retval; + level = head->curr; if (bfdev_unlikely(!level)) return NULL; @@ -59,10 +61,10 @@ skipnode_find(bfdev_skip_head_t *head, bfdev_find_t find, } export int -bfdev_skiplist_insert(bfdev_skip_head_t *head, void *key, - bfdev_cmp_t cmp, void *pdata) +bfdev_skiplist_insert(bfdev_skip_head_t *head, void *key, bfdev_cmp_t cmp, + void *pdata) { - const bfdev_alloc_t *alloc = head->alloc; + const bfdev_alloc_t *alloc; bfdev_list_head_t *list, *end; bfdev_skip_node_t *walk, *node; unsigned int level, count; @@ -71,6 +73,7 @@ bfdev_skiplist_insert(bfdev_skip_head_t *head, void *key, level = random_level(head); bfdev_max_adj(head->curr, level); + alloc = head->alloc; node = bfdev_malloc(alloc, sizeof(*node) + sizeof(*node->list) * level); if (bfdev_unlikely(!node)) return -BFDEV_ENOMEM; @@ -98,13 +101,13 @@ bfdev_skiplist_insert(bfdev_skip_head_t *head, void *key, } export void -bfdev_skiplist_delete(bfdev_skip_head_t *head, - bfdev_find_t find, void *pdata) +bfdev_skiplist_delete(bfdev_skip_head_t *head, bfdev_find_t find, void *pdata) { - const bfdev_alloc_t *alloc = head->alloc; + const bfdev_alloc_t *alloc; bfdev_skip_node_t *node; unsigned int level; + alloc = head->alloc; node = skipnode_find(head, find, pdata, &level); if (bfdev_unlikely(!node)) return; @@ -128,45 +131,34 @@ bfdev_skiplist_find(bfdev_skip_head_t *head, } static void -bfdev_skiplist_release(bfdev_skip_head_t *head, - bfdev_release_t relse) +skiplist_release(bfdev_skip_head_t *head, bfdev_release_t release, void *pdata) { - const bfdev_alloc_t *alloc = head->alloc; + const bfdev_alloc_t *alloc; bfdev_skip_node_t *node, *tmp; + alloc = head->alloc; bfdev_list_for_each_entry_safe(node, tmp, head->nodes, list[0]) { - if (relse) - relse(node->key); + if (release) + release(node->key, pdata); bfdev_free(alloc, node); } } export void -bfdev_skiplist_reset(bfdev_skip_head_t *head, - bfdev_release_t relse) +bfdev_skiplist_reset(bfdev_skip_head_t *head, bfdev_release_t release, + void *pdata) { unsigned int count; - bfdev_skiplist_release(head, relse); + skiplist_release(head, release, pdata); for (count = 0; count < head->levels; ++count) bfdev_list_head_init(&head->nodes[count]); head->curr = 0; } -export void -bfdev_skiplist_destroy(bfdev_skip_head_t *head, - bfdev_release_t relse) -{ - const bfdev_alloc_t *alloc = head->alloc; - - bfdev_skiplist_release(head, relse); - bfdev_free(alloc, head); -} - export bfdev_skip_head_t * -bfdev_skiplist_create(const bfdev_alloc_t *alloc, - unsigned int levels) +bfdev_skiplist_create(const bfdev_alloc_t *alloc, unsigned int levels) { bfdev_skip_head_t *head; unsigned int count; @@ -187,3 +179,14 @@ bfdev_skiplist_create(const bfdev_alloc_t *alloc, return head; } + +export void +bfdev_skiplist_destroy(bfdev_skip_head_t *head, bfdev_release_t release, + void *pdata) +{ + const bfdev_alloc_t *alloc; + + alloc = head->alloc; + skiplist_release(head, release, pdata); + bfdev_free(alloc, head); +} diff --git a/src/stringhash.c b/src/stringhash.c index 136e0ce6..a99fa225 100644 --- a/src/stringhash.c +++ b/src/stringhash.c @@ -9,8 +9,9 @@ export unsigned long bfdev_pjwhash(const char *str) { - unsigned long value, hash = 0; + unsigned long value, hash; + hash = 0; while (*str) { hash <<= 4; hash += *str++;