53 constexpr explicit ThreadPriority(
int priority = 0) : priority_(std::clamp(priority, min_priority, max_priority))
57 [[nodiscard]]
constexpr auto value()
const noexcept ->
int
61 [[nodiscard]]
constexpr auto is_valid()
const noexcept ->
bool
63 return priority_ >= min_priority && priority_ <= max_priority;
67 static constexpr auto lowest() -> ThreadPriority
69 return ThreadPriority(min_priority);
71 static constexpr auto normal() -> ThreadPriority
73 return ThreadPriority(0);
75 static constexpr auto highest() -> ThreadPriority
77 return ThreadPriority(max_priority);
81 [[nodiscard]]
auto operator==(ThreadPriority
const& other)
const ->
bool
83 return priority_ == other.priority_;
85 [[nodiscard]]
auto operator!=(ThreadPriority
const& other)
const ->
bool
87 return priority_ != other.priority_;
89 [[nodiscard]]
auto operator<(ThreadPriority
const& other)
const ->
bool
91 return priority_ < other.priority_;
93 [[nodiscard]]
auto operator<=(ThreadPriority
const& other)
const ->
bool
95 return priority_ <= other.priority_;
97 [[nodiscard]]
auto operator>(ThreadPriority
const& other)
const ->
bool
99 return priority_ > other.priority_;
101 [[nodiscard]]
auto operator>=(ThreadPriority
const& other)
const ->
bool
103 return priority_ >= other.priority_;
106 [[nodiscard]]
auto to_string()
const -> std::string
108 std::ostringstream oss;
109 oss <<
"ThreadPriority(" << priority_ <<
")";
114 static constexpr int min_priority = -20;
115 static constexpr int max_priority = 19;
135 explicit ThreadAffinity(std::vector<int>
const& cpus) : ThreadAffinity()
144 void add_cpu(
int cpu)
149 WORD g =
static_cast<WORD
>(cpu / 64);
160 mask_ |= (
static_cast<unsigned long long>(1) << bit);
162 if (cpu >= 0 && cpu < CPU_SETSIZE)
164 CPU_SET(cpu, &cpuset_);
169 void remove_cpu(
int cpu)
174 WORD g =
static_cast<WORD
>(cpu / 64);
178 mask_ &= ~(
static_cast<unsigned long long>(1) << bit);
181 if (cpu >= 0 && cpu < CPU_SETSIZE)
183 CPU_CLR(cpu, &cpuset_);
188 [[nodiscard]]
auto is_set(
int cpu)
const ->
bool
193 WORD g =
static_cast<WORD
>(cpu / 64);
195 return g == group_ && (mask_ & (
static_cast<unsigned long long>(1) << bit)) != 0;
197 return cpu >= 0 && cpu < CPU_SETSIZE && CPU_ISSET(cpu, &cpuset_);
201 [[nodiscard]]
auto has_cpu(
int cpu)
const ->
bool
215 [[nodiscard]]
auto get_cpus()
const -> std::vector<int>
217 std::vector<int> cpus;
219 for (
int i = 0; i < 64; ++i)
221 if (mask_ & (
static_cast<unsigned long long>(1) << i))
223 cpus.push_back(
static_cast<int>(group_) * 64 + i);
227 for (
int i = 0; i < CPU_SETSIZE; ++i)
229 if (CPU_ISSET(i, &cpuset_))
239 [[nodiscard]]
unsigned long long get_mask()
const
243 [[nodiscard]] WORD get_group()
const
247 [[nodiscard]]
bool has_any()
const
252 [[nodiscard]]
auto native_handle()
const -> cpu_set_t
const&
258 [[nodiscard]]
auto to_string()
const -> std::string
260 auto cpus = get_cpus();
261 std::ostringstream oss;
262 oss <<
"ThreadAffinity({";
263 for (
size_t i = 0; i < cpus.size(); ++i)
276 unsigned long long mask_;
290 struct sched_param_win
298 sched_param_win param{};
300 param.sched_priority = priority.value();
310 static auto create_for_policy(SchedulingPolicy policy,
ThreadPriority priority)
315 int const policy_int =
static_cast<int>(policy);
316 int const min_prio = sched_get_priority_min(policy_int);
317 int const max_prio = sched_get_priority_max(policy_int);
319 if (min_prio == -1 || max_prio == -1)
321 return unexpected(std::make_error_code(std::errc::invalid_argument));
324 param.sched_priority = std::clamp(priority.value(), min_prio, max_prio);
330 int const policy_int =
static_cast<int>(policy);
331 int const min_prio = sched_get_priority_min(policy_int);
332 int const max_prio = sched_get_priority_max(policy_int);
334 if (min_prio == -1 || max_prio == -1)
336 return unexpected(std::make_error_code(std::errc::invalid_argument));
339 return max_prio - min_prio;