ThreadSchedule 1.0.0
Modern C++ thread management library
Loading...
Searching...
No Matches
chaos.hpp
Go to the documentation of this file.
1#pragma once
2
12
13#include "scheduler_policy.hpp"
14#include "thread_registry.hpp"
15#include "thread_wrapper.hpp"
16#include "topology.hpp"
17#include <atomic>
18#include <chrono>
19#include <random>
20#include <thread>
21
22namespace threadschedule
23{
24
34{
36 std::chrono::milliseconds interval{250};
37
45
47 bool shuffle_affinity{true};
48};
49
85class ChaosController
86{
87 public:
88 template <typename Predicate>
89 ChaosController(ChaosConfig cfg, Predicate pred)
90 : config_(cfg), stop_(false), worker_([this, pred]() { run_loop(pred); })
91 {
92 }
93
94 ~ChaosController()
95 {
96 stop_ = true;
97 if (worker_.joinable())
98 worker_.join();
99 }
100
101 ChaosController(ChaosController const&) = delete;
102 auto operator=(ChaosController const&) -> ChaosController& = delete;
103
104 private:
105 template <typename Predicate>
106 void run_loop(Predicate pred)
107 {
108 std::mt19937 rng(std::random_device{}());
109 while (!stop_)
110 {
111 registry().apply(pred, [&](RegisteredThreadInfo const& info) {
112 auto blk = registry().get(info.tid);
113 (void)blk;
114 });
115
116 // Affinity shuffle using topology
117 if (config_.shuffle_affinity)
118 {
119 auto topo = read_topology();
120 size_t idx = 0;
121 registry().apply(pred, [&](RegisteredThreadInfo const& info) {
123 static_cast<int>(idx % (topo.numa_nodes > 0 ? topo.numa_nodes : 1)), static_cast<int>(idx));
124 (void)registry().set_affinity(info.tid, aff);
125 ++idx;
126 });
127 }
128
129 // Priority jitter around current policy
130 if (config_.priority_jitter != 0)
131 {
132 std::uniform_int_distribution<int> dist(-config_.priority_jitter, config_.priority_jitter);
133 registry().apply(pred, [&](RegisteredThreadInfo const& info) {
134 int delta = dist(rng);
135 // Use normal as baseline if we can't read current
136 ThreadPriority prio = ThreadPriority::normal();
137 (void)registry().set_priority(info.tid, ThreadPriority{prio.value() + delta});
138 });
139 }
140
141 std::this_thread::sleep_for(config_.interval);
142 }
143 }
144
145 ChaosConfig config_;
146 std::atomic<bool> stop_;
147 std::thread worker_;
148};
149
150} // namespace threadschedule
Manages a set of CPU indices to which a thread may be bound.
Value-semantic wrapper for a thread scheduling priority.
Plain value type holding runtime chaos-testing parameters.
Definition chaos.hpp:34
int priority_jitter
+/- range applied around the current thread priority each interval.
Definition chaos.hpp:44
std::chrono::milliseconds interval
Definition chaos.hpp:36
Snapshot of metadata for a single registered thread.
Hardware topology helpers (CPU count, NUMA nodes) and affinity builders.
auto affinity_for_node(int node_index, int thread_index, int threads_per_node=1) -> ThreadAffinity
Build a ThreadAffinity for the given NUMA node.
Definition topology.hpp:151
auto read_topology() -> CpuTopology
Discover basic topology. Linux: reads /sys for NUMA nodes. Windows: single node, sequential CPU indic...
Definition topology.hpp:53