|
| 1 | +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
| 2 | +// vim: ts=8 sw=2 smarttab |
| 3 | + |
| 4 | +#pragma once |
| 5 | + |
| 6 | +#include <cstdlib> |
| 7 | +#include <iostream> |
| 8 | +#include <optional> |
| 9 | +#include <regex> |
| 10 | +#include <string> |
| 11 | +#include <vector> |
| 12 | + |
| 13 | +#include <boost/algorithm/string.hpp> |
| 14 | +#include <fmt/format.h> |
| 15 | +#include <seastar/core/resource.hh> |
| 16 | +#include <seastar/core/app-template.hh> |
| 17 | + |
| 18 | +struct ctest_resource { |
| 19 | + int id; |
| 20 | + int slots; |
| 21 | + ctest_resource(int id, int slots) : id(id), slots(slots) {} |
| 22 | +}; |
| 23 | + |
| 24 | +static std::vector<ctest_resource> parse_ctest_resources(const std::string& resource_spec) { |
| 25 | + std::vector<std::string> resources; |
| 26 | + boost::split(resources, resource_spec, boost::is_any_of(";")); |
| 27 | + std::regex res_regex("id:([0-9]+),slots:([0-9]+)"); |
| 28 | + std::vector<ctest_resource> ctest_resources; |
| 29 | + for (auto& resource : resources) { |
| 30 | + std::smatch matched; |
| 31 | + if (std::regex_match(resource, matched, res_regex)) { |
| 32 | + int id = std::stoi(matched[1].str()); |
| 33 | + int slots = std::stoi(matched[2].str()); |
| 34 | + ctest_resources.emplace_back(id, slots); |
| 35 | + } |
| 36 | + } |
| 37 | + return ctest_resources; |
| 38 | +} |
| 39 | + |
| 40 | +static std::optional<seastar::resource::cpuset> get_cpuset_from_ctest_resource_group() { |
| 41 | + int nr_groups = 0; |
| 42 | + auto group_count = std::getenv("CTEST_RESOURCE_GROUP_COUNT"); |
| 43 | + if (group_count != nullptr) { |
| 44 | + nr_groups = std::stoi(group_count); |
| 45 | + } else { |
| 46 | + return {}; |
| 47 | + } |
| 48 | + |
| 49 | + seastar::resource::cpuset cpuset; |
| 50 | + for (int num = 0; num < nr_groups; num++) { |
| 51 | + std::string resource_type_name; |
| 52 | + fmt::format_to(std::back_inserter(resource_type_name), "CTEST_RESOURCE_GROUP_{}", num); |
| 53 | + // only a single resource type is supported for now |
| 54 | + std::string resource_type = std::getenv(resource_type_name.data()); |
| 55 | + if (resource_type == "cpus") { |
| 56 | + std::transform(resource_type.begin(), resource_type.end(), resource_type.begin(), ::toupper); |
| 57 | + std::string resource_group; |
| 58 | + fmt::format_to(std::back_inserter(resource_group), "CTEST_RESOURCE_GROUP_{}_{}", num, resource_type); |
| 59 | + std::string resource_spec = std::getenv(resource_group.data()); |
| 60 | + for (auto& resource : parse_ctest_resources(resource_spec)) { |
| 61 | + // each id has a single cpu slot |
| 62 | + cpuset.insert(resource.id); |
| 63 | + } |
| 64 | + } else { |
| 65 | + fmt::print(std::cerr, "unsupported resource type: {}", resource_type); |
| 66 | + } |
| 67 | + } |
| 68 | + return cpuset; |
| 69 | +} |
| 70 | + |
| 71 | +static seastar::app_template::seastar_options get_smp_opts_from_ctest() { |
| 72 | + seastar::app_template::seastar_options opts; |
| 73 | + auto cpuset = get_cpuset_from_ctest_resource_group(); |
| 74 | + if (cpuset) { |
| 75 | + opts.smp_opts.cpuset.set_value(*cpuset); |
| 76 | + } |
| 77 | + return opts; |
| 78 | +} |
0 commit comments