ThreadSchedule 2.2.0
Modern C++ thread management library
Loading...
Searching...
No Matches
profiles.hpp
Go to the documentation of this file.
1#pragma once
2
12
13#include "concepts.hpp"
14#include "scheduler_policy.hpp"
15#include "thread_pool.hpp"
16#include "thread_registry.hpp"
17#include <optional>
18#include <string>
19#include <vector>
20
21namespace threadschedule
22{
23
24template <>
25struct is_thread_like<ThreadWrapper> : std::true_type
26{
27};
28
29template <>
30struct is_thread_like<ThreadWrapperView> : std::true_type
31{
32};
33
34#if __cplusplus >= 202002L || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)
35template <>
36struct is_thread_like<JThreadWrapper> : std::true_type
37{
38};
39
40template <>
41struct is_thread_like<JThreadWrapperView> : std::true_type
42{
43};
44#endif
45
58{
59 std::string name;
62 std::optional<ThreadAffinity> affinity;
63};
64
65namespace profiles
66{
71inline auto realtime() -> ThreadProfile
72{
73 return ThreadProfile{"realtime",
74#ifdef _WIN32
76#else
78#endif
79 ThreadPriority::highest(), std::nullopt};
80}
81
85inline auto low_latency() -> ThreadProfile
86{
87 return ThreadProfile{"low_latency", SchedulingPolicy::RR, ThreadPriority{5}, std::nullopt};
88}
89
93inline auto throughput() -> ThreadProfile
94{
95 return ThreadProfile{"throughput", SchedulingPolicy::BATCH, ThreadPriority::normal(), std::nullopt};
96}
97
101inline auto background() -> ThreadProfile
102{
103 return ThreadProfile{"background", SchedulingPolicy::IDLE, ThreadPriority::lowest(), std::nullopt};
104}
105} // namespace profiles
106
107namespace detail
108{
109
114template <typename T>
116{
117 bool ok = true;
118 if (!t.set_scheduling_policy(p.policy, p.priority).has_value())
119 ok = false;
120 if (p.affinity.has_value())
121 {
122 if (!t.set_affinity(*p.affinity).has_value())
123 ok = false;
124 }
125 if (ok)
126 return {};
127 return unexpected(std::make_error_code(std::errc::operation_not_permitted));
128}
129
133template <typename PoolType>
134inline auto apply_profile_to_pool(PoolType& pool, std::string const& name_prefix, ThreadProfile const& p)
136{
137 bool ok = true;
138 if (!pool.configure_threads(name_prefix, p.policy, p.priority).has_value())
139 ok = false;
140 if (p.affinity.has_value())
141 {
142 if (!pool.set_affinity(*p.affinity).has_value())
143 ok = false;
144 }
145 if (ok)
146 return {};
147 return unexpected(std::make_error_code(std::errc::operation_not_permitted));
148}
149
150} // namespace detail
151
160template <typename ThreadLike, std::enable_if_t<is_thread_like_v<ThreadLike>, int> = 0>
161inline auto apply_profile(ThreadLike& t, ThreadProfile const& p) -> expected<void, std::error_code>
162{
163 return detail::apply_profile_to(t, p);
164}
165
173
178{
179 return apply_profile(*t.control, p);
180}
181
186{
187 return detail::apply_profile_to_pool(pool, "pool", p);
188}
189
194{
195 return detail::apply_profile_to_pool(pool, "fast", p);
196}
197
202{
203 return detail::apply_profile_to_pool(pool, "hp", p);
204}
205
210{
211 bool ok = true;
212 if (!reg.set_scheduling_policy(tid, p.policy, p.priority).has_value())
213 ok = false;
214 if (p.affinity.has_value())
215 {
216 if (!reg.set_affinity(tid, *p.affinity).has_value())
217 ok = false;
218 }
219 if (ok)
220 return {};
221 return unexpected(std::make_error_code(std::errc::operation_not_permitted));
222}
223
239template <typename ThreadLike, std::enable_if_t<is_thread_like_v<ThreadLike>, int> = 0>
240inline auto apply_profile_detailed(ThreadLike& t, ThreadProfile const& p) -> std::vector<std::error_code>
241{
242 std::vector<std::error_code> results;
243 auto policy_result = t.set_scheduling_policy(p.policy, p.priority);
244 results.push_back(policy_result.has_value() ? std::error_code{} : policy_result.error());
245 if (p.affinity.has_value())
246 {
247 auto aff_result = t.set_affinity(*p.affinity);
248 results.push_back(aff_result.has_value() ? std::error_code{} : aff_result.error());
249 }
250 return results;
251}
252
257inline auto apply_profile_detailed(ThreadControlBlock& t, ThreadProfile const& p) -> std::vector<std::error_code>
258{
259 std::vector<std::error_code> results;
260 auto policy_result = t.set_scheduling_policy(p.policy, p.priority);
261 results.push_back(policy_result.has_value() ? std::error_code{} : policy_result.error());
262 if (p.affinity.has_value())
263 {
264 auto aff_result = t.set_affinity(*p.affinity);
265 results.push_back(aff_result.has_value() ? std::error_code{} : aff_result.error());
266 }
267 return results;
268}
269
270} // namespace threadschedule
High-performance thread pool optimized for high-frequency task submission.
Per-thread control handle for OS-level scheduling operations.
Value-semantic wrapper for a thread scheduling priority.
static constexpr auto normal() noexcept -> ThreadPriority
static constexpr auto highest() noexcept -> ThreadPriority
static constexpr auto lowest() noexcept -> ThreadPriority
Central registry of threads indexed by OS-level thread ID (Tid).
Non-owning view over an externally managed std::thread.
Owning wrapper around std::thread with RAII join-on-destroy semantics.
A result type that holds either a value of type T or an error of type E.
Definition expected.hpp:215
Exception thrown by expected::value() when the object is in the error state.
Definition expected.hpp:162
C++20 concepts, type traits, and SFINAE helpers for the threading library.
auto apply_profile_to(T &t, ThreadProfile const &p) -> expected< void, std::error_code >
Apply policy + optional affinity to any type exposing set_scheduling_policy() and set_affinity().
Definition profiles.hpp:115
auto apply_profile_to_pool(PoolType &pool, std::string const &name_prefix, ThreadProfile const &p) -> expected< void, std::error_code >
Apply configure_threads + optional affinity to any pool type.
Definition profiles.hpp:134
auto throughput() -> ThreadProfile
Throughput-oriented profile favoring batch scheduling.
Definition profiles.hpp:93
auto background() -> ThreadProfile
Background profile for very low priority work.
Definition profiles.hpp:101
auto low_latency() -> ThreadProfile
Low-latency interactive profile using RR scheduling.
Definition profiles.hpp:85
auto realtime() -> ThreadProfile
Highest priority profile. Uses FIFO on Linux (if permitted), falls back to OTHER on Windows.
Definition profiles.hpp:71
SchedulingPolicy
Enumeration of available thread scheduling policies.
@ OTHER
Standard round-robin time-sharing.
@ BATCH
For batch style execution.
@ IDLE
For very low priority background tasks.
auto apply_profile_detailed(ThreadLike &t, ThreadProfile const &p) -> std::vector< std::error_code >
Apply a profile and return per-step error codes.
Definition profiles.hpp:240
ThreadPoolBase< IndefiniteWait > ThreadPool
General-purpose thread pool with indefinite blocking wait.
auto apply_profile(ThreadLike &t, ThreadProfile const &p) -> expected< void, std::error_code >
Apply a profile to a thread wrapper or view.
Definition profiles.hpp:161
ThreadWrapperView JThreadWrapperView
ThreadPoolBase< PollingWait<> > FastThreadPool
Thread pool with 10 ms polling wait for lower wake-up latency.
ThreadWrapper JThreadWrapper
Owning wrapper around std::jthread with cooperative cancellation (C++20).
Scheduling policies, thread priority, and CPU affinity types.
Snapshot of metadata for a single registered thread.
Declarative profile bundling scheduling intent for a thread.
Definition profiles.hpp:58
std::optional< ThreadAffinity > affinity
Definition profiles.hpp:62
Type trait that identifies thread-like types.
Definition concepts.hpp:145
Thread pools: HighPerformancePool, ThreadPoolBase, LightweightPoolT, and GlobalPool.
Process-wide thread registry, control blocks, and composite registry.