fix: runtime/core/util (#91)
This commit is contained in:
parent
5b01f4e9e1
commit
dac046b3fe
@ -153,15 +153,18 @@ if(AIMRT_BUILD_WITH_PROTOBUF)
|
|||||||
include(ProtobufGenCode)
|
include(ProtobufGenCode)
|
||||||
|
|
||||||
if(AIMRT_USE_LOCAL_PROTOC_COMPILER)
|
if(AIMRT_USE_LOCAL_PROTOC_COMPILER)
|
||||||
find_program(PROTOC_EXECUTABLE protoc)
|
if(NOT Protobuf_PROTOC_EXECUTABLE)
|
||||||
if(NOT PROTOC_EXECUTABLE)
|
find_program(PROTOC_EXECUTABLE protoc)
|
||||||
message(FATAL_ERROR "AIMRT_USE_LOCAL_PROTOC_COMPILER is ON, but can not find protoc compiler, " #
|
if(NOT PROTOC_EXECUTABLE)
|
||||||
"please install protoc and make it available in your PATH.")
|
message(FATAL_ERROR "AIMRT_USE_LOCAL_PROTOC_COMPILER is ON, but can not find protoc compiler, " #
|
||||||
|
"please install protoc and make it available in your PATH, or set Protobuf_PROTOC_EXECUTABLE to protoc path")
|
||||||
|
endif()
|
||||||
|
message(STATUS "Found local protoc compiler: ${PROTOC_EXECUTABLE}")
|
||||||
|
set(Protobuf_PROTOC_EXECUTABLE
|
||||||
|
${PROTOC_EXECUTABLE}
|
||||||
|
CACHE STRING "Path to local protoc compiler.")
|
||||||
endif()
|
endif()
|
||||||
message(STATUS "Found local protoc compiler: ${PROTOC_EXECUTABLE}")
|
|
||||||
set(Protobuf_PROTOC_EXECUTABLE
|
|
||||||
${PROTOC_EXECUTABLE}
|
|
||||||
CACHE STRING "Path to local protoc compiler.")
|
|
||||||
add_executable(aimrt::protoc IMPORTED GLOBAL)
|
add_executable(aimrt::protoc IMPORTED GLOBAL)
|
||||||
set_target_properties(aimrt::protoc PROPERTIES IMPORTED_LOCATION ${Protobuf_PROTOC_EXECUTABLE})
|
set_target_properties(aimrt::protoc PROPERTIES IMPORTED_LOCATION ${Protobuf_PROTOC_EXECUTABLE})
|
||||||
set_property(GLOBAL PROPERTY PROTOC_NAMESPACE_PROPERTY "aimrt")
|
set_property(GLOBAL PROPERTY PROTOC_NAMESPACE_PROPERTY "aimrt")
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
@echo off
|
@echo off
|
||||||
setlocal
|
setlocal
|
||||||
|
|
||||||
|
if exist .\build\install (
|
||||||
|
rmdir /s /q .\build\install
|
||||||
|
)
|
||||||
|
|
||||||
cmake -B build ^
|
cmake -B build ^
|
||||||
-DCMAKE_BUILD_TYPE=Release ^
|
-DCMAKE_BUILD_TYPE=Release ^
|
||||||
-DAIMRT_INSTALL=ON ^
|
-DAIMRT_INSTALL=ON ^
|
||||||
@ -36,10 +40,6 @@ if %errorlevel% neq 0 (
|
|||||||
exit /b 1
|
exit /b 1
|
||||||
)
|
)
|
||||||
|
|
||||||
if exist .\build\install (
|
|
||||||
rmdir /s /q .\build\install
|
|
||||||
)
|
|
||||||
|
|
||||||
cmake --build build --config Release --target install --parallel %NUMBER_OF_PROCESSORS%
|
cmake --build build --config Release --target install --parallel %NUMBER_OF_PROCESSORS%
|
||||||
|
|
||||||
if %errorlevel% neq 0 (
|
if %errorlevel% neq 0 (
|
||||||
|
8
build.sh
8
build.sh
@ -3,6 +3,10 @@
|
|||||||
# exit on error and print each command
|
# exit on error and print each command
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
if [ -d ./build/install ]; then
|
||||||
|
rm -rf ./build/install
|
||||||
|
fi
|
||||||
|
|
||||||
cmake -B build \
|
cmake -B build \
|
||||||
-DCMAKE_BUILD_TYPE=Release \
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
-DAIMRT_INSTALL=ON \
|
-DAIMRT_INSTALL=ON \
|
||||||
@ -33,8 +37,4 @@ cmake -B build \
|
|||||||
-DAIMRT_BUILD_PYTHON_PACKAGE=ON \
|
-DAIMRT_BUILD_PYTHON_PACKAGE=ON \
|
||||||
$@
|
$@
|
||||||
|
|
||||||
if [ -d ./build/install ]; then
|
|
||||||
rm -rf ./build/install
|
|
||||||
fi
|
|
||||||
|
|
||||||
cmake --build build --config Release --target install --parallel $(nproc)
|
cmake --build build --config Release --target install --parallel $(nproc)
|
||||||
|
@ -32,12 +32,12 @@ class DynamicLib {
|
|||||||
DynamicLib(const DynamicLib&) = delete;
|
DynamicLib(const DynamicLib&) = delete;
|
||||||
DynamicLib& operator=(const DynamicLib&) = delete;
|
DynamicLib& operator=(const DynamicLib&) = delete;
|
||||||
|
|
||||||
bool Load(const std::string& libname) {
|
bool Load(const std::string& lib_name) {
|
||||||
Unload();
|
Unload();
|
||||||
libname_ = libname;
|
lib_name_ = lib_name;
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
handle_ = LoadLibraryEx(libname_.c_str(), NULL, 0);
|
handle_ = LoadLibraryEx(lib_name_.c_str(), NULL, 0);
|
||||||
|
|
||||||
if (nullptr == handle_) return false;
|
if (nullptr == handle_) return false;
|
||||||
|
|
||||||
@ -45,13 +45,13 @@ class DynamicLib {
|
|||||||
DWORD re = GetModuleFileName(handle_, buf, MAX_PATH);
|
DWORD re = GetModuleFileName(handle_, buf, MAX_PATH);
|
||||||
if (re != 0) lib_full_path_ = std::string(buf);
|
if (re != 0) lib_full_path_ = std::string(buf);
|
||||||
#else
|
#else
|
||||||
handle_ = dlopen(libname_.c_str(), RTLD_NOW | RTLD_LOCAL | RTLD_DEEPBIND);
|
handle_ = dlopen(lib_name_.c_str(), RTLD_NOW | RTLD_LOCAL | RTLD_DEEPBIND);
|
||||||
|
|
||||||
if (nullptr == handle_) return false;
|
if (nullptr == handle_) return false;
|
||||||
|
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
dlinfo(handle_, RTLD_DI_ORIGIN, &buf);
|
dlinfo(handle_, RTLD_DI_ORIGIN, &buf);
|
||||||
lib_full_path_ = std::filesystem::canonical(std::filesystem::path(buf) / libname_).string();
|
lib_full_path_ = std::filesystem::canonical(std::filesystem::path(buf) / lib_name_).string();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -74,7 +74,7 @@ class DynamicLib {
|
|||||||
handle_ = nullptr;
|
handle_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsLoaded() const { return nullptr == handle_; }
|
bool IsLoaded() const { return nullptr != handle_; }
|
||||||
|
|
||||||
SymbolType GetSymbol(const std::string& symbol_name) {
|
SymbolType GetSymbol(const std::string& symbol_name) {
|
||||||
if (nullptr == handle_)
|
if (nullptr == handle_)
|
||||||
@ -87,7 +87,7 @@ class DynamicLib {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& GetLibName() const { return libname_; }
|
const std::string& GetLibName() const { return lib_name_; }
|
||||||
|
|
||||||
const std::string& GetLibFullPath() const { return lib_full_path_; }
|
const std::string& GetLibFullPath() const { return lib_full_path_; }
|
||||||
|
|
||||||
@ -111,7 +111,7 @@ class DynamicLib {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
DynlibHandle handle_ = nullptr;
|
DynlibHandle handle_ = nullptr;
|
||||||
std::string libname_;
|
std::string lib_name_;
|
||||||
std::string lib_full_path_;
|
std::string lib_full_path_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -35,14 +35,14 @@ wheel_size: [1000, 600]
|
|||||||
s = std::move(msg);
|
s = std::move(msg);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 正常处理
|
// normal test
|
||||||
rpc_client_tool.Record(1, std::chrono::milliseconds(100), "msg 1");
|
rpc_client_tool.Record(1, std::chrono::milliseconds(100), "msg 1");
|
||||||
auto msg = rpc_client_tool.GetRecord(1);
|
auto msg = rpc_client_tool.GetRecord(1);
|
||||||
EXPECT_STREQ(msg->c_str(), "msg 1");
|
EXPECT_STREQ(msg->c_str(), "msg 1");
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||||
EXPECT_STREQ(s.c_str(), "");
|
EXPECT_STREQ(s.c_str(), "");
|
||||||
|
|
||||||
// 超时处理
|
// timeout test
|
||||||
rpc_client_tool.Record(2, std::chrono::milliseconds(100), "msg 2");
|
rpc_client_tool.Record(2, std::chrono::milliseconds(100), "msg 2");
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||||
EXPECT_STREQ(s.c_str(), "msg 2");
|
EXPECT_STREQ(s.c_str(), "msg 2");
|
||||||
|
@ -9,14 +9,13 @@
|
|||||||
namespace aimrt::runtime::core::util {
|
namespace aimrt::runtime::core::util {
|
||||||
|
|
||||||
#if !defined(_WIN32)
|
#if !defined(_WIN32)
|
||||||
// 非Windows系统下,获取当前线程的名字
|
|
||||||
std::string GetCurrentThreadName() {
|
std::string GetCurrentThreadName() {
|
||||||
char name[16];
|
char name[16];
|
||||||
pthread_getname_np(pthread_self(), name, 16);
|
pthread_getname_np(pthread_self(), name, 16);
|
||||||
return std::string(name);
|
return std::string(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取当前线程的CPU亲和性掩码
|
|
||||||
std::vector<uint32_t> GetCurrentThreadAffinity() {
|
std::vector<uint32_t> GetCurrentThreadAffinity() {
|
||||||
cpu_set_t cpuset;
|
cpu_set_t cpuset;
|
||||||
CPU_ZERO(&cpuset);
|
CPU_ZERO(&cpuset);
|
||||||
@ -36,42 +35,34 @@ std::vector<uint32_t> GetCurrentThreadAffinity() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
TEST(ThreadToolsTest, SetNameForCurrentThread) {
|
TEST(ThreadToolsTest, SetNameForCurrentThread) {
|
||||||
// 测试给一个短名字的线程设置名字
|
|
||||||
#if !defined(_WIN32)
|
#if !defined(_WIN32)
|
||||||
|
|
||||||
std::string short_name = "short_name";
|
std::string short_name = "short_name";
|
||||||
SetNameForCurrentThread(short_name);
|
SetNameForCurrentThread(short_name);
|
||||||
EXPECT_EQ(GetCurrentThreadName(), short_name);
|
EXPECT_EQ(GetCurrentThreadName(), short_name);
|
||||||
|
|
||||||
// 测试给一个长名字的线程设置名字
|
|
||||||
std::string long_name = "long_thread_name_more_than_15_characters_long";
|
std::string long_name = "long_thread_name_more_than_15_characters_long";
|
||||||
SetNameForCurrentThread(long_name);
|
SetNameForCurrentThread(long_name);
|
||||||
std::string expected_name = "long_thr.._long";
|
std::string expected_name = "long_thr.._long";
|
||||||
EXPECT_EQ(GetCurrentThreadName(), expected_name);
|
EXPECT_EQ(GetCurrentThreadName(), expected_name);
|
||||||
#else
|
#else
|
||||||
// 测试Windows平台不支持的情况
|
|
||||||
GTEST_SKIP() << "Skipping this test on Windows as it is not supported.";
|
GTEST_SKIP() << "Skipping this test on Windows as it is not supported.";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ThreadToolsTest, BindCpuForCurrentThread) {
|
TEST(ThreadToolsTest, BindCpuForCurrentThread) {
|
||||||
#if !defined(_WIN32)
|
#if !defined(_WIN32)
|
||||||
// 测试正常情况
|
|
||||||
std::vector<uint32_t> cpu_set = {0, 1};
|
std::vector<uint32_t> cpu_set = {0, 1};
|
||||||
EXPECT_NO_THROW(BindCpuForCurrentThread(cpu_set));
|
EXPECT_NO_THROW(BindCpuForCurrentThread(cpu_set));
|
||||||
|
|
||||||
// 判断cpu_set和GetCurrentThreadAffinity返回值是否相等
|
|
||||||
EXPECT_EQ(cpu_set, GetCurrentThreadAffinity());
|
EXPECT_EQ(cpu_set, GetCurrentThreadAffinity());
|
||||||
|
|
||||||
// 测试空cpu_set
|
|
||||||
std::vector<uint32_t> empty_cpu_set = {};
|
std::vector<uint32_t> empty_cpu_set = {};
|
||||||
EXPECT_NO_THROW(BindCpuForCurrentThread(empty_cpu_set));
|
EXPECT_NO_THROW(BindCpuForCurrentThread(empty_cpu_set));
|
||||||
|
|
||||||
// 测试无效的CPU索引
|
|
||||||
EXPECT_ANY_THROW(BindCpuForCurrentThread({10000}));
|
EXPECT_ANY_THROW(BindCpuForCurrentThread({10000}));
|
||||||
|
|
||||||
#else
|
#else
|
||||||
// 测试Windows平台不支持的情况
|
|
||||||
EXPECT_ANY_THROW(BindCpuForCurrentThread({10000}));
|
EXPECT_ANY_THROW(BindCpuForCurrentThread({10000}));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -81,13 +72,10 @@ TEST(ThreadToolsTest, SetCpuSchedForCurrentThread) {
|
|||||||
|
|
||||||
auto lgr = aimrt::common::util::SimpleLogger();
|
auto lgr = aimrt::common::util::SimpleLogger();
|
||||||
|
|
||||||
// 测试传入空字符串
|
|
||||||
EXPECT_NO_THROW(SetCpuSchedForCurrentThread(""));
|
EXPECT_NO_THROW(SetCpuSchedForCurrentThread(""));
|
||||||
|
|
||||||
// 测试传入SCHED_OTHER
|
|
||||||
EXPECT_NO_THROW(SetCpuSchedForCurrentThread("SCHED_OTHER"));
|
EXPECT_NO_THROW(SetCpuSchedForCurrentThread("SCHED_OTHER"));
|
||||||
|
|
||||||
// 测试传入SCHED_FIFO,先判断是否有权限访问(因为没有权限,不确定是否会正常运行)
|
|
||||||
if (sched_setscheduler(0, SCHED_FIFO, nullptr) == 0) {
|
if (sched_setscheduler(0, SCHED_FIFO, nullptr) == 0) {
|
||||||
int priority_max_fifo = sched_get_priority_max(SCHED_FIFO);
|
int priority_max_fifo = sched_get_priority_max(SCHED_FIFO);
|
||||||
int priority_min_fifo = sched_get_priority_min(SCHED_FIFO);
|
int priority_min_fifo = sched_get_priority_min(SCHED_FIFO);
|
||||||
@ -98,7 +86,6 @@ TEST(ThreadToolsTest, SetCpuSchedForCurrentThread) {
|
|||||||
AIMRT_HL_WARN(lgr, "This is a test warning: Failed to set SCHED_FIFO scheduler, permission denied !");
|
AIMRT_HL_WARN(lgr, "This is a test warning: Failed to set SCHED_FIFO scheduler, permission denied !");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 测试传入SCHED_RR,先判断是否有权限访问
|
|
||||||
if (sched_setscheduler(0, SCHED_RR, nullptr) == 0) {
|
if (sched_setscheduler(0, SCHED_RR, nullptr) == 0) {
|
||||||
int priority_max_rr = sched_get_priority_max(SCHED_RR);
|
int priority_max_rr = sched_get_priority_max(SCHED_RR);
|
||||||
int priority_min_rr = sched_get_priority_min(SCHED_RR);
|
int priority_min_rr = sched_get_priority_min(SCHED_RR);
|
||||||
@ -109,22 +96,18 @@ TEST(ThreadToolsTest, SetCpuSchedForCurrentThread) {
|
|||||||
AIMRT_HL_WARN(lgr, "This is a test warning: Failed to set SCHED_RR scheduler, permission denied !");
|
AIMRT_HL_WARN(lgr, "This is a test warning: Failed to set SCHED_RR scheduler, permission denied !");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 测试传入无效策略
|
|
||||||
EXPECT_ANY_THROW(SetCpuSchedForCurrentThread("SCHED_INVALID"));
|
EXPECT_ANY_THROW(SetCpuSchedForCurrentThread("SCHED_INVALID"));
|
||||||
|
|
||||||
// 测试传入无效策略优先级
|
|
||||||
int priority_max = sched_get_priority_max(SCHED_FIFO);
|
int priority_max = sched_get_priority_max(SCHED_FIFO);
|
||||||
int priority_min = sched_get_priority_min(SCHED_FIFO);
|
int priority_min = sched_get_priority_min(SCHED_FIFO);
|
||||||
int priority = priority_max + 1;
|
int priority = priority_max + 1;
|
||||||
std::string sched = "SCHED_FIFO:" + std::to_string(priority);
|
std::string sched = "SCHED_FIFO:" + std::to_string(priority);
|
||||||
EXPECT_ANY_THROW(SetCpuSchedForCurrentThread(sched));
|
EXPECT_ANY_THROW(SetCpuSchedForCurrentThread(sched));
|
||||||
|
|
||||||
// 测试传入无效格式、
|
|
||||||
EXPECT_THROW(SetCpuSchedForCurrentThread("SCHED_FIFO"), aimrt::common::util::AimRTException);
|
EXPECT_THROW(SetCpuSchedForCurrentThread("SCHED_FIFO"), aimrt::common::util::AimRTException);
|
||||||
EXPECT_THROW(SetCpuSchedForCurrentThread("SCHED_FIFO:"), aimrt::common::util::AimRTException);
|
EXPECT_THROW(SetCpuSchedForCurrentThread("SCHED_FIFO:"), aimrt::common::util::AimRTException);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
// 测试Windows平台不支持的情况
|
|
||||||
EXPECT_THROW(SetCpuSchedForCurrentThread("SCHED_OTHER"), aimrt::common::util::AimRTException);
|
EXPECT_THROW(SetCpuSchedForCurrentThread("SCHED_OTHER"), aimrt::common::util::AimRTException);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,10 @@
|
|||||||
// All rights reserved.
|
// All rights reserved.
|
||||||
|
|
||||||
#include "core/util/type_support_pkg_loader.h"
|
#include "core/util/type_support_pkg_loader.h"
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
#include "util/exception.h"
|
#include "util/exception.h"
|
||||||
#include "util/format.h"
|
|
||||||
|
|
||||||
namespace aimrt::runtime::core::util {
|
namespace aimrt::runtime::core::util {
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
#include "aimrt_module_c_interface/util/type_support_base.h"
|
#include "aimrt_module_c_interface/util/type_support_base.h"
|
||||||
|
|
||||||
#include "core/util/dynamic_lib.h"
|
#include "core/util/dynamic_lib.h"
|
||||||
#include "util/log_util.h"
|
|
||||||
|
|
||||||
namespace aimrt::runtime::core::util {
|
namespace aimrt::runtime::core::util {
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
namespace aimrt::runtime::core::util {
|
namespace aimrt::runtime::core::util {
|
||||||
|
|
||||||
// 计算两个字符串的距离
|
|
||||||
int LevenshteinDistance(const std::string& s1, const std::string& s2) {
|
int LevenshteinDistance(const std::string& s1, const std::string& s2) {
|
||||||
int len1 = s1.size();
|
int len1 = s1.size();
|
||||||
int len2 = s2.size();
|
int len2 = s2.size();
|
||||||
@ -26,7 +25,6 @@ int LevenshteinDistance(const std::string& s1, const std::string& s2) {
|
|||||||
return dp[len1][len2];
|
return dp[len1][len2];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 找到最接近的匹配节点
|
|
||||||
std::string FindClosestMatch(const YAML::Node& node, const std::string& target) {
|
std::string FindClosestMatch(const YAML::Node& node, const std::string& target) {
|
||||||
std::string closest_match;
|
std::string closest_match;
|
||||||
int min_distance = 4;
|
int min_distance = 4;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user