#pragma once #include namespace dragonx { namespace ui { struct ThreadBenchmark { enum class Phase { Idle, Starting, WarmingUp, Measuring, Advancing, CoolingDown, Done }; struct Result { int threads = 0; double hashrate = 0.0; }; static constexpr float MIN_WARMUP_SECS = 90.0f; static constexpr float MAX_WARMUP_SECS = 300.0f; static constexpr float MEASURE_SECS = 30.0f; static constexpr float COOLDOWN_SECS = 5.0f; static constexpr float STABILITY_WINDOW_SECS = 10.0f; static constexpr float STABILITY_THRESHOLD = 0.05f; static constexpr int STABLE_WINDOWS_NEEDED = 3; Phase phase = Phase::Idle; std::vector candidates; int current_index = 0; std::vector results; float phase_timer = 0.0f; double prev_window_avg = 0.0; double window_sum = 0.0; int window_samples = 0; float window_timer = 0.0f; int consecutive_stable = 0; double measure_sum = 0.0; int measure_samples = 0; int optimal_threads = 0; double optimal_hashrate = 0.0; bool was_pool_running = false; int prev_threads = 0; float total_warmup_secs = 0.0f; void reset(); void buildCandidates(int maxThreads); float avgWarmupSecs() const; float perTestSecs() const; float totalEstimatedSecs() const; float elapsedSecs() const; float progress() const; void resetStabilityTracking(); bool active() const; }; struct ThreadBenchmarkUpdate { bool stopPoolMining = false; bool startPoolMining = false; int startThreads = 0; bool saveOptimalThreads = false; int optimalThreads = 0; }; ThreadBenchmarkUpdate AdvanceThreadBenchmark(ThreadBenchmark& benchmark, float deltaSeconds, double poolHashrate10s); } // namespace ui } // namespace dragonx