3#include "../../result.hpp"
4#include "../../scheduling.hpp"
5#include "../../thread_affinity.hpp"
6#include "../../thread_config.hpp"
7#include "../scheduling/native.hpp"
8#include "../try_result.hpp"
10#include <condition_variable>
15#include <system_error>
26struct native_thread_access;
31[[nodiscard]]
constexpr auto
51 std::unique_lock<std::mutex> lock(mutex_);
52 ready_.wait(lock, [
this] {
return ready_to_start_; });
60 std::lock_guard<std::mutex> lock(mutex_);
62 ready_to_start_ =
true;
69 std::condition_variable ready_;
70 bool ready_to_start_{
false };
74[[nodiscard]]
constexpr auto
77 switch (config.intent())
97[[nodiscard]]
inline auto
100 std::vector<int> cpus;
101 cpus.reserve(affinity.cpus().size());
102 for (
auto cpu : affinity.cpus())
103 cpus.push_back(
static_cast<int>(cpu.value()));
105 if (native.get_cpus() != cpus)
106 throw std::system_error(std::make_error_code(std::errc::invalid_argument),
"thread affinity is not representable");
110[[nodiscard]]
inline auto
114 native.name = config.get_name();
115 if (config.get_scheduling())
116 native.scheduling =
to_native(*config.get_scheduling());
117 if (config.get_affinity())
118 native.affinity =
to_native(*config.get_affinity());
122[[nodiscard]]
inline auto
125 return !config.empty();
128[[nodiscard]]
inline auto
131 std::vector<cpu_id> cpus;
132 cpus.reserve(affinity.get_cpus().size());
133 for (
auto cpu : affinity.get_cpus())
134 cpus.emplace_back(cpu);
138namespace thread_lifecycle
140template <
typename ThreadLike>
144 if (!value.joinable())
145 return unexpected(std::make_error_code(std::errc::invalid_argument));
154template <
typename ThreadLike>
156join_or_throw(ThreadLike& value,
char const* operation)
158 if (!value.joinable())
159 throw std::system_error(std::make_error_code(std::errc::invalid_argument), operation);
163template <
typename ThreadLike>
167 if (!value.joinable())
168 return unexpected(std::make_error_code(std::errc::invalid_argument));
177template <
typename ThreadLike>
179detach_or_throw(ThreadLike& value,
char const* operation)
181 if (!value.joinable())
182 throw std::system_error(std::make_error_code(std::errc::invalid_argument), operation);
187namespace portable_thread_control
189template <
typename Control>
196template <
typename Control>
203template <
typename Control>
210[[nodiscard]]
inline auto
218[[nodiscard]]
inline auto
226template <
typename Control>
233[[nodiscard]]
inline auto
242#if defined(__cpp_lib_jthread) && __cpp_lib_jthread >= 201911L
243template <
typename Function,
typename Tuple>
245invoke_jthread_callable(Function& callable, Tuple&& arguments, std::stop_token token)
247 using function_type = std::remove_reference_t<Function>;
249 [&callable, &token](
auto&&... stored)
251 if constexpr (std::is_invocable_v<function_type, std::stop_token,
decltype(stored)...>)
252 std::invoke(std::move(callable), std::move(token), std::forward<
decltype(stored)>(stored)...);
254 std::invoke(std::move(callable), std::forward<
decltype(stored)>(stored)...);
256 std::forward<Tuple>(arguments));
Manages a set of CPU indices to which a thread may be bound.
Strongly-typed nice value in the POSIX range $[-20, 19]$.
constexpr auto value() const noexcept -> int
Return the wrapped nice value.
static auto create(int value) noexcept -> result< nice_value >
Construct a nice value without exceptions.
Immutable scheduling request passed to thread creation/configuration APIs.
Portable thread configuration bundle.
constexpr auto posix_nice(int nice_value) noexcept -> native_scheduling_config
constexpr auto interactive() noexcept -> native_scheduling_config
constexpr auto low_latency() noexcept -> native_scheduling_config
constexpr auto normal() noexcept -> native_scheduling_config
constexpr auto realtime_fifo(int priority=80) noexcept -> native_scheduling_config
constexpr auto realtime_rr(int priority=80) noexcept -> native_scheduling_config
constexpr auto background() noexcept -> native_scheduling_config
auto from_native(native_thread_affinity const &affinity) -> thread_affinity
constexpr auto to_native(shutdown_policy policy) noexcept -> shutdown_policy_backend
constexpr auto to_priority_level(int nice_value) noexcept -> priority_level
auto has_thread_configuration(thread_config const &config) noexcept -> bool
auto try_result(Function &&function) -> decltype(std::forward< Function >(function)())
priority_level
Portable non-realtime priority levels.
@ nice
Apply an explicit nice-level priority value.
@ low_latency
Favor low-latency execution where possible.
@ background
Prefer throughput and lower CPU contention over responsiveness.
@ realtime_fifo
Request POSIX FIFO realtime scheduling.
@ realtime_round_robin
Request POSIX round-robin realtime scheduling.
@ interactive
Favor responsiveness for user-facing work.
@ normal
Default scheduler behavior with balanced responsiveness.