1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
//
// Copyright 2019 Ettus Research, a National Instruments brand
//
// SPDX-License-Identifier: GPL-3.0-or-later
//
#include <uhd/utils/log.hpp>
#include <uhdlib/usrp/common/io_service_args.hpp>
#include <uhdlib/usrp/constrained_device_args.hpp>
#include <boost/format.hpp>
#include <regex>
#include <string>
static const std::string LOG_ID = "IO_SRV";
static const char* recv_offload_str = "recv_offload";
static const char* send_offload_str = "send_offload";
static const char* recv_offload_wait_mode_str = "recv_offload_wait_mode";
static const char* send_offload_wait_mode_str = "send_offload_wait_mode";
static const char* num_poll_offload_threads_str = "num_poll_offload_threads";
static const std::regex recv_offload_thread_cpu_expr("^recv_offload_thread_(\\d+)_cpu");
static const std::regex send_offload_thread_cpu_expr("^send_offload_thread_(\\d+)_cpu");
static const std::regex poll_offload_thread_cpu_expr("^poll_offload_thread_(\\d+)_cpu");
namespace uhd { namespace usrp {
namespace {
bool get_bool_arg(const device_addr_t& args, const std::string& key, const bool def)
{
constrained_device_args_t::bool_arg arg(key, def);
if (args.has_key(key)) {
arg.parse(args[key]);
}
return arg.get();
}
io_service_args_t::wait_mode_t get_wait_mode_arg(const device_addr_t& args,
const std::string& key,
const io_service_args_t::wait_mode_t def)
{
constrained_device_args_t::enum_arg<io_service_args_t::wait_mode_t> arg(key,
def,
{{"poll", io_service_args_t::POLL}, {"block", io_service_args_t::BLOCK}});
if (args.has_key(key)) {
arg.parse(args[key]);
}
return arg.get();
}
}; // namespace
io_service_args_t read_io_service_args(
const device_addr_t& args, const io_service_args_t& defaults)
{
io_service_args_t io_srv_args;
std::string tmp_str, default_str;
io_srv_args.recv_offload =
get_bool_arg(args, recv_offload_str, defaults.recv_offload);
io_srv_args.send_offload =
get_bool_arg(args, send_offload_str, defaults.send_offload);
io_srv_args.recv_offload_wait_mode = get_wait_mode_arg(
args, recv_offload_wait_mode_str, defaults.recv_offload_wait_mode);
io_srv_args.send_offload_wait_mode = get_wait_mode_arg(
args, send_offload_wait_mode_str, defaults.send_offload_wait_mode);
io_srv_args.num_poll_offload_threads = args.cast<size_t>(
num_poll_offload_threads_str, defaults.num_poll_offload_threads);
if (io_srv_args.num_poll_offload_threads == 0) {
UHD_LOG_WARNING(LOG_ID,
"Invalid value for num_poll_offload_threads. "
"Value must be greater than 0.");
io_srv_args.num_poll_offload_threads = 1;
}
auto read_thread_args = [&args](
const std::regex& expr, std::map<size_t, size_t>& dest) {
auto keys = args.keys();
for (const auto& key : keys) {
std::smatch match;
if (std::regex_match(key, match, expr)) {
UHD_ASSERT_THROW(match.size() == 2); // first match is the entire key
const size_t thread = std::stoul(match.str(1));
const size_t cpu = args.cast<size_t>(key, 0);
dest[thread] = cpu;
}
}
};
read_thread_args(recv_offload_thread_cpu_expr, io_srv_args.recv_offload_thread_cpu);
read_thread_args(send_offload_thread_cpu_expr, io_srv_args.send_offload_thread_cpu);
read_thread_args(poll_offload_thread_cpu_expr, io_srv_args.poll_offload_thread_cpu);
return io_srv_args;
}
device_addr_t merge_io_service_dev_args(
const device_addr_t& dev_args, const device_addr_t& stream_args)
{
device_addr_t args = stream_args;
auto merge_args = [](const device_addr_t& dev_args,
device_addr_t& stream_args,
const std::string& key) {
if (!stream_args.has_key(key)) {
if (dev_args.has_key(key)) {
stream_args[key] = dev_args[key];
}
}
};
merge_args(dev_args, args, recv_offload_str);
merge_args(dev_args, args, send_offload_str);
merge_args(dev_args, args, recv_offload_wait_mode_str);
merge_args(dev_args, args, send_offload_wait_mode_str);
merge_args(dev_args, args, num_poll_offload_threads_str);
auto merge_thread_args = [&merge_args](const device_addr_t& dev_args,
device_addr_t& stream_args,
const std::regex& expr) {
auto keys = dev_args.keys();
for (const auto& key : keys) {
std::smatch match;
if (std::regex_match(key, match, expr)) {
merge_args(dev_args, stream_args, key);
}
}
};
merge_thread_args(dev_args, args, recv_offload_thread_cpu_expr);
merge_thread_args(dev_args, args, send_offload_thread_cpu_expr);
merge_thread_args(dev_args, args, poll_offload_thread_cpu_expr);
return args;
}
}} // namespace uhd::usrp
|