14#include <sys/resource.h>
20inline constexpr bool ALWAYS_FALSE_V =
false;
26std::error_code
Apply(IdleScheduler
const& scheduler)
noexcept {
27 return Apply(0, scheduler);
30std::error_code
Apply(DynamicScheduler
const& scheduler)
noexcept {
31 return Apply(0, scheduler);
34std::error_code
Apply(StaticScheduler
const& scheduler)
noexcept {
35 return Apply(0, scheduler);
38std::error_code
Apply(Scheduler
const& scheduler)
noexcept {
39 return Apply(0, scheduler);
50 thread,
static_cast<int>(scheduler.GetPolicy()), 0, scheduler.GetNice());
55 thread,
static_cast<int>(scheduler.GetPolicy()), scheduler.GetPriority(), 0);
58std::error_code
Apply(pid_t thread,
Scheduler const& scheduler)
noexcept {
59 return std::visit([thread](
auto const& sched) {
return Apply(thread, sched); },
63std::ostream& operator<<(std::ostream& os,
IdleScheduler const& scheduler) {
69 if (
auto err = SetPolicy(policy); err) {
70 throw std::system_error(err);
72 if (
auto err = SetPriority(prio); err) {
73 throw std::system_error(err);
77std::error_code StaticScheduler::SetPolicy(Policy policy)
noexcept {
84 return std::make_error_code(std::errc::invalid_argument);
89std::error_code StaticScheduler::SetPriority(
int priority) {
90 if (priority < 1 || priority > 99) {
91 return std::make_error_code(std::errc::invalid_argument);
97std::ostream& operator<<(std::ostream& os, StaticScheduler::Policy
const& policy) {
99 case StaticScheduler::Policy::Rr:
102 case StaticScheduler::Policy::Fifo:
109std::ostream& operator<<(std::ostream& os, StaticScheduler
const& scheduler) {
110 os <<
"Static {policy=" << scheduler.GetPolicy() <<
", priority=" << scheduler.GetPriority()
115DynamicScheduler::DynamicScheduler(Policy policy,
int priority)
116 : m_policy(Policy::Other), m_priority(0) {
117 if (
auto err = SetPolicy(policy); err) {
118 throw std::system_error(err);
120 if (
auto err = SetNice(priority); err) {
121 throw std::system_error(err);
125std::error_code DynamicScheduler::SetNice(
int priority)
noexcept {
126 if (priority < -20 || priority > 19) {
127 return std::make_error_code(std::errc::invalid_argument);
129 m_priority = priority;
133int DynamicScheduler::GetNice() const noexcept {
137std::error_code DynamicScheduler::SetPolicy(Policy policy)
noexcept {
144 return std::make_error_code(std::errc::invalid_argument);
149std::ostream& operator<<(std::ostream& os, DynamicScheduler::Policy
const& policy) {
151 case DynamicScheduler::Policy::Other:
154 case DynamicScheduler::Policy::Batch:
161std::ostream& operator<<(std::ostream& os, DynamicScheduler
const& scheduler) {
162 os <<
"Dynamic {policy=" << scheduler.GetPolicy() <<
", nice=" << scheduler.GetNice() <<
"}";
166Scheduler::Scheduler(SchedulerVariant&& sched) noexcept : m_scheduler(sched) {
169Scheduler::Scheduler(SchedulerVariant
const& sched) : m_scheduler(sched) {
172Scheduler::Scheduler(IdleScheduler sched) noexcept
173 : m_scheduler(std::in_place_type<IdleScheduler>, sched) {
176Scheduler::Scheduler(StaticScheduler sched) noexcept
177 : m_scheduler(std::in_place_type<StaticScheduler>, sched) {
180Scheduler::Scheduler(DynamicScheduler sched) noexcept
181 : m_scheduler(std::in_place_type<DynamicScheduler>, sched) {
190Scheduler Scheduler::MakeFromActive() {
191 return MakeFromActive(0);
194Scheduler Scheduler::MakeFromActive(pid_t pid) {
198 if (
auto err = ll::GetSchedulerPolicy(pid, &policy, &static_prio, &dynamic_prio); err) {
199 throw std::system_error(err);
205 DynamicScheduler(
static_cast<DynamicScheduler::Policy
>(policy), dynamic_prio));
210 StaticScheduler(
static_cast<StaticScheduler::Policy
>(policy), static_prio));
212 return Scheduler(IdleScheduler());
214 throw std::system_error(std::make_error_code(std::errc::not_supported));
218std::ostream& operator<<(std::ostream& os, Scheduler
const& scheduler) {
220 [&](
auto const& sched) {
221 using T = std::decay_t<
decltype(sched)>;
222 if constexpr (std::is_same_v<T, IdleScheduler>) {
223 os <<
"Scheduler {IdleScheduler}";
224 }
else if constexpr (std::is_same_v<T, DynamicScheduler>) {
225 os <<
"Scheduler {" << sched <<
"}";
226 }
else if constexpr (std::is_same_v<T, StaticScheduler>) {
227 os <<
"Scheduler {" << sched <<
"}";
229 static_assert(ALWAYS_FALSE_V<T>,
"non-exhaustive visitor!");
Normal non-realtime scheduler that use dynamic priority (nice value).
Represents SCHED_IDLE scheduler policy.
A sum-type of all supported schedulers.
Static priority scheduler (real-time).
StaticScheduler(Policy policy, int priority)
Create with provided policy and priority.
std::error_code Apply(CpuAffinity const &affinity) noexcept
Apply policy to calling thread.
std::error_code Apply(pid_t thread, CpuAffinity const &affinity) noexcept
Apply policy to specified thread.
std::variant< DynamicScheduler, StaticScheduler, IdleScheduler > SchedulerVariant
Variant of possible schedulers.
Contains low-level functions.
std::error_code SetSchedulerPolicy(pid_t pid, int policy, int static_priority, int dynamic_priority) noexcept
A low-level, and error prone function to set policy.
Contains scheduler declarations.