perf(mining): one save, at most one restart per thread-count gesture
Every thread-count change on the Mining tab saved settings.json and, with a miner running, stopped and restarted it: xmrig re-inits its RandomX dataset and reconnects to the pool, seconds of lost hashing each time. A drag across the grid did this once per tile crossed (up to ~24), with a "Starting pool miner" toast each; every -/+ click or Enter did it again. The tab now hands each pick to the App, which puts the newest in settings at once and applies it when the input settles: on drag release, or 0.5 s after the last click, even if the Mining tab was left in the meantime. The header, RAM estimate and tile fill still follow the drag live. - Pool: the restart is decided on the mining-control thread, after every earlier start or stop has run. It never starts a miner the user stopped, is a no-op when xmrig already runs at that count, and is no longer silently skipped when the pick lands in another restart's stop window (which left xmrig on the old count). - Solo: one setgenerate per gesture. A pick made while one is in flight now waits for it instead of being dropped (another stale count). - Clicking the tile that is already selected does nothing; it used to save settings and restart the miner. - With idle thread scaling on, the grid no longer snaps back to the old count while a pick is on its way to the miner. A pool auto-balance restart keeps a count still queued. - Idle thread scaling changes the pool count through the same retarget. Its correction after a start compares with the count last requested, not the xmrig API's lagging report, so it comes about 1 s in instead of after the first API report (3-5 s). - A retarget whose pool config no longer validates shows the same error and stops the miner, as the old stop-then-start did. - While a benchmark runs a pick is saved, but the miner change is dropped: the benchmark owns the count until it ends. A crash within 0.5 s of a pick, or mid-drag, loses that pick; every clean exit saves it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -32,6 +32,7 @@
|
||||
#include "services/wallet_scan_governor.h"
|
||||
#include "services/chat_scan_policy.h"
|
||||
#include "services/note_consolidation.h"
|
||||
#include "services/mining_thread_commit.h"
|
||||
#include "services/network_refresh_service.h"
|
||||
#include "services/wallet_security_controller.h"
|
||||
#include "services/wallet_security_workflow.h"
|
||||
@@ -347,9 +348,23 @@ public:
|
||||
// Pool mining (xmrig)
|
||||
void startPoolMining(int threads);
|
||||
void stopPoolMining();
|
||||
// Change the thread count of the pool miner that is running (or queued to start). Never starts one.
|
||||
void retargetPoolMining(int threads);
|
||||
int getXmrigRequestedThreads() const {
|
||||
return xmrig_manager_ ? xmrig_manager_->getRequestedThreads() : 0;
|
||||
}
|
||||
// Thread count of the newest pool start/retarget posted and not stopped since (0 = none). Leads
|
||||
// getXmrigRequestedThreads(), which only changes once the mining-control thread runs that job.
|
||||
int poolThreadsTarget() const { return pool_threads_target_.load(std::memory_order_relaxed); }
|
||||
// A thread-count pick from the Mining tab (grid tile, -/+, Enter). The settings value changes at once;
|
||||
// the save and the miner change happen ONCE, when the input settles (drag released, or ~0.5 s after
|
||||
// the last click). Latest wins.
|
||||
void selectMiningThreads(int threads);
|
||||
void setMiningThreadDragActive(bool active) { mining_thread_drag_ = active; }
|
||||
// A pick has not reached the miner yet (the grid must not snap back to the old count meanwhile).
|
||||
bool miningThreadCommitPending() const {
|
||||
return mining_thread_commit_.pending() || mining_solo_threads_pending_ > 0;
|
||||
}
|
||||
// True while the pool miner process is live — used to refuse replacing the binary under it.
|
||||
bool isPoolMinerRunning() const {
|
||||
return xmrig_manager_ && xmrig_manager_->isRunning();
|
||||
@@ -1107,6 +1122,15 @@ private:
|
||||
bool mining_ctl_stop_ = false;
|
||||
void postMiningControl(std::function<void()> job); // enqueue a blocking xmrig op onto the FIFO thread
|
||||
void stopMiningControlThread(); // signal + join the control thread (shutdown)
|
||||
// Builds the pool config on the main thread and posts stop(if running)+start to the control thread.
|
||||
// retargetOnly: a thread-count change, decided on the control thread (never starts a miner).
|
||||
void postPoolMinerJob(int threads, bool retargetOnly);
|
||||
// Coalesced thread-count picks (main thread only; see services/mining_thread_commit.h).
|
||||
services::MiningThreadCommit mining_thread_commit_;
|
||||
bool mining_thread_drag_ = false; // the thread grid is mid-drag (set by the Mining tab)
|
||||
bool mining_threads_save_pending_ = false; // settings hold a picked count that is not on disk yet
|
||||
int mining_solo_threads_pending_ = 0; // settled pick waiting for an in-flight setgenerate
|
||||
void tickMiningThreadCommit(); // per frame, from update()
|
||||
// Auto-balance runtime state (pool mining, full-node only). The service fetches
|
||||
// pool hashrates off-thread; the RNG drives the weighted-random pick.
|
||||
util::PoolStatsService pool_stats_service_;
|
||||
@@ -1589,6 +1613,16 @@ private:
|
||||
// poll — drives the "connecting…" → "connected" feedback for pool mining (which has a connect delay).
|
||||
std::atomic<bool> pool_starting_{false};
|
||||
|
||||
// Thread count of the newest pool start/retarget job posted (0 = none / stopped). A hint for the main
|
||||
// thread: set when a job is posted, cleared by stopPoolMining(), by a start that fails and by a retarget
|
||||
// that finds no miner. The control thread re-checks the real state, so a stale value can only skip a
|
||||
// job the newest posted one already covers, or post a no-op one.
|
||||
std::atomic<int> pool_threads_target_{0};
|
||||
void clearPoolThreadsTarget(int mine) { // only if it still holds this job's value
|
||||
int expected = mine;
|
||||
pool_threads_target_.compare_exchange_strong(expected, 0, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
// Auto-shield guard (prevents concurrent auto-shield operations)
|
||||
std::atomic<bool> auto_shield_pending_{false};
|
||||
// v1.3.0+ daemons auto-shield coinbase themselves; probe z_autoshieldstatus once per connection and
|
||||
|
||||
Reference in New Issue
Block a user