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
29{
30 std::chrono::milliseconds interval{250};
31 int priority_jitter{0}; // +/- jitter applied around current priority
32 bool shuffle_affinity{true};
33};
34
35// RAII controller that periodically perturbs affinity/priority of registered threads matching a predicate
39class ChaosController
40{
41 public:
42 template <typename Predicate>
43 ChaosController(ChaosConfig cfg, Predicate pred)
44 : config_(cfg), stop_(false), worker_([this, pred]() { run_loop(pred); })
45 {
46 }
47
48 ~ChaosController()
49 {
50 stop_ = true;
51 if (worker_.joinable())
52 worker_.join();
53 }
54
55 ChaosController(ChaosController const&) = delete;
56 auto operator=(ChaosController const&) -> ChaosController& = delete;
57
58 private:
59 template <typename Predicate>
60 void run_loop(Predicate pred)
61 {
62 std::mt19937 rng(std::random_device{}());
63 while (!stop_)
64 {
65 registry().apply(pred, [&](RegisteredThreadInfo const& info) {
66 auto blk = registry().get(info.tid);
67 (void)blk;
68 });
69
70 // Affinity shuffle using topology
71 if (config_.shuffle_affinity)
72 {
73 auto topo = read_topology();
74 size_t idx = 0;
75 registry().apply(pred, [&](RegisteredThreadInfo const& info) {
77 static_cast<int>(idx % (topo.numa_nodes > 0 ? topo.numa_nodes : 1)), static_cast<int>(idx));
78 (void)registry().set_affinity(info.tid, aff);
79 ++idx;
80 });
81 }
82
83 // Priority jitter around current policy
84 if (config_.priority_jitter != 0)
85 {
86 std::uniform_int_distribution<int> dist(-config_.priority_jitter, config_.priority_jitter);
87 registry().apply(pred, [&](RegisteredThreadInfo const& info) {
88 int delta = dist(rng);
89 // Use normal as baseline if we can't read current
90 ThreadPriority prio = ThreadPriority::normal();
91 (void)registry().set_priority(info.tid, ThreadPriority{prio.value() + delta});
92 });
93 }
94
95 std::this_thread::sleep_for(config_.interval);
96 }
97 }
98
99 ChaosConfig config_;
100 std::atomic<bool> stop_;
101 std::thread worker_;
102};
103
104} // namespace threadschedule
Thread priority wrapper with validation.
Runtime chaos settings.
Definition chaos.hpp:29
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:137
auto read_topology() -> CpuTopology
Discover basic topology. Linux: reads /sys for NUMA nodes. Windows: single node, sequential CPU indic...
Definition topology.hpp:42