diff --git a/.github/workflows/ci-linux.yml b/.github/workflows/ci-linux.yml index e15d81db4f..2112ce31e7 100644 --- a/.github/workflows/ci-linux.yml +++ b/.github/workflows/ci-linux.yml @@ -85,6 +85,49 @@ jobs: -DWITH_ASAN=ON -DCMAKE_POLICY_VERSION_MINIMUM=3.5 .. make -j ${{env.proc_num}} && make clean + compile-and-test-with-urma: + # WITH_URMA=ON is not covered by the jobs above: none of them set the flag, + # so src/brpc/urma/*.cpp and brpc_urma_unittest.cpp are never compiled. + # liburma is absent on the runner, so CMake falls back to the link-time + # mock (src/brpc/urma/mock_urma.cpp) and no URMA hardware is needed. + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v2 + - uses: ./.github/actions/install-essential-dependencies + + # test/CMakeLists.txt does find_package(Gperftools) and links + # ${GPERFTOOLS_LIBRARIES} into every unittest target. The make-based + # unittest jobs never hit this, but the CMake generate step fails with + # NOTFOUND without it. + - name: install gperftools + run: sudo apt-get install -y libgoogle-perftools-dev + + # DOWNLOAD_URMA_HEADERS fetches from atomgit.com, which is slow and often + # unreachable from CI. openEuler mirrors the same repo (identical tags and + # layout) on GitHub, so clone that and hand it to CMake via URMA_ROOT. + - name: fetch UMDK headers + run: | + git clone --depth 1 --branch v26.06.0_CAM \ + https://github.com/openeuler-mirror/umdk.git $GITHUB_WORKSPACE/umdk + test -f $GITHUB_WORKSPACE/umdk/src/urma/lib/urma/core/include/urma_api.h + + - name: gcc with URMA + env: + URMA_ROOT: ${{ github.workspace }}/umdk + run: | + export CC=gcc && export CXX=g++ + mkdir urma_build && cd urma_build + cmake -DWITH_URMA=ON \ + -DBUILD_UNIT_TESTS=ON -DBUILD_BRPC_TOOLS=OFF \ + -DCMAKE_BUILD_TYPE=Debug -DCMAKE_POLICY_VERSION_MINIMUM=3.5 .. + # brpc_urma_unittest links brpc-shared-debug, built from + # SOURCES_DEBUG_LIB, which contains every urma_*.cpp plus + # mock_urma.cpp -- so this target compiles all the URMA code. + make -j ${{env.proc_num}} brpc_urma_unittest + + - name: run brpc_urma_unittest + run: cd urma_build/test && ./brpc_urma_unittest + gcc-compile-with-make-protobuf: runs-on: ubuntu-22.04 steps: diff --git a/CMakeLists.txt b/CMakeLists.txt index 10e9052dcb..a2838bceaa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,6 +31,9 @@ option(WITH_URMA "With URMA (openEuler Unified Remote Memory Access)" OFF) option(DOWNLOAD_URMA_HEADERS "Download UMDK headers when WITH_URMA is enabled and headers are absent" ON) +option(WITH_URMA_MOCK + "Explicitly allow linking brpc's URMA link-time mock when liburma is not found (WITH_URMA only). The mock cannot talk to real URMA hardware, so this must be opted into rather than silently substituted." + OFF) option(WITH_UBRING "With UB" OFF) option(WITH_DEBUG_BTHREAD_SCHE_SAFETY "With debugging bthread sche safety" OFF) option(WITH_DEBUG_LOCK "With debugging lock" OFF) @@ -371,10 +374,17 @@ if(WITH_URMA) if(URMA_LIB) message(STATUS "Found URMA library: ${URMA_LIB}") set(URMA_USE_MOCK 0) - else() + elseif(WITH_URMA_MOCK) message(STATUS - "liburma not found; building with the URMA link-time mock") + "liburma not found; WITH_URMA_MOCK=ON, building with the URMA " + "link-time mock") set(URMA_USE_MOCK 1) + else() + message(FATAL_ERROR + "Fail to find liburma. Install liburma, set URMA_ROOT, or " + "explicitly opt into brpc's link-time mock with " + "-DWITH_URMA_MOCK=ON (the mock cannot talk to real URMA " + "hardware; only enable it for CI/tests without URMA hardware).") endif() endif() diff --git a/MODULE.bazel b/MODULE.bazel index 391b8c2784..1cbbb83f92 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -62,4 +62,18 @@ git_repository( build_file = '//bazel/third_party/umdk:umdk.BUILD', remote = 'https://atomgit.com/openeuler/umdk.git', commit = '564ee727a55523d4351a8fb3c94292b388ebb924', # v26.06.0_CAM +git_repository( + name = 'umdk', + build_file = '//bazel/third_party/umdk:umdk.BUILD', + remote = 'https://atomgit.com/openeuler/umdk.git', + commit = '564ee727a55523d4351a8fb3c94292b388ebb924', # v26.06.0_CAM + # umdk ships its own src/urma/BUILD.bazel, which turns src/urma into a + # separate Bazel package and silently empties the glob() in umdk.BUILD + # (glob cannot cross package boundaries). Drop it so the headers under + # src/urma/lib/urma/**/include stay part of this repository's root + # package. + patch_cmds = [ + 'rm -f src/urma/BUILD.bazel', + ], +) ) diff --git a/WORKSPACE b/WORKSPACE index 22fc411b32..10d8f08954 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -284,6 +284,20 @@ git_repository( build_file = "//bazel/third_party/umdk:umdk.BUILD", remote = "https://atomgit.com/openeuler/umdk.git", commit = "564ee727a55523d4351a8fb3c94292b388ebb924", # v26.06.0_CAM +git_repository( + name = "umdk", + build_file = "//bazel/third_party/umdk:umdk.BUILD", + remote = "https://atomgit.com/openeuler/umdk.git", + commit = "564ee727a55523d4351a8fb3c94292b388ebb924", # v26.06.0_CAM + # umdk ships its own src/urma/BUILD.bazel, which turns src/urma into a + # separate Bazel package and silently empties the glob() in umdk.BUILD + # (glob cannot cross package boundaries). Drop it so the headers under + # src/urma/lib/urma/**/include stay part of this repository's root + # package. + patch_cmds = [ + "rm -f src/urma/BUILD.bazel", + ], +) ) # Header-only JSON library used by iobuf_unittest's IOBuf<->std::iostream diff --git a/bazel/third_party/umdk/BUILD.bazel b/bazel/third_party/umdk/BUILD.bazel new file mode 100644 index 0000000000..fefa6c3fea --- /dev/null +++ b/bazel/third_party/umdk/BUILD.bazel @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Thie empty BUILD.bazel file is required to make Bazel treat +# this directory as a package. diff --git a/config_brpc.sh b/config_brpc.sh index 2c1394e840..edfa989c49 100755 --- a/config_brpc.sh +++ b/config_brpc.sh @@ -54,11 +54,12 @@ else LDD=ldd fi -TEMP=`getopt -o v: --long headers:,libs:,cc:,cxx:,with-glog,with-thrift,with-rdma,with-urma,with-mesalink,with-bthread-tracer,with-debug-bthread-sche-safety,with-debug-lock,with-asan,with-riscv-zvbc,with-riscv-zbc,with-cpu-frequency,nodebugsymbols,werror -n 'config_brpc' -- "$@"` +TEMP=`getopt -o v: --long headers:,libs:,cc:,cxx:,with-glog,with-thrift,with-rdma,with-urma,with-urma-mock,with-mesalink,with-bthread-tracer,with-debug-bthread-sche-safety,with-debug-lock,with-asan,with-riscv-zvbc,with-riscv-zbc,with-cpu-frequency,nodebugsymbols,werror -n 'config_brpc' -- "$@"` WITH_GLOG=0 WITH_THRIFT=0 WITH_RDMA=0 WITH_URMA=0 +WITH_URMA_MOCK=0 WITH_MESALINK=0 WITH_BTHREAD_TRACER=0 WITH_ASAN=0 @@ -92,6 +93,7 @@ while true; do --with-thrift) WITH_THRIFT=1; shift 1 ;; --with-rdma) WITH_RDMA=1; shift 1 ;; --with-urma) WITH_URMA=1; shift 1 ;; + --with-urma-mock) WITH_URMA_MOCK=1; shift 1 ;; --with-mesalink) WITH_MESALINK=1; shift 1 ;; --with-bthread-tracer) WITH_BTHREAD_TRACER=1; shift 1 ;; --with-debug-bthread-sche-safety ) BRPC_DEBUG_BTHREAD_SCHE_SAFETY=1; shift 1 ;; @@ -554,9 +556,12 @@ if [ $WITH_URMA != 0 ]; then append_to_output_libs "$URMA_LIB" append_to_output "DYNAMIC_LINKINGS+=-lurma" append_to_output "URMA_USE_MOCK=0" - else + elif [ $WITH_URMA_MOCK != 0 ]; then append_to_output "URMA_USE_MOCK=1" - print_info "liburma not found; using URMA link-time mock" + print_info "liburma not found; --with-urma-mock given, using URMA link-time mock" + else + >&2 $ECHO "Fail to find liburma. Install liburma, or explicitly opt into brpc's link-time mock with --with-urma-mock (the mock cannot talk to real URMA hardware; only use it for CI/tests without URMA hardware)." + exit 1 fi fi diff --git a/docs/cn/urma.md b/docs/cn/urma.md index a9be634ec7..b1c048fae1 100644 --- a/docs/cn/urma.md +++ b/docs/cn/urma.md @@ -20,7 +20,7 @@ WR。完成事件既可由 JFC 忙轮询获取,也可通过 JFCE 事件 fd 获 ### CMake 编译 ```bash -# 带 URMA 支持编译 brpc +# 带 URMA 支持编译 brpc(需要 liburma;无硬件/CI 场景见下方 mock 说明) cmake -B build -DWITH_URMA=ON make -C build -j$(nproc) @@ -30,11 +30,37 @@ cmake -B build make -C build -j$(nproc) ``` +未安装 `liburma` 时(例如 CI 环境),需显式开启链接期 mock,而不是依赖 +隐式回退: + +```bash +cmake -B build -DWITH_URMA=ON -DWITH_URMA_MOCK=ON +make -C build -j$(nproc) +``` + `WITH_URMA=ON` 使用上游 UMDK 头文件进行编译。CMake 优先使用系统安装的 SDK;找不到头文件时,会参照 Mooncake 的 mock 构建方式下载固定版本的 UMDK,可通过 `DOWNLOAD_URMA_HEADERS=OFF` 禁止下载。找到 `liburma` 时使用 -真实硬件数据通路,否则链接 brpc 的 mock,使 URMA 代码和测试仍可在无硬件 -环境编译。 +真实硬件数据通路;否则默认直接报错终止构建,避免静默回退到 mock 而产出 +一个看似支持 URMA、实际无法访问真实硬件的产物。需要在无硬件环境(例如 +CI)编译和测试 URMA 代码时,显式传入 `-DWITH_URMA_MOCK=ON` +(Make 对应 `config_brpc.sh --with-urma-mock`)以主动选择链接 brpc 的 +mock。 + +### Bazel 编译 + +```bash +# 带 URMA 支持编译 brpc +bazel build --define=BRPC_WITH_URMA=true //:brpc +``` + +Bazel 下的 URMA 头文件来自 `WORKSPACE` / `MODULE.bazel` 中固定 commit 的 +`umdk` `git_repository`,没有 CMake `DOWNLOAD_URMA_HEADERS` 那样的开关: +既不能改用系统已安装的 SDK 头文件,也无法禁止下载。此外 Bazel 构建目前 +未提供检测/链接真实 `liburma` 的逻辑,`src/brpc/urma/mock_urma.cpp` 会 +无条件编入,因此 Bazel 构建的 URMA 始终使用 mock 数据通路;如需链接真实 +硬件,请使用 CMake 或 Make 构建。`urma_performance` 示例目前也只有 +CMake/Make 构建脚本,尚无对应的 Bazel target。 ## 使用 diff --git a/docs/en/urma.md b/docs/en/urma.md index 964f648bd2..8556fbdf93 100644 --- a/docs/en/urma.md +++ b/docs/en/urma.md @@ -20,7 +20,7 @@ from a JFC either by busy polling or through a JFCE event fd. ### Build with CMake ```bash -# Build brpc with URMA support +# Build brpc with URMA support (requires liburma; see below for CI/mock builds) cmake -B build -DWITH_URMA=ON make -C build -j$(nproc) @@ -30,13 +30,42 @@ cmake -B build make -C build -j$(nproc) ``` +Without `liburma` installed (e.g. in CI), explicitly opt into the link-time +mock instead of relying on an implicit fallback: + +```bash +cmake -B build -DWITH_URMA=ON -DWITH_URMA_MOCK=ON +make -C build -j$(nproc) +``` + `WITH_URMA=ON` compiles against upstream UMDK headers. CMake prefers an installed SDK and, following Mooncake's mock setup, downloads a pinned UMDK release when the headers are unavailable. Set `DOWNLOAD_URMA_HEADERS=OFF` to disable downloading. -When `liburma` is found it is linked for the hardware data path. Otherwise, -brpc uses its link-time mock so URMA code and tests can still be built without -hardware. +When `liburma` is found it is linked for the hardware data path. Otherwise +the build fails by default, since silently falling back to the mock could +mask a broken environment and ship a binary that looks URMA-capable but +cannot reach real hardware. Pass `-DWITH_URMA_MOCK=ON` +(`config_brpc.sh --with-urma-mock`) to explicitly opt into brpc's +link-time mock so URMA code and tests can still be built without hardware +(e.g. in CI). + +### Build with Bazel + +```bash +# Build brpc with URMA support +bazel build --define=BRPC_WITH_URMA=true //:brpc +``` + +Bazel fetches the UMDK headers from the `umdk` `git_repository` pinned to a +fixed commit in `WORKSPACE` / `MODULE.bazel`. There is no Bazel equivalent of +CMake's `DOWNLOAD_URMA_HEADERS`: Bazel can neither use a locally installed SDK +nor disable the download. Bazel builds also have no detection/linking logic +for a real `liburma` yet — `src/brpc/urma/mock_urma.cpp` is compiled in +unconditionally, so a Bazel build of URMA always uses the mock data path. Use +CMake or Make to link against real hardware. The `urma_performance` example +currently only has CMake/Make build files; there is no Bazel target for it +yet. ## Usage diff --git a/example/cmake/BrpcExample.cmake b/example/cmake/BrpcExample.cmake index 6b2c7850ff..e57cda196a 100644 --- a/example/cmake/BrpcExample.cmake +++ b/example/cmake/BrpcExample.cmake @@ -86,11 +86,12 @@ macro(brpc_example_find_common_deps out_libs) ) endif() - # Search for libthrift* by best effort. If it is not found and brpc is - # compiled with thrift protocol enabled, a link error would be reported. - find_library(THRIFT_LIB NAMES thrift) - if(NOT THRIFT_LIB) - set(THRIFT_LIB "") + + # brpc built with -DWITH_URMA=ON carries undefined urma_* symbols. Link + # liburma when the header is present, which indicates a URMA-capable build. + set(_brpc_example_urma_lib "") + if(EXISTS "/usr/lib64/liburma.so" OR EXISTS "/usr/lib/liburma.so") + set(_brpc_example_urma_lib "urma") endif() find_path(BRPC_INCLUDE_PATH NAMES brpc/server.h) @@ -123,6 +124,11 @@ macro(brpc_example_find_common_deps out_libs) find_package(OpenSSL REQUIRED) + find_library(URMA_LIB NAMES urma) + if(NOT URMA_LIB) + set(URMA_LIB "") + endif() + set(_common_libs Threads::Threads ${GFLAGS_LIBRARY} @@ -132,6 +138,7 @@ macro(brpc_example_find_common_deps out_libs) ${OPENSSL_CRYPTO_LIBRARY} ${OPENSSL_SSL_LIBRARY} ${THRIFT_LIB} + ${_brpc_example_urma_lib} dl ) diff --git a/example/urma_performance/CMakeLists.txt b/example/urma_performance/CMakeLists.txt index 154970fbd3..eae472fe90 100644 --- a/example/urma_performance/CMakeLists.txt +++ b/example/urma_performance/CMakeLists.txt @@ -26,13 +26,7 @@ brpc_example_find_common_deps(DYNAMIC_LIB) protobuf_generate_cpp(PROTO_SRC PROTO_HEADER test.proto) set(BRPC_EXAMPLE_WITH_URMA ON) -find_library(URMA_LIB NAMES urma) -if(URMA_LIB) - list(APPEND DYNAMIC_LIB ${URMA_LIB}) -else() - message(STATUS - "liburma not found; using the URMA implementation linked into brpc") -endif() + add_executable(urma_performance_client client.cpp ${PROTO_SRC} ${PROTO_HEADER}) brpc_example_configure_target(urma_performance_client) diff --git a/src/brpc/urma/mock_urma.cpp b/src/brpc/urma/mock_urma.cpp index 266c08b19a..b6b7e29733 100644 --- a/src/brpc/urma/mock_urma.cpp +++ b/src/brpc/urma/mock_urma.cpp @@ -62,7 +62,13 @@ struct PendingRecv { uint64_t user_ctx; }; -std::shared_mutex g_rw_mutex; +// brpc is built with -std=c++14 whenever protobuf < 4.21 (see BRPC_CXX_STANDARD +// in CMakeLists.txt and CXXFLAGS in config_brpc.sh), which is the case on the +// CI runners. std::shared_mutex is C++17-only; std::shared_timed_mutex is the +// C++14 equivalent and has the same locking semantics here. +typedef std::shared_timed_mutex MockSharedMutex; + +MockSharedMutex g_rw_mutex; bool initialized = false; std::vector device_list; std::map context_map; @@ -119,7 +125,7 @@ urma_eid_info_t mock_eid_info = { extern "C" { urma_status_t urma_init(urma_init_attr_t *init_attr) { - std::unique_lock lock(g_rw_mutex); + std::unique_lock lock(g_rw_mutex); if (initialized) { return URMA_EEXIST; } @@ -128,7 +134,7 @@ urma_status_t urma_init(urma_init_attr_t *init_attr) { } urma_status_t urma_uninit(void) { - std::unique_lock lock(g_rw_mutex); + std::unique_lock lock(g_rw_mutex); initialized = false; for (auto device : device_list) { delete device; @@ -153,7 +159,7 @@ urma_status_t urma_uninit(void) { urma_device_t **urma_get_device_list(int *num_devices) { { - std::shared_lock lock(g_rw_mutex); + std::shared_lock lock(g_rw_mutex); if (!initialized) { *num_devices = 0; return nullptr; @@ -168,7 +174,7 @@ urma_device_t **urma_get_device_list(int *num_devices) { } } { - std::unique_lock write_lock(g_rw_mutex); + std::unique_lock write_lock(g_rw_mutex); if (!initialized) { *num_devices = 0; return nullptr; @@ -193,7 +199,7 @@ urma_device_t **urma_get_device_list(int *num_devices) { urma_device_t *urma_get_device_by_name(char *dev_name) { { - std::shared_lock lock(g_rw_mutex); + std::shared_lock lock(g_rw_mutex); if (!initialized) { return nullptr; } @@ -207,7 +213,7 @@ urma_device_t *urma_get_device_by_name(char *dev_name) { } } { - std::unique_lock write_lock(g_rw_mutex); + std::unique_lock write_lock(g_rw_mutex); if (!initialized) { return nullptr; } @@ -265,7 +271,7 @@ void urma_free_eid_list(urma_eid_info_t *eid_list) { } urma_context_t *urma_create_context(urma_device_t *device, uint32_t eid_index) { - std::unique_lock lock(g_rw_mutex); + std::unique_lock lock(g_rw_mutex); if (!device) { return nullptr; } @@ -277,7 +283,7 @@ urma_context_t *urma_create_context(urma_device_t *device, uint32_t eid_index) { } urma_status_t urma_delete_context(urma_context_t *ctx) { - std::unique_lock lock(g_rw_mutex); + std::unique_lock lock(g_rw_mutex); if (!ctx || context_map.find(ctx) == context_map.end()) { return URMA_EINVAL; } @@ -287,7 +293,7 @@ urma_status_t urma_delete_context(urma_context_t *ctx) { } urma_jfce_t *urma_create_jfce(urma_context_t *ctx) { - std::unique_lock lock(g_rw_mutex); + std::unique_lock lock(g_rw_mutex); if (!ctx || context_map.find(ctx) == context_map.end()) { return nullptr; } @@ -305,7 +311,7 @@ urma_jfce_t *urma_create_jfce(urma_context_t *ctx) { } urma_status_t urma_delete_jfce(urma_jfce_t *jfce) { - std::unique_lock lock(g_rw_mutex); + std::unique_lock lock(g_rw_mutex); if (!jfce || jfce_map.find(jfce) == jfce_map.end()) { return URMA_EINVAL; } @@ -316,7 +322,7 @@ urma_status_t urma_delete_jfce(urma_jfce_t *jfce) { } urma_jfc_t *urma_create_jfc(urma_context_t *ctx, urma_jfc_cfg_t *cfg) { - std::unique_lock lock(g_rw_mutex); + std::unique_lock lock(g_rw_mutex); if (!ctx || !cfg || context_map.find(ctx) == context_map.end()) { return nullptr; } @@ -334,7 +340,7 @@ urma_jfc_t *urma_create_jfc(urma_context_t *ctx, urma_jfc_cfg_t *cfg) { } urma_status_t urma_delete_jfc(urma_jfc_t *jfc) { - std::unique_lock lock(g_rw_mutex); + std::unique_lock lock(g_rw_mutex); if (!jfc || jfc_state_map.find(jfc) == jfc_state_map.end()) { return URMA_EINVAL; } @@ -345,7 +351,7 @@ urma_status_t urma_delete_jfc(urma_jfc_t *jfc) { } urma_jfr_t *urma_create_jfr(urma_context_t *ctx, urma_jfr_cfg_t *cfg) { - std::unique_lock lock(g_rw_mutex); + std::unique_lock lock(g_rw_mutex); if (!ctx || !cfg || context_map.find(ctx) == context_map.end()) { return nullptr; } @@ -361,7 +367,7 @@ urma_jfr_t *urma_create_jfr(urma_context_t *ctx, urma_jfr_cfg_t *cfg) { } urma_status_t urma_delete_jfr(urma_jfr_t *jfr) { - std::unique_lock lock(g_rw_mutex); + std::unique_lock lock(g_rw_mutex); if (!jfr || jfr_map.find(jfr) == jfr_map.end()) { return URMA_EINVAL; } @@ -373,7 +379,7 @@ urma_status_t urma_delete_jfr(urma_jfr_t *jfr) { } urma_target_seg_t *urma_register_seg(urma_context_t *ctx, urma_seg_cfg_t *cfg) { - std::unique_lock lock(g_rw_mutex); + std::unique_lock lock(g_rw_mutex); if (!ctx || !cfg || context_map.find(ctx) == context_map.end()) { return nullptr; } @@ -389,7 +395,7 @@ urma_target_seg_t *urma_register_seg(urma_context_t *ctx, urma_seg_cfg_t *cfg) { } urma_status_t urma_unregister_seg(urma_target_seg_t *seg) { - std::unique_lock lock(g_rw_mutex); + std::unique_lock lock(g_rw_mutex); if (!seg || seg_map.find(seg) == seg_map.end()) { return URMA_EINVAL; } @@ -401,7 +407,7 @@ urma_status_t urma_unregister_seg(urma_target_seg_t *seg) { urma_target_seg_t *urma_import_seg(urma_context_t *ctx, urma_seg_t *seg, urma_token_t *token_value, uint64_t addr, urma_import_seg_flag_t flag) { - std::unique_lock lock(g_rw_mutex); + std::unique_lock lock(g_rw_mutex); if (!ctx || !seg || !token_value || context_map.find(ctx) == context_map.end()) { return nullptr; @@ -414,7 +420,7 @@ urma_target_seg_t *urma_import_seg(urma_context_t *ctx, urma_seg_t *seg, } urma_status_t urma_unimport_seg(urma_target_seg_t *tseg) { - std::unique_lock lock(g_rw_mutex); + std::unique_lock lock(g_rw_mutex); if (!tseg || seg_map.find(tseg) == seg_map.end()) { return URMA_EINVAL; } @@ -428,7 +434,7 @@ urma_status_t urma_get_async_event(urma_context_t *ctx, if (!ctx || !event) { return URMA_EINVAL; } - std::shared_lock lock(g_rw_mutex); + std::shared_lock lock(g_rw_mutex); if (context_map.find(ctx) == context_map.end()) { return URMA_EINVAL; } @@ -438,7 +444,7 @@ urma_status_t urma_get_async_event(urma_context_t *ctx, void urma_ack_async_event(urma_async_event_t *event) {} urma_jetty_t *urma_create_jetty(urma_context_t *ctx, urma_jetty_cfg_t *cfg) { - std::unique_lock lock(g_rw_mutex); + std::unique_lock lock(g_rw_mutex); if (!ctx || !cfg || context_map.find(ctx) == context_map.end()) { return nullptr; } @@ -455,7 +461,7 @@ urma_jetty_t *urma_create_jetty(urma_context_t *ctx, urma_jetty_cfg_t *cfg) { } urma_status_t urma_delete_jetty(urma_jetty_t *jetty) { - std::unique_lock lock(g_rw_mutex); + std::unique_lock lock(g_rw_mutex); if (!jetty || jetty_map.find(jetty) == jetty_map.end()) { return URMA_EINVAL; } @@ -466,7 +472,7 @@ urma_status_t urma_delete_jetty(urma_jetty_t *jetty) { } urma_status_t urma_unbind_jetty(urma_jetty_t *jetty) { - std::unique_lock lock(g_rw_mutex); + std::unique_lock lock(g_rw_mutex); if (!jetty || jetty_map.find(jetty) == jetty_map.end()) { return URMA_EINVAL; } @@ -477,7 +483,7 @@ urma_status_t urma_unbind_jetty(urma_jetty_t *jetty) { urma_target_jetty_t *urma_import_jetty(urma_context_t *ctx, urma_rjetty_t *rjetty, urma_token_t *token_value) { - std::unique_lock lock(g_rw_mutex); + std::unique_lock lock(g_rw_mutex); if (!ctx || !rjetty || !token_value || context_map.find(ctx) == context_map.end()) { return nullptr; @@ -490,7 +496,7 @@ urma_target_jetty_t *urma_import_jetty(urma_context_t *ctx, } urma_status_t urma_unimport_jetty(urma_target_jetty_t *tjetty) { - std::unique_lock lock(g_rw_mutex); + std::unique_lock lock(g_rw_mutex); if (!tjetty || target_jetty_map.find(tjetty) == target_jetty_map.end()) { return URMA_EINVAL; } @@ -501,7 +507,7 @@ urma_status_t urma_unimport_jetty(urma_target_jetty_t *tjetty) { urma_status_t urma_bind_jetty(urma_jetty_t *jetty, urma_target_jetty_t *tjetty) { - std::unique_lock lock(g_rw_mutex); + std::unique_lock lock(g_rw_mutex); if (!jetty || !tjetty || jetty_map.find(jetty) == jetty_map.end() || target_jetty_map.find(tjetty) == target_jetty_map.end()) { return URMA_EINVAL; @@ -511,7 +517,7 @@ urma_status_t urma_bind_jetty(urma_jetty_t *jetty, } urma_status_t urma_modify_jetty(urma_jetty_t *jetty, urma_jetty_attr_t *attr) { - std::shared_lock lock(g_rw_mutex); + std::shared_lock lock(g_rw_mutex); if (!jetty || !attr || jetty_map.find(jetty) == jetty_map.end()) { return URMA_EINVAL; } @@ -520,7 +526,7 @@ urma_status_t urma_modify_jetty(urma_jetty_t *jetty, urma_jetty_attr_t *attr) { urma_status_t urma_post_jetty_send_wr(urma_jetty_t *jetty, urma_jfs_wr_t *wr, urma_jfs_wr_t **bad_wr) { - std::shared_lock read_lock(g_rw_mutex); + std::shared_lock read_lock(g_rw_mutex); auto local_it = jetty_map.find(jetty); auto local_jfc_it = jetty ? jfc_state_map.find(jetty->jetty_cfg.jfs_cfg.jfc) @@ -555,7 +561,7 @@ urma_status_t urma_post_jetty_send_wr(urma_jetty_t *jetty, urma_jfs_wr_t *wr, PendingRecv recv{}; urma_jfc_t* remote_jfc = nullptr; { - std::unique_lock lock(g_rw_mutex); + std::unique_lock lock(g_rw_mutex); auto remote_it = jetty_id_map.find(current->tjetty->id.id); if (remote_it == jetty_id_map.end()) { continue; @@ -585,7 +591,7 @@ urma_status_t urma_post_jetty_send_wr(urma_jetty_t *jetty, urma_jfs_wr_t *wr, JfcState* remote_state = nullptr; { - std::shared_lock lock(g_rw_mutex); + std::shared_lock lock(g_rw_mutex); auto state_it = jfc_state_map.find(remote_jfc); if (state_it != jfc_state_map.end()) { remote_state = state_it->second; @@ -613,7 +619,7 @@ urma_status_t urma_post_jetty_send_wr(urma_jetty_t *jetty, urma_jfs_wr_t *wr, urma_status_t urma_post_jfr_wr(urma_jfr_t *jfr, urma_jfr_wr_t *wr, urma_jfr_wr_t **bad_wr) { - std::unique_lock lock(g_rw_mutex); + std::unique_lock lock(g_rw_mutex); auto recv_it = jfr_recv_map.find(jfr); if (!jfr || !wr || recv_it == jfr_recv_map.end()) { if (bad_wr) { @@ -644,7 +650,7 @@ urma_status_t urma_post_jetty_recv_wr(urma_jetty_t *jetty, urma_jfr_wr_t **bad_wr) { urma_jfr_t* shared_jfr = nullptr; { - std::shared_lock lock(g_rw_mutex); + std::shared_lock lock(g_rw_mutex); if (!jetty || jetty_map.find(jetty) == jetty_map.end()) { if (bad_wr) { *bad_wr = wr; @@ -659,7 +665,7 @@ urma_status_t urma_post_jetty_recv_wr(urma_jetty_t *jetty, int urma_poll_jfc(urma_jfc_t *jfc, int num_entries, urma_cr_t *cr_list) { JfcState* state = nullptr; { - std::shared_lock lock(g_rw_mutex); + std::shared_lock lock(g_rw_mutex); auto it = jfc_state_map.find(jfc); if (it == jfc_state_map.end()) { return -1; @@ -690,7 +696,7 @@ int urma_wait_jfc(urma_jfce_t* jfce, uint32_t jfc_cnt, int, } uint64_t value = 0; (void)read(jfce->fd, &value, sizeof(value)); - std::shared_lock lock(g_rw_mutex); + std::shared_lock lock(g_rw_mutex); uint32_t count = 0; for (const auto& item : jfc_state_map) { if (count >= jfc_cnt || item.first->jfc_cfg.jfce != jfce) { @@ -708,6 +714,27 @@ int urma_wait_jfc(urma_jfce_t* jfce, uint32_t jfc_cnt, int, void urma_ack_jfc(urma_jfc_t*[], uint32_t[], uint32_t) { } +// Referenced by SetBondingMode() in urma_helper.cpp whenever the provider +// header urma_ubagg.h is available (BRPC_URMA_HAS_BONDING_EXT). Without a +// definition here, WITH_URMA=ON fails to link against the mock. The mock +// advertises no bonding device, so this is never reached at runtime, but the +// symbol must exist. +urma_status_t urma_user_ctl(urma_context_t *ctx, urma_user_ctl_in_t *in, + urma_user_ctl_out_t *out) { + if (ctx == nullptr || in == nullptr || out == nullptr) { + return URMA_EINVAL; + } + std::shared_lock lock(g_rw_mutex); + if (context_map.find(ctx) == context_map.end()) { + return URMA_EINVAL; + } + // No provider state to configure; accept the command and report an empty + // output buffer. + out->addr = 0; + out->len = 0; + return URMA_SUCCESS; +} + } // extern "C" #endif // BRPC_WITH_URMA