89 template <
typename Predicate>
92 std::promise<Tid> worker_started;
93 auto worker_ready = worker_started.get_future();
95 worker_ =
ThreadWrapper([
this, pred, started = std::move(worker_started)]()
mutable {
100 worker_tid_ = worker_ready.get();
107 if (worker_.joinable())
116 if (!worker_.joinable() || worker_tid_ ==
Tid{})
125 if (!info.has_value())
126 return unexpected(std::make_error_code(std::errc::no_such_process));
131 template <
typename Predicate>
132 void run_loop(Predicate pred)
134 std::mt19937 rng(std::random_device{}());
137 registry().apply(pred, [&](RegisteredThreadInfo
const& info) {
138 auto blk =
registry().get(info.tid);
143 if (config_.shuffle_affinity)
147 registry().apply(pred, [&](RegisteredThreadInfo
const& info) {
149 static_cast<int>(idx % (topo.numa_nodes > 0 ? topo.numa_nodes : 1)),
static_cast<int>(idx));
150 (void)
registry().set_affinity(info.tid, aff);
156 if (config_.priority_jitter != 0)
158 std::uniform_int_distribution<int> dist(-config_.priority_jitter, config_.priority_jitter);
159 registry().apply(pred, [&](RegisteredThreadInfo
const& info) {
160 int delta = dist(rng);
164 if (sched_getparam(info.tid, &sp) == 0)
165 baseline = sp.sched_priority;
167 (void)
registry().set_priority(info.tid, ThreadPriority{baseline + delta});
171 std::this_thread::sleep_for(config_.interval);
176 std::atomic<bool> stop_;
177 ThreadWrapper worker_;
auto configure_thread(std::string const &name, SchedulingPolicy policy=SchedulingPolicy::OTHER, ThreadPriority priority=ThreadPriority::normal()) -> expected< void, std::error_code >
auto thread_info() const -> std::optional< ThreadInfo >
ChaosController(ChaosController const &)=delete
ChaosController(ChaosConfig cfg, Predicate pred)
auto operator=(ChaosController const &) -> ChaosController &=delete
Lightweight handle for querying and controlling a specific OS thread.
static auto get_thread_id() -> Tid
auto set_name(std::string const &name) const -> expected< void, std::error_code >
Value-semantic wrapper for a thread scheduling priority.
static constexpr auto normal() noexcept -> ThreadPriority
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.
Exception thrown by expected::value() when the object is in the error state.
auto configure_thread(ThreadLike &thread, std::string const &name, SchedulingPolicy policy, ThreadPriority priority) -> expected< void, std::error_code >
SchedulingPolicy
Enumeration of available thread scheduling policies.
@ OTHER
Standard round-robin time-sharing.
auto registry() -> ThreadRegistry &
Returns a reference to the process-wide ThreadRegistry.
auto read_topology() -> CpuTopology
Discover basic topology. Linux: reads /sys for NUMA nodes. Windows: single node, sequential CPU indic...
auto affinity_for_node(CpuTopology const &topo, int node_index, int thread_index, int threads_per_node=1) -> ThreadAffinity
Build a ThreadAffinity for the given NUMA node using a pre-read topology.
Scheduling policies, thread priority, and CPU affinity types.
Plain value type holding runtime chaos-testing parameters.
int priority_jitter
+/- range applied around the current thread priority each interval.
std::chrono::milliseconds interval
Process-wide thread registry, control blocks, and composite registry.
Enhanced thread wrappers: ThreadWrapper, JThreadWrapper, and non-owning views.
Hardware topology helpers (CPU count, NUMA nodes) and affinity builders.