diff --git a/src/core/Config.cpp b/src/core/Config.cpp index f75e058a..b3564f92 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -43,12 +43,10 @@ static char affinity_tmp[20] = { 0 }; xmrig::Config::Config() : xmrig::CommonConfig(), m_aesMode(AES_AUTO), m_algoVariant(AV_AUTO), - m_doubleHash(false), m_dryRun(false), m_hugePages(true), m_safe(false), m_maxCpuUsage(75), - m_printTime(60), m_priority(-1) { } @@ -129,8 +127,21 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const doc.AddMember("retries", retries(), allocator); doc.AddMember("retry-pause", retryPause(), allocator); doc.AddMember("safe", m_safe, allocator); - doc.AddMember("threads", threadsCount(), allocator); - doc.AddMember("user-agent", userAgent() ? Value(StringRef(userAgent())).Move() : Value(kNullType).Move(), allocator); + + if (threadsMode() == Advanced) { + Value threads(kArrayType); + + for (const IThread *thread : m_threads.list) { + threads.PushBack(thread->toConfig(doc), doc.GetAllocator()); + } + + doc.AddMember("threads", threads, allocator); + } + else { + doc.AddMember("threads", threadsMode() == Automatic ? Value(kNullType) : Value(threadsCount()), allocator); + } + + doc.AddMember("user-agent", userAgent() ? Value(StringRef(userAgent())).Move() : Value(kNullType).Move(), allocator); # ifdef HAVE_SYSLOG_H doc.AddMember("syslog", isSyslog(), allocator); @@ -153,6 +164,7 @@ bool xmrig::Config::adjust() } if (!m_threads.cpu.empty()) { + m_threads.mode = Advanced; const bool softAES = (m_aesMode == AES_AUTO ? (Cpu::hasAES() ? AES_HW : AES_SOFT) : m_aesMode) == AES_SOFT; for (size_t i = 0; i < m_threads.cpu.size(); ++i) { @@ -162,16 +174,16 @@ bool xmrig::Config::adjust() return true; } - m_algoVariant = getAlgoVariant(); - if (m_algoVariant == AV_DOUBLE || m_algoVariant == AV_DOUBLE_SOFT) { - m_doubleHash = true; - } + m_algoVariant = getAlgoVariant(); + m_threads.mode = m_threads.count ? Simple : Automatic; + + const bool doubleHash = m_algoVariant == AV_DOUBLE || m_algoVariant == AV_DOUBLE_SOFT; if (!m_threads.count) { - m_threads.count = Cpu::optimalThreadsCount(m_algorithm, m_doubleHash, m_maxCpuUsage); + m_threads.count = Cpu::optimalThreadsCount(m_algorithm, doubleHash, m_maxCpuUsage); } else if (m_safe) { - const size_t count = Cpu::optimalThreadsCount(m_algorithm, m_doubleHash, m_maxCpuUsage); + const size_t count = Cpu::optimalThreadsCount(m_algorithm, doubleHash, m_maxCpuUsage); if (m_threads.count > count) { m_threads.count = count; } diff --git a/src/core/Config.h b/src/core/Config.h index 720557a7..13320a80 100644 --- a/src/core/Config.h +++ b/src/core/Config.h @@ -61,6 +61,13 @@ class IWatcherListener; class Config : public CommonConfig { public: + enum ThreadsMode { + Automatic, + Simple, + Advanced + }; + + Config(); ~Config(); @@ -70,14 +77,13 @@ public: inline AesMode aesMode() const { return m_aesMode; } inline AlgoVariant algoVariant() const { return m_algoVariant; } - inline bool isDoubleHash() const { return m_doubleHash; } inline bool isDryRun() const { return m_dryRun; } inline bool isHugePages() const { return m_hugePages; } inline const std::vector &threads() const { return m_threads.list; } - inline int printTime() const { return m_printTime; } inline int priority() const { return m_priority; } inline int threadsCount() const { return m_threads.list.size(); } inline int64_t affinity() const { return m_threads.mask; } + inline ThreadsMode threadsMode() const { return m_threads.mode; } static Config *load(int argc, char **argv, IWatcherListener *listener); @@ -99,23 +105,22 @@ private: struct Threads { - inline Threads() : mask(-1L), count(0) {} + inline Threads() : mask(-1L), count(0), mode(Automatic) {} int64_t mask; size_t count; std::vector cpu; std::vector list; + ThreadsMode mode; }; AesMode m_aesMode; AlgoVariant m_algoVariant; - bool m_doubleHash; bool m_dryRun; bool m_hugePages; bool m_safe; int m_maxCpuUsage; - int m_printTime; int m_priority; Threads m_threads; }; diff --git a/src/interfaces/IThread.h b/src/interfaces/IThread.h index f517ed18..2e9e3c39 100644 --- a/src/interfaces/IThread.h +++ b/src/interfaces/IThread.h @@ -53,12 +53,13 @@ public: virtual ~IThread() {} - virtual Algo algorithm() const = 0; - virtual int priority() const = 0; - virtual int64_t affinity() const = 0; - virtual Multiway multiway() const = 0; - virtual size_t index() const = 0; - virtual Type type() const = 0; + virtual Algo algorithm() const = 0; + virtual int priority() const = 0; + virtual int64_t affinity() const = 0; + virtual Multiway multiway() const = 0; + virtual rapidjson::Value toConfig(rapidjson::Document &doc) const = 0; + virtual size_t index() const = 0; + virtual Type type() const = 0; # ifndef XMRIG_NO_API virtual rapidjson::Value toAPI(rapidjson::Document &doc) const = 0; diff --git a/src/workers/CpuThread.cpp b/src/workers/CpuThread.cpp index 07fbbb64..ac733ef6 100644 --- a/src/workers/CpuThread.cpp +++ b/src/workers/CpuThread.cpp @@ -245,7 +245,9 @@ xmrig::CpuThread::Data xmrig::CpuThread::parse(const rapidjson::Value &object) #ifndef XMRIG_NO_API rapidjson::Value xmrig::CpuThread::toAPI(rapidjson::Document &doc) const { - rapidjson::Value obj(rapidjson::kObjectType); + using namespace rapidjson; + + Value obj(kObjectType); auto &allocator = doc.GetAllocator(); obj.AddMember("type", "cpu", allocator); @@ -259,3 +261,17 @@ rapidjson::Value xmrig::CpuThread::toAPI(rapidjson::Document &doc) const return obj; } #endif + + +rapidjson::Value xmrig::CpuThread::toConfig(rapidjson::Document &doc) const +{ + using namespace rapidjson; + + Value obj(kObjectType); + auto &allocator = doc.GetAllocator(); + + obj.AddMember("low_power_mode", multiway(), allocator); + obj.AddMember("affine_to_cpu", affinity() == -1L ? Value(kFalseType) : Value(affinity()), allocator); + + return obj; +} diff --git a/src/workers/CpuThread.h b/src/workers/CpuThread.h index e14c79f1..ba36cc87 100644 --- a/src/workers/CpuThread.h +++ b/src/workers/CpuThread.h @@ -77,10 +77,13 @@ public: inline size_t index() const override { return m_index; } inline Type type() const override { return CPU; } +protected: # ifndef XMRIG_NO_API rapidjson::Value toAPI(rapidjson::Document &doc) const override; # endif + rapidjson::Value toConfig(rapidjson::Document &doc) const override; + private: const Algo m_algorithm; const AlgoVariant m_av;