7#include "../../expected.hpp"
8#include "../callable/copyable_function.hpp"
9#include "../scheduling/native.hpp"
10#include "../thread/identity.hpp"
11#include "../thread_backend.hpp"
14# include "../unique_handle.hpp"
21#include <shared_mutex>
23#include <system_error>
30class thread_registry_backend;
31class registration_guard_backend;
76 std::shared_ptr<class thread_control_block>
control;
145 native_handle()
const
148 return handle_.get();
150 return pthread_handle_;
158 std::shared_lock<std::shared_mutex> lock(lifecycle_mutex_);
159 if (!target_is_active())
160 return inactive_error();
171 std::shared_lock<std::shared_mutex> lock(lifecycle_mutex_);
172 if (!target_is_active())
173 return inactive_error();
175 return detail::apply_priority(native_handle(), priority);
184 std::shared_lock<std::shared_mutex> lock(lifecycle_mutex_);
185 if (!target_is_active())
186 return inactive_error();
188 return detail::apply_nice_value(native_handle(),
nice_value);
190 return detail::apply_nice_value(tid_,
nice_value);
197 std::shared_lock<std::shared_mutex> lock(lifecycle_mutex_);
198 if (!target_is_active())
199 return inactive_error();
211 std::shared_lock<std::shared_mutex> lock(lifecycle_mutex_);
212 if (!target_is_active())
213 return inactive_error();
215 return detail::apply_scheduling_policy(native_handle(), policy, priority);
217 return detail::apply_scheduling_policy(tid_, policy, priority);
224 std::shared_lock<std::shared_mutex> lock(lifecycle_mutex_);
225 if (!target_is_active())
226 return inactive_error();
237 std::shared_lock<std::shared_mutex> lock(lifecycle_mutex_);
238 if (!target_is_active())
239 return inactive_error();
241 return detail::apply_name(native_handle(), name);
243 return detail::apply_name(tid_, name);
250 auto block = std::make_shared<thread_control_block>();
252 block->std_id_ = std::this_thread::get_id();
254 HANDLE realHandle =
nullptr;
255 if (DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &realHandle,
256 THREAD_SET_INFORMATION | THREAD_QUERY_INFORMATION, FALSE, 0)
258 throw std::system_error(detail::last_win32_error(),
"DuplicateHandle");
259 block->handle_.reset(realHandle);
261 block->pthread_handle_ = pthread_self();
264 current_thread_controls().add(block);
269 struct thread_exit_controls
272 add(std::shared_ptr<thread_control_block>
const& control)
275 std::remove_if(controls_.begin(), controls_.end(), [](
auto const& item) { return item.expired(); }),
277 controls_.push_back(control);
280 ~thread_exit_controls()
282 for (
auto const& item : controls_)
283 if (auto control = item.lock())
284 control->deactivate();
287 std::vector<std::weak_ptr<thread_control_block>> controls_;
290 [[nodiscard]]
static auto
291 current_thread_controls() -> thread_exit_controls&
293 thread_local thread_exit_controls controls;
297 [[nodiscard]]
static auto
298 inactive_error() -> unexpected<std::error_code>
300 return unexpected(std::make_error_code(std::errc::no_such_process));
304 target_is_active() const noexcept ->
bool
309 return static_cast<bool>(handle_);
314 if (!start_time_.has_value())
321 deactivate() noexcept
323 std::unique_lock<std::shared_mutex> lock(lifecycle_mutex_);
329 mutable std::shared_mutex lifecycle_mutex_;
330 bool active_{
true };
332 std::thread::id std_id_;
334 detail::unique_handle handle_;
336 pthread_t pthread_handle_{};
337 std::optional<std::uint64_t> start_time_;
Manages a set of CPU indices to which a thread may be bound.
Value-semantic wrapper for a thread scheduling priority.
Per-thread control handle for OS-level scheduling operations.
auto tid() const noexcept -> native_thread_id
auto set_name(std::string const &name) const -> expected< void, std::error_code >
thread_control_block(thread_control_block const &)=delete
thread_control_block()=default
auto set_scheduling_policy(native_scheduling_policy policy, native_thread_priority priority) const -> expected< void, std::error_code >
thread_control_block(thread_control_block &&)=delete
auto set_affinity(native_thread_affinity const &affinity) const -> expected< void, std::error_code >
auto operator=(thread_control_block &&) -> thread_control_block &=delete
auto configure(native_scheduling_config const &config) const -> expected< void, std::error_code >
auto std_id() const noexcept -> std::thread::id
auto set_nice_value(int nice_value) const -> expected< void, std::error_code >
auto set_priority(native_thread_priority priority) const -> expected< void, std::error_code >
static auto create_for_current_thread() -> std::shared_ptr< thread_control_block >
auto operator=(thread_control_block const &) -> thread_control_block &=delete
auto get_nice_value() const -> expected< int, std::error_code >
~thread_control_block()=default
static auto get_thread_id() -> native_thread_id
Central registry of threads indexed by OS-level thread ID (native_thread_id).
Strongly-typed nice value in the POSIX range $[-20, 19]$.
Owning thread wrapper with result-based lifecycle/configuration API.
constexpr auto posix_nice(int nice_value) noexcept -> native_scheduling_config
Aggregates multiple thread_registry_backend instances into a single queryable view.
auto read_effective_nice(NativeHandle handle, native_thread_id tid) -> expected< int, std::error_code >
auto read_thread_start_time(native_thread_id id) noexcept -> std::optional< std::uint64_t >
native_scheduling_policy
Enumeration of available thread scheduling policies.
detail::copyable_function< void(registered_thread_info_backend const &)> registry_callback
auto apply_affinity_checked(NativeHandle handle, native_thread_affinity const &affinity) -> expected< void, std::error_code >
auto native_thread_is_alive(native_thread_identity const &identity) noexcept -> bool
auto apply_scheduling_config(NativeHandle handle, native_thread_id tid, native_scheduling_config const &config) -> expected< void, std::error_code >
std::function< Signature > copyable_function
Snapshot of metadata for a single registered thread.
std::shared_ptr< class thread_control_block > control