From d7f42d54ad68b735db03210c1940a8a133aa93b5 Mon Sep 17 00:00:00 2001 From: XMRig Date: Mon, 10 Jun 2019 20:46:29 +0700 Subject: [PATCH 01/48] Added initial support for per pool algo option (mining code is broken). --- src/Summary.cpp | 6 +- src/base/kernel/config/BaseConfig.cpp | 23 +- src/base/kernel/config/BaseConfig.h | 14 +- src/base/kernel/interfaces/IConfig.h | 1 - src/base/net/stratum/Client.cpp | 33 +-- src/base/net/stratum/Job.cpp | 38 ---- src/base/net/stratum/Job.h | 10 +- src/base/net/stratum/Pool.cpp | 203 +---------------- src/base/net/stratum/Pool.h | 10 +- src/base/net/stratum/Pools.cpp | 21 +- src/base/net/stratum/Pools.h | 7 +- src/core/config/Config.cpp | 56 +++-- src/crypto/common/Algorithm.cpp | 304 +++++++------------------- src/crypto/common/Algorithm.h | 84 ++++--- src/net/Network.cpp | 3 +- src/net/strategies/DonateStrategy.cpp | 6 +- src/workers/MultiWorker.cpp | 3 +- src/workers/Workers.cpp | 2 +- 18 files changed, 187 insertions(+), 637 deletions(-) diff --git a/src/Summary.cpp b/src/Summary.cpp index 2b28f98d..d780d64f 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -90,10 +90,9 @@ static void print_threads(xmrig::Config *config) snprintf(buf, sizeof buf, ", affinity=0x%" PRIX64, config->affinity()); } - xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%d") WHITE_BOLD(", %s, av=%d, %sdonate=%d%%") WHITE_BOLD("%s"), + xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%d") WHITE_BOLD(", av=%d, %sdonate=%d%%") WHITE_BOLD("%s"), "THREADS", config->threadsCount(), - config->algorithm().shortName(), config->algoVariant(), config->pools().donateLevel() == 0 ? RED_BOLD_S : "", config->pools().donateLevel(), @@ -101,10 +100,9 @@ static void print_threads(xmrig::Config *config) ); } else { - xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%d") WHITE_BOLD(", %s, %sdonate=%d%%"), + xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%d") WHITE_BOLD(", %sdonate=%d%%"), "THREADS", config->threadsCount(), - config->algorithm().shortName(), config->pools().donateLevel() == 0 ? RED_BOLD_S : "", config->pools().donateLevel() ); diff --git a/src/base/kernel/config/BaseConfig.cpp b/src/base/kernel/config/BaseConfig.cpp index af2418aa..489849a3 100644 --- a/src/base/kernel/config/BaseConfig.cpp +++ b/src/base/kernel/config/BaseConfig.cpp @@ -60,14 +60,7 @@ #include "version.h" -xmrig::BaseConfig::BaseConfig() : - m_algorithm(CRYPTONIGHT, VARIANT_AUTO), - m_autoSave(true), - m_background(false), - m_dryRun(false), - m_syslog(false), - m_upgrade(false), - m_watch(true) +xmrig::BaseConfig::BaseConfig() { } @@ -160,19 +153,7 @@ bool xmrig::BaseConfig::read(const IJsonReader &reader, const char *fileName) m_http.load(chain.getObject("http")); # endif - m_algorithm.parseAlgorithm(reader.getString("algo", "cn")); - - m_pools.load(reader.getArray("pools")); - m_pools.setDonateLevel(reader.getInt("donate-level", kDefaultDonateLevel)); - m_pools.setProxyDonate(reader.getInt("donate-over-proxy", Pools::PROXY_DONATE_AUTO)); - m_pools.setRetries(reader.getInt("retries")); - m_pools.setRetryPause(reader.getInt("retry-pause")); - - if (!m_algorithm.isValid()) { - return false; - } - - m_pools.adjust(m_algorithm); + m_pools.load(reader); return m_pools.active() > 0; } diff --git a/src/base/kernel/config/BaseConfig.h b/src/base/kernel/config/BaseConfig.h index f0c52536..48d7c2cf 100644 --- a/src/base/kernel/config/BaseConfig.h +++ b/src/base/kernel/config/BaseConfig.h @@ -59,7 +59,6 @@ public: inline uint32_t printTime() const { return m_printTime; } inline bool isWatch() const override { return m_watch && !m_fileName.isNull(); } - inline const Algorithm &algorithm() const override { return m_algorithm; } inline const String &fileName() const override { return m_fileName; } inline void setFileName(const char *fileName) override { m_fileName = fileName; } @@ -69,13 +68,12 @@ public: void printVersions(); protected: - Algorithm m_algorithm; - bool m_autoSave; - bool m_background; - bool m_dryRun; - bool m_syslog; - bool m_upgrade; - bool m_watch; + bool m_autoSave = true; + bool m_background = false; + bool m_dryRun = false; + bool m_syslog = false; + bool m_upgrade = false; + bool m_watch = true; Http m_http; Pools m_pools; String m_apiId; diff --git a/src/base/kernel/interfaces/IConfig.h b/src/base/kernel/interfaces/IConfig.h index 3d0407e6..c8189ba5 100644 --- a/src/base/kernel/interfaces/IConfig.h +++ b/src/base/kernel/interfaces/IConfig.h @@ -144,7 +144,6 @@ public: virtual bool isWatch() const = 0; virtual bool read(const IJsonReader &reader, const char *fileName) = 0; virtual bool save() = 0; - virtual const Algorithm &algorithm() const = 0; virtual const String &fileName() const = 0; virtual void getJSON(rapidjson::Document &doc) const = 0; virtual void setFileName(const char *fileName) = 0; diff --git a/src/base/net/stratum/Client.cpp b/src/base/net/stratum/Client.cpp index 1d448ddf..05e53c78 100644 --- a/src/base/net/stratum/Client.cpp +++ b/src/base/net/stratum/Client.cpp @@ -333,17 +333,6 @@ bool xmrig::Client::parseJob(const rapidjson::Value ¶ms, int *code) job.setAlgorithm(params["algo"].GetString()); } - if (params.HasMember("variant")) { - const rapidjson::Value &variant = params["variant"]; - - if (variant.IsInt()) { - job.setVariant(variant.GetInt()); - } - else if (variant.IsString()){ - job.setVariant(variant.GetString()); - } - } - if (params.HasMember("height")) { const rapidjson::Value &variant = params["height"]; @@ -438,7 +427,7 @@ bool xmrig::Client::verifyAlgorithm(const Algorithm &algorithm) const } # endif - if (m_pool.isCompatible(algorithm)) { + if (m_pool.algorithm() == algorithm) { // FIXME return true; } @@ -590,18 +579,18 @@ void xmrig::Client::login() params.AddMember("rigid", m_pool.rigId().toJSON(), allocator); } -# ifdef XMRIG_PROXY_PROJECT - if (m_pool.algorithm().variant() != xmrig::VARIANT_AUTO) -# endif - { - Value algo(kArrayType); +//# ifdef XMRIG_PROXY_PROJECT FIXME +// if (m_pool.algorithm().variant() != xmrig::VARIANT_AUTO) +//# endif +// { +// Value algo(kArrayType); - for (const auto &a : m_pool.algorithms()) { - algo.PushBack(StringRef(a.shortName()), allocator); - } +// for (const auto &a : m_pool.algorithms()) { +// algo.PushBack(StringRef(a.shortName()), allocator); +// } - params.AddMember("algo", algo, allocator); - } +// params.AddMember("algo", algo, allocator); +// } m_listener->onLogin(this, doc, params); diff --git a/src/base/net/stratum/Job.cpp b/src/base/net/stratum/Job.cpp index 1f1cd413..293d0f46 100644 --- a/src/base/net/stratum/Job.cpp +++ b/src/base/net/stratum/Job.cpp @@ -34,10 +34,8 @@ xmrig::Job::Job() : - m_autoVariant(false), m_nicehash(false), m_poolId(-2), - m_threadId(-1), m_size(0), m_diff(0), m_height(0), @@ -49,10 +47,8 @@ xmrig::Job::Job() : xmrig::Job::Job(int poolId, bool nicehash, const Algorithm &algorithm, const String &clientId) : m_algorithm(algorithm), - m_autoVariant(algorithm.variant() == VARIANT_AUTO), m_nicehash(nicehash), m_poolId(poolId), - m_threadId(-1), m_size(0), m_clientId(clientId), m_diff(0), @@ -98,10 +94,6 @@ bool xmrig::Job::setBlob(const char *blob) m_nicehash = true; } - if (m_autoVariant) { - m_algorithm.setVariant(variant()); - } - # ifdef XMRIG_PROXY_PROJECT memset(m_rawBlob, 0, sizeof(m_rawBlob)); memcpy(m_rawBlob, blob, m_size * 2); @@ -153,16 +145,6 @@ bool xmrig::Job::setTarget(const char *target) } -void xmrig::Job::setAlgorithm(const char *algo) -{ - m_algorithm.parseAlgorithm(algo); - - if (m_algorithm.variant() == xmrig::VARIANT_AUTO) { - m_algorithm.setVariant(variant()); - } -} - - void xmrig::Job::setDiff(uint64_t diff) { m_diff = diff; @@ -173,23 +155,3 @@ void xmrig::Job::setDiff(uint64_t diff) m_rawTarget[16] = '\0'; # endif } - - -xmrig::Variant xmrig::Job::variant() const -{ - switch (m_algorithm.algo()) { - case CRYPTONIGHT: - return (m_blob[0] >= 10) ? VARIANT_4 : ((m_blob[0] >= 8) ? VARIANT_2 : VARIANT_1); - - case CRYPTONIGHT_LITE: - return VARIANT_1; - - case CRYPTONIGHT_HEAVY: - return VARIANT_0; - - default: - break; - } - - return m_algorithm.variant(); -} diff --git a/src/base/net/stratum/Job.h b/src/base/net/stratum/Job.h index 5052040a..518a337e 100644 --- a/src/base/net/stratum/Job.h +++ b/src/base/net/stratum/Job.h @@ -53,7 +53,6 @@ public: bool isEqual(const Job &other) const; bool setBlob(const char *blob); bool setTarget(const char *target); - void setAlgorithm(const char *algo); void setDiff(uint64_t diff); inline bool isNicehash() const { return m_nicehash; } @@ -65,7 +64,6 @@ public: inline const uint32_t *nonce() const { return reinterpret_cast(m_blob + 39); } inline const uint8_t *blob() const { return m_blob; } inline int poolId() const { return m_poolId; } - inline int threadId() const { return m_threadId; } inline size_t size() const { return m_size; } inline uint32_t *nonce() { return reinterpret_cast(m_blob + 39); } inline uint64_t diff() const { return m_diff; } @@ -73,12 +71,10 @@ public: inline uint64_t target() const { return m_target; } inline uint8_t fixedByte() const { return *(m_blob + 42); } inline void reset() { m_size = 0; m_diff = 0; } + inline void setAlgorithm(const char *algo) { m_algorithm = algo; } inline void setClientId(const String &id) { m_clientId = id; } inline void setHeight(uint64_t height) { m_height = height; } inline void setPoolId(int poolId) { m_poolId = poolId; } - inline void setThreadId(int threadId) { m_threadId = threadId; } - inline void setVariant(const char *variant) { m_algorithm.parseVariant(variant); } - inline void setVariant(int variant) { m_algorithm.parseVariant(variant); } # ifdef XMRIG_PROXY_PROJECT inline char *rawBlob() { return m_rawBlob; } @@ -93,13 +89,9 @@ public: inline bool operator!=(const Job &other) const { return !isEqual(other); } private: - Variant variant() const; - Algorithm m_algorithm; - bool m_autoVariant; bool m_nicehash; int m_poolId; - int m_threadId; size_t m_size; String m_clientId; String m_id; diff --git a/src/base/net/stratum/Pool.cpp b/src/base/net/stratum/Pool.cpp index f441ba63..bb3fab72 100644 --- a/src/base/net/stratum/Pool.cpp +++ b/src/base/net/stratum/Pool.cpp @@ -47,6 +47,7 @@ namespace xmrig { +static const char *kAlgo = "algo"; static const char *kDaemon = "daemon"; static const char *kDaemonPollInterval = "daemon-poll-interval"; static const char *kEnabled = "enabled"; @@ -58,7 +59,6 @@ static const char *kRigId = "rig-id"; static const char *kTls = "tls"; static const char *kUrl = "url"; static const char *kUser = "user"; -static const char *kVariant = "variant"; const String Pool::kDefaultPassword = "x"; const String Pool::kDefaultUser = "x"; @@ -119,6 +119,7 @@ xmrig::Pool::Pool(const rapidjson::Value &object) : m_rigId = Json::getString(object, kRigId); m_fingerprint = Json::getString(object, kFingerprint); m_pollInterval = Json::getUint64(object, kDaemonPollInterval, kDefaultPollInterval); + m_algorithm = Json::getString(object, kAlgo); m_flags.set(FLAG_ENABLED, Json::getBool(object, kEnabled, true)); m_flags.set(FLAG_NICEHASH, Json::getBool(object, kNicehash)); @@ -132,15 +133,6 @@ xmrig::Pool::Pool(const rapidjson::Value &object) : else if (keepalive.IsBool()) { setKeepAlive(keepalive.GetBool()); } - - const rapidjson::Value &variant = Json::getValue(object, kVariant); - if (variant.IsString()) { - algorithm().parseVariant(variant.GetString()); - } - else if (variant.IsInt()) { - algorithm().parseVariant(variant.GetInt()); - } - } @@ -166,28 +158,6 @@ xmrig::Pool::Pool(const char *host, uint16_t port, const char *user, const char } -bool xmrig::Pool::isCompatible(const Algorithm &algorithm) const -{ - if (m_algorithms.empty()) { - return true; - } - - for (const auto &a : m_algorithms) { - if (algorithm == a) { - return true; - } - } - -# ifdef XMRIG_PROXY_PROJECT - if (m_algorithm.algo() == xmrig::CRYPTONIGHT && algorithm.algo() == xmrig::CRYPTONIGHT) { - return m_algorithm.variant() == xmrig::VARIANT_RWZ || m_algorithm.variant() == xmrig::VARIANT_ZLS; - } -# endif - - return false; -} - - bool xmrig::Pool::isEnabled() const { # ifndef XMRIG_FEATURE_TLS @@ -289,6 +259,7 @@ rapidjson::Value xmrig::Pool::toJSON(rapidjson::Document &doc) const Value obj(kObjectType); + obj.AddMember(StringRef(kAlgo), StringRef(m_algorithm.shortName()), allocator); obj.AddMember(StringRef(kUrl), m_url.toJSON(), allocator); obj.AddMember(StringRef(kUser), m_user.toJSON(), allocator); obj.AddMember(StringRef(kPass), m_password.toJSON(), allocator); @@ -305,22 +276,6 @@ rapidjson::Value xmrig::Pool::toJSON(rapidjson::Document &doc) const obj.AddMember(StringRef(kKeepalive), m_keepAlive, allocator); } - switch (m_algorithm.variant()) { - case VARIANT_AUTO: - case VARIANT_0: - case VARIANT_1: - obj.AddMember(StringRef(kVariant), m_algorithm.variant(), allocator); - break; - - case VARIANT_2: - obj.AddMember(StringRef(kVariant), 2, allocator); - break; - - default: - obj.AddMember(StringRef(kVariant), StringRef(m_algorithm.variantName()), allocator); - break; - } - obj.AddMember(StringRef(kEnabled), m_flags.test(FLAG_ENABLED), allocator); obj.AddMember(StringRef(kTls), isTLS(), allocator); obj.AddMember(StringRef(kFingerprint), m_fingerprint.toJSON(), allocator); @@ -331,29 +286,6 @@ rapidjson::Value xmrig::Pool::toJSON(rapidjson::Document &doc) const } -void xmrig::Pool::adjust(const Algorithm &algorithm) -{ - if (!isValid()) { - return; - } - - if (!m_algorithm.isValid()) { - m_algorithm.setAlgo(algorithm.algo()); - adjustVariant(algorithm.variant()); - } - - rebuild(); -} - - -void xmrig::Pool::setAlgo(const xmrig::Algorithm &algorithm) -{ - m_algorithm = algorithm; - - rebuild(); -} - - #ifdef APP_DEBUG void xmrig::Pool::print() const { @@ -391,132 +323,3 @@ bool xmrig::Pool::parseIPv6(const char *addr) return true; } - - -void xmrig::Pool::addVariant(xmrig::Variant variant) -{ - const xmrig::Algorithm algorithm(m_algorithm.algo(), variant); - if (!algorithm.isValid() || m_algorithm == algorithm) { - return; - } - - m_algorithms.push_back(algorithm); -} - - -void xmrig::Pool::adjustVariant(const xmrig::Variant variantHint) -{ -# ifndef XMRIG_PROXY_PROJECT - using namespace xmrig; - - if (m_host.contains(".nicehash.com")) { - m_flags.set(FLAG_NICEHASH, true); - m_keepAlive = false; - bool valid = true; - - switch (m_port) { - case 3355: - case 33355: - valid = m_algorithm.algo() == CRYPTONIGHT && m_host.contains("cryptonight."); - m_algorithm.setVariant(VARIANT_0); - break; - - case 3363: - case 33363: - valid = m_algorithm.algo() == CRYPTONIGHT && m_host.contains("cryptonightv7."); - m_algorithm.setVariant(VARIANT_1); - break; - - case 3364: - valid = m_algorithm.algo() == CRYPTONIGHT_HEAVY && m_host.contains("cryptonightheavy."); - m_algorithm.setVariant(VARIANT_0); - break; - - case 3367: - case 33367: - valid = m_algorithm.algo() == CRYPTONIGHT && m_host.contains("cryptonightv8."); - m_algorithm.setVariant(VARIANT_2); - break; - - default: - break; - } - - if (!valid) { - m_algorithm.setAlgo(INVALID_ALGO); - } - - m_flags.set(FLAG_TLS, m_port > 33000); - return; - } - - if (m_host.contains(".minergate.com")) { - m_keepAlive = false; - bool valid = true; - m_algorithm.setVariant(VARIANT_1); - - if (m_host.contains("xmr.pool.")) { - valid = m_algorithm.algo() == CRYPTONIGHT; - m_algorithm.setVariant(m_port == 45700 ? VARIANT_AUTO : VARIANT_0); - } - else if (m_host.contains("aeon.pool.") && m_port == 45690) { - valid = m_algorithm.algo() == CRYPTONIGHT_LITE; - m_algorithm.setVariant(VARIANT_1); - } - - if (!valid) { - m_algorithm.setAlgo(INVALID_ALGO); - } - - return; - } - - if (variantHint != VARIANT_AUTO) { - m_algorithm.setVariant(variantHint); - return; - } - - if (m_algorithm.variant() != VARIANT_AUTO) { - return; - } - - if (m_algorithm.algo() == CRYPTONIGHT_HEAVY) { - m_algorithm.setVariant(VARIANT_0); - } - else if (m_algorithm.algo() == CRYPTONIGHT_LITE) { - m_algorithm.setVariant(VARIANT_1); - } -# endif -} - - -void xmrig::Pool::rebuild() -{ - m_algorithms.clear(); - - if (!m_algorithm.isValid()) { - return; - } - - m_algorithms.push_back(m_algorithm); - -# ifndef XMRIG_PROXY_PROJECT - addVariant(VARIANT_4); - addVariant(VARIANT_WOW); - addVariant(VARIANT_2); - addVariant(VARIANT_1); - addVariant(VARIANT_0); - addVariant(VARIANT_HALF); - addVariant(VARIANT_XTL); - addVariant(VARIANT_TUBE); - addVariant(VARIANT_MSR); - addVariant(VARIANT_XHV); - addVariant(VARIANT_XAO); - addVariant(VARIANT_RTO); - addVariant(VARIANT_GPU); - addVariant(VARIANT_RWZ); - addVariant(VARIANT_ZLS); - addVariant(VARIANT_DOUBLE); - addVariant(VARIANT_AUTO); -# endif -} diff --git a/src/base/net/stratum/Pool.h b/src/base/net/stratum/Pool.h index 5348271a..36c3ed1b 100644 --- a/src/base/net/stratum/Pool.h +++ b/src/base/net/stratum/Pool.h @@ -69,13 +69,11 @@ public: bool tls = false ); - inline Algorithm &algorithm() { return m_algorithm; } inline bool isDaemon() const { return m_flags.test(FLAG_DAEMON); } inline bool isNicehash() const { return m_flags.test(FLAG_NICEHASH); } inline bool isTLS() const { return m_flags.test(FLAG_TLS); } inline bool isValid() const { return !m_host.isNull() && m_port > 0; } inline const Algorithm &algorithm() const { return m_algorithm; } - inline const Algorithms &algorithms() const { return m_algorithms; } inline const String &fingerprint() const { return m_fingerprint; } inline const String &host() const { return m_host; } inline const String &password() const { return !m_password.isNull() ? m_password : kDefaultPassword; } @@ -85,6 +83,7 @@ public: inline int keepAlive() const { return m_keepAlive; } inline uint16_t port() const { return m_port; } inline uint64_t pollInterval() const { return m_pollInterval; } + inline void setAlgo(const Algorithm &algorithm) { m_algorithm = algorithm; } inline void setPassword(const String &password) { m_password = password; } inline void setRigId(const String &rigId) { m_rigId = rigId; } inline void setUser(const String &user) { m_user = user; } @@ -92,13 +91,10 @@ public: inline bool operator!=(const Pool &other) const { return !isEqual(other); } inline bool operator==(const Pool &other) const { return isEqual(other); } - bool isCompatible(const Algorithm &algorithm) const; bool isEnabled() const; bool isEqual(const Pool &other) const; bool parse(const char *url); rapidjson::Value toJSON(rapidjson::Document &doc) const; - void adjust(const Algorithm &algorithm); - void setAlgo(const Algorithm &algorithm); # ifdef APP_DEBUG void print() const; @@ -109,12 +105,8 @@ private: inline void setKeepAlive(int keepAlive) { m_keepAlive = keepAlive >= 0 ? keepAlive : 0; } bool parseIPv6(const char *addr); - void addVariant(Variant variant); - void adjustVariant(const Variant variantHint); - void rebuild(); Algorithm m_algorithm; - Algorithms m_algorithms; int m_keepAlive; std::bitset m_flags; String m_fingerprint; diff --git a/src/base/net/stratum/Pools.cpp b/src/base/net/stratum/Pools.cpp index 638ba5ea..985e5d4e 100644 --- a/src/base/net/stratum/Pools.cpp +++ b/src/base/net/stratum/Pools.cpp @@ -24,6 +24,7 @@ #include "base/io/log/Log.h" +#include "base/kernel/interfaces/IJsonReader.h" #include "base/net/stratum/Pools.h" #include "base/net/stratum/strategies/FailoverStrategy.h" #include "base/net/stratum/strategies/SinglePoolStrategy.h" @@ -103,18 +104,11 @@ size_t xmrig::Pools::active() const } -void xmrig::Pools::adjust(const Algorithm &algorithm) -{ - for (Pool &pool : m_data) { - pool.adjust(algorithm); - } -} - - -void xmrig::Pools::load(const rapidjson::Value &pools) +void xmrig::Pools::load(const IJsonReader &reader) { m_data.clear(); + const rapidjson::Value &pools = reader.getArray("pools"); if (!pools.IsArray()) { return; } @@ -129,6 +123,11 @@ void xmrig::Pools::load(const rapidjson::Value &pools) m_data.push_back(std::move(pool)); } } + + setDonateLevel(reader.getInt("donate-level", kDefaultDonateLevel)); + setProxyDonate(reader.getInt("donate-over-proxy", PROXY_DONATE_AUTO)); + setRetries(reader.getInt("retries")); + setRetryPause(reader.getInt("retry-pause")); } @@ -136,11 +135,11 @@ void xmrig::Pools::print() const { size_t i = 1; for (const Pool &pool : m_data) { - Log::print(GREEN_BOLD(" * ") WHITE_BOLD("POOL #%-7zu") CSI "1;%dm%s" CLEAR " variant " WHITE_BOLD("%s"), + Log::print(GREEN_BOLD(" * ") WHITE_BOLD("POOL #%-7zu") CSI "1;%dm%s" CLEAR " algo " WHITE_BOLD("%s"), i, (pool.isEnabled() ? (pool.isTLS() ? 32 : 36) : 31), pool.url().data(), - pool.algorithm().variantName() + pool.algorithm().shortName() ); i++; diff --git a/src/base/net/stratum/Pools.h b/src/base/net/stratum/Pools.h index 6a63f166..70e17225 100644 --- a/src/base/net/stratum/Pools.h +++ b/src/base/net/stratum/Pools.h @@ -35,6 +35,7 @@ namespace xmrig { +class IJsonReader; class IStrategy; class IStrategyListener; @@ -63,15 +64,15 @@ public: IStrategy *createStrategy(IStrategyListener *listener) const; rapidjson::Value toJSON(rapidjson::Document &doc) const; size_t active() const; - void adjust(const Algorithm &algorithm); - void load(const rapidjson::Value &pools); + void load(const IJsonReader &reader); void print() const; + +private: void setDonateLevel(int level); void setProxyDonate(int value); void setRetries(int retries); void setRetryPause(int retryPause); -private: int m_donateLevel; int m_retries; int m_retryPause; diff --git a/src/core/config/Config.cpp b/src/core/config/Config.cpp index c1430e4d..fbb12ffa 100644 --- a/src/core/config/Config.cpp +++ b/src/core/config/Config.cpp @@ -87,8 +87,6 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const auto &allocator = doc.GetAllocator(); - doc.AddMember("algo", StringRef(algorithm().name()), allocator); - Value api(kObjectType); api.AddMember("id", m_apiId.toJSON(), allocator); api.AddMember("worker-id", m_apiWorkerId.toJSON(), allocator); @@ -146,37 +144,37 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const bool xmrig::Config::finalize() { - if (!m_threads.cpu.empty()) { - m_threads.mode = Advanced; - const bool softAES = (m_aesMode == AES_AUTO ? (Cpu::info()->hasAES() ? AES_HW : AES_SOFT) : m_aesMode) == AES_SOFT; +// if (!m_threads.cpu.empty()) { // FIXME +// m_threads.mode = Advanced; +// const bool softAES = (m_aesMode == AES_AUTO ? (Cpu::info()->hasAES() ? AES_HW : AES_SOFT) : m_aesMode) == AES_SOFT; - for (size_t i = 0; i < m_threads.cpu.size(); ++i) { - m_threads.list.push_back(CpuThread::createFromData(i, m_algorithm.algo(), m_threads.cpu[i], m_priority, softAES)); - } +// for (size_t i = 0; i < m_threads.cpu.size(); ++i) { +//// m_threads.list.push_back(CpuThread::createFromData(i, m_algorithm.algo(), m_threads.cpu[i], m_priority, softAES)); +// } - return true; - } +// return true; +// } - const AlgoVariant av = getAlgoVariant(); - m_threads.mode = m_threads.count ? Simple : Automatic; +// const AlgoVariant av = getAlgoVariant(); +// m_threads.mode = m_threads.count ? Simple : Automatic; - const size_t size = CpuThread::multiway(av) * cn_select_memory(m_algorithm.algo()) / 1024; +//// const size_t size = CpuThread::multiway(av) * cn_select_memory(m_algorithm.algo()) / 1024; - if (!m_threads.count) { - m_threads.count = Cpu::info()->optimalThreadsCount(size, m_maxCpuUsage); - } - else if (m_safe) { - const size_t count = Cpu::info()->optimalThreadsCount(size, m_maxCpuUsage); - if (m_threads.count > count) { - m_threads.count = count; - } - } +// if (!m_threads.count) { +// m_threads.count = Cpu::info()->optimalThreadsCount(size, m_maxCpuUsage); +// } +// else if (m_safe) { +// const size_t count = Cpu::info()->optimalThreadsCount(size, m_maxCpuUsage); +// if (m_threads.count > count) { +// m_threads.count = count; +// } +// } - for (size_t i = 0; i < m_threads.count; ++i) { - m_threads.list.push_back(CpuThread::createFromAV(i, m_algorithm.algo(), av, m_threads.mask, m_priority, m_assembly)); - } +// for (size_t i = 0; i < m_threads.count; ++i) { +// m_threads.list.push_back(CpuThread::createFromAV(i, m_algorithm.algo(), av, m_threads.mask, m_priority, m_assembly)); +// } - m_shouldSave = m_threads.mode == Automatic; +// m_shouldSave = m_threads.mode == Automatic; return true; } @@ -245,9 +243,9 @@ void xmrig::Config::setThreads(const rapidjson::Value &threads) xmrig::AlgoVariant xmrig::Config::getAlgoVariant() const { # ifdef XMRIG_ALGO_CN_LITE - if (m_algorithm.algo() == xmrig::CRYPTONIGHT_LITE) { - return getAlgoVariantLite(); - } +// if (m_algorithm.algo() == xmrig::CRYPTONIGHT_LITE) { // FIXME +// return getAlgoVariantLite(); +// } # endif if (m_algoVariant <= AV_AUTO || m_algoVariant >= AV_MAX) { diff --git a/src/crypto/common/Algorithm.cpp b/src/crypto/common/Algorithm.cpp index 29ca9ecf..f85b0a6f 100644 --- a/src/crypto/common/Algorithm.cpp +++ b/src/crypto/common/Algorithm.cpp @@ -44,254 +44,96 @@ #endif -struct AlgoData +namespace xmrig { + + +struct AlgoName { const char *name; const char *shortName; - xmrig::Algo algo; - xmrig::Variant variant; + const Algorithm::Id id; }; -static AlgoData const algorithms[] = { - { "cryptonight", "cn", xmrig::CRYPTONIGHT, xmrig::VARIANT_AUTO }, - { "cryptonight/0", "cn/0", xmrig::CRYPTONIGHT, xmrig::VARIANT_0 }, - { "cryptonight/1", "cn/1", xmrig::CRYPTONIGHT, xmrig::VARIANT_1 }, - { "cryptonight/xtl", "cn/xtl", xmrig::CRYPTONIGHT, xmrig::VARIANT_XTL }, - { "cryptonight/msr", "cn/msr", xmrig::CRYPTONIGHT, xmrig::VARIANT_MSR }, - { "cryptonight/xao", "cn/xao", xmrig::CRYPTONIGHT, xmrig::VARIANT_XAO }, - { "cryptonight/rto", "cn/rto", xmrig::CRYPTONIGHT, xmrig::VARIANT_RTO }, - { "cryptonight/2", "cn/2", xmrig::CRYPTONIGHT, xmrig::VARIANT_2 }, - { "cryptonight/half", "cn/half", xmrig::CRYPTONIGHT, xmrig::VARIANT_HALF }, - { "cryptonight/xtlv9", "cn/xtlv9", xmrig::CRYPTONIGHT, xmrig::VARIANT_HALF }, - { "cryptonight/wow", "cn/wow", xmrig::CRYPTONIGHT, xmrig::VARIANT_WOW }, - { "cryptonight/r", "cn/r", xmrig::CRYPTONIGHT, xmrig::VARIANT_4 }, - { "cryptonight/rwz", "cn/rwz", xmrig::CRYPTONIGHT, xmrig::VARIANT_RWZ }, - { "cryptonight/zls", "cn/zls", xmrig::CRYPTONIGHT, xmrig::VARIANT_ZLS }, - { "cryptonight/double", "cn/double", xmrig::CRYPTONIGHT, xmrig::VARIANT_DOUBLE }, - -# ifdef XMRIG_ALGO_CN_LITE - { "cryptonight-lite", "cn-lite", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_AUTO }, - { "cryptonight-light", "cn-light", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_AUTO }, - { "cryptonight-lite/0", "cn-lite/0", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_0 }, - { "cryptonight-lite/1", "cn-lite/1", xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_1 }, -# endif - -# ifdef XMRIG_ALGO_CN_HEAVY - { "cryptonight-heavy", "cn-heavy", xmrig::CRYPTONIGHT_HEAVY, xmrig::VARIANT_AUTO }, - { "cryptonight-heavy/0", "cn-heavy/0", xmrig::CRYPTONIGHT_HEAVY, xmrig::VARIANT_0 }, - { "cryptonight-heavy/xhv", "cn-heavy/xhv", xmrig::CRYPTONIGHT_HEAVY, xmrig::VARIANT_XHV }, - { "cryptonight-heavy/tube", "cn-heavy/tube", xmrig::CRYPTONIGHT_HEAVY, xmrig::VARIANT_TUBE }, -# endif - -# ifdef XMRIG_ALGO_CN_PICO - { "cryptonight-pico/trtl", "cn-pico/trtl", xmrig::CRYPTONIGHT_PICO, xmrig::VARIANT_TRTL }, - { "cryptonight-pico", "cn-pico", xmrig::CRYPTONIGHT_PICO, xmrig::VARIANT_TRTL }, - { "cryptonight-turtle", "cn-trtl", xmrig::CRYPTONIGHT_PICO, xmrig::VARIANT_TRTL }, - { "cryptonight-ultralite", "cn-ultralite", xmrig::CRYPTONIGHT_PICO, xmrig::VARIANT_TRTL }, - { "cryptonight_turtle", "cn_turtle", xmrig::CRYPTONIGHT_PICO, xmrig::VARIANT_TRTL }, -# endif - +static AlgoName const algorithm_names[] = { + { "cryptonight/0", "cn/0", Algorithm::CN_0 }, + { "cryptonight", "cn", Algorithm::CN_0 }, + { "cryptonight/1", "cn/1", Algorithm::CN_1 }, + { "cryptonight-monerov7", nullptr, Algorithm::CN_1 }, + { "cryptonight_v7", nullptr, Algorithm::CN_1 }, + { "cryptonight/2", "cn/2", Algorithm::CN_2 }, + { "cryptonight-monerov8", nullptr, Algorithm::CN_2 }, + { "cryptonight_v8", nullptr, Algorithm::CN_2 }, + { "cryptonight/r", "cn/r", Algorithm::CN_R }, + { "cryptonight_r", nullptr, Algorithm::CN_R }, + { "cryptonight/wow", "cn/wow", Algorithm::CN_WOW }, + { "cryptonight/fast", "cn/fast", Algorithm::CN_FAST }, + { "cryptonight/msr", "cn/msr", Algorithm::CN_FAST }, + { "cryptonight/half", "cn/half", Algorithm::CN_HALF }, + { "cryptonight/xao", "cn/xao", Algorithm::CN_XAO }, + { "cryptonight_alloy", nullptr, Algorithm::CN_XAO }, + { "cryptonight/rto", "cn/rto", Algorithm::CN_RTO }, + { "cryptonight/rwz", "cn/rwz", Algorithm::CN_RWZ }, + { "cryptonight/zls", "cn/zls", Algorithm::CN_ZLS }, + { "cryptonight/double", "cn/double", Algorithm::CN_ZLS }, # ifdef XMRIG_ALGO_CN_GPU - { "cryptonight/gpu", "cn/gpu", xmrig::CRYPTONIGHT, xmrig::VARIANT_GPU }, + { "cryptonight/gpu", "cn/gpu", Algorithm::CN_GPU }, + { "cryptonight_gpu", nullptr, Algorithm::CN_GPU }, +# endif +# ifdef XMRIG_ALGO_CN_LITE + { "cryptonight-lite/0", "cn-lite/0", Algorithm::CN_LITE_0 }, + { "cryptonight-lite/1", "cn-lite/1", Algorithm::CN_LITE_1 }, + { "cryptonight-lite", "cn-lite", Algorithm::CN_LITE_1 }, + { "cryptonight-light", "cn-light", Algorithm::CN_LITE_1 }, + { "cryptonight_lite", nullptr, Algorithm::CN_LITE_1 }, + { "cryptonight-aeonv7", nullptr, Algorithm::CN_LITE_1 }, + { "cryptonight_lite_v7", nullptr, Algorithm::CN_LITE_1 }, +# endif +# ifdef XMRIG_ALGO_CN_HEAVY + { "cryptonight-heavy/0", "cn-heavy/0", Algorithm::CN_HEAVY_0 }, + { "cryptonight-heavy", "cn-heavy", Algorithm::CN_HEAVY_0 }, + { "cryptonight_heavy", nullptr, Algorithm::CN_HEAVY_0 }, + { "cryptonight-heavy/xhv", "cn-heavy/xhv", Algorithm::CN_HEAVY_XHV }, + { "cryptonight_haven", nullptr, Algorithm::CN_HEAVY_XHV }, + { "cryptonight-heavy/tube", "cn-heavy/tube", Algorithm::CN_HEAVY_TUBE }, + { "cryptonight-bittube2", nullptr, Algorithm::CN_HEAVY_TUBE }, +# endif +# ifdef XMRIG_ALGO_CN_PICO + { "cryptonight-pico", "cn-pico", Algorithm::CN_PICO }, + { "cryptonight-pico/trtl", "cn-pico/trtl", Algorithm::CN_PICO }, + { "cryptonight-turtle", "cn-trtl", Algorithm::CN_PICO }, + { "cryptonight-ultralite", "cn-ultralite", Algorithm::CN_PICO }, + { "cryptonight_turtle", "cn_turtle", Algorithm::CN_PICO }, # endif }; -#ifdef XMRIG_PROXY_PROJECT -static AlgoData const xmrStakAlgorithms[] = { - { "cryptonight-monerov7", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_1 }, - { "cryptonight_v7", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_1 }, - { "cryptonight-monerov8", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_2 }, - { "cryptonight_v8", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_2 }, - { "cryptonight_v7_stellite", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_XTL }, - { "cryptonight_lite", nullptr, xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_0 }, - { "cryptonight-aeonv7", nullptr, xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_1 }, - { "cryptonight_lite_v7", nullptr, xmrig::CRYPTONIGHT_LITE, xmrig::VARIANT_1 }, - { "cryptonight_heavy", nullptr, xmrig::CRYPTONIGHT_HEAVY, xmrig::VARIANT_0 }, - { "cryptonight_haven", nullptr, xmrig::CRYPTONIGHT_HEAVY, xmrig::VARIANT_XHV }, - { "cryptonight_masari", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_MSR }, - { "cryptonight_masari", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_MSR }, - { "cryptonight-bittube2", nullptr, xmrig::CRYPTONIGHT_HEAVY, xmrig::VARIANT_TUBE }, // bittube-miner - { "cryptonight_alloy", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_XAO }, // xmr-stak-alloy - { "cryptonight_turtle", nullptr, xmrig::CRYPTONIGHT_PICO, xmrig::VARIANT_TRTL }, - { "cryptonight_gpu", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_GPU }, - { "cryptonight_r", nullptr, xmrig::CRYPTONIGHT, xmrig::VARIANT_4 }, -}; -#endif - - -static const char *variants[] = { - "0", - "1", - "tube", - "xtl", - "msr", - "xhv", - "xao", - "rto", - "2", - "half", - "trtl", - "gpu", - "wow", - "r", - "rwz", - "zls", - "double" -}; - - -static_assert(xmrig::VARIANT_MAX == ARRAY_SIZE(variants), "variants size mismatch"); - - -bool xmrig::Algorithm::isValid() const -{ - if (m_algo == INVALID_ALGO) { - return false; - } - - for (size_t i = 0; i < ARRAY_SIZE(algorithms); i++) { - if (algorithms[i].algo == m_algo && algorithms[i].variant == m_variant) { - return true; - } - } - - return false; -} - - -const char *xmrig::Algorithm::variantName() const -{ - if (m_variant == VARIANT_AUTO) { - return "auto"; - } - - return variants[m_variant]; -} - - -void xmrig::Algorithm::parseAlgorithm(const char *algo) -{ - m_algo = INVALID_ALGO; - m_variant = VARIANT_AUTO; - -// assert(algo != nullptr); - if (algo == nullptr || strlen(algo) < 1) { - return; - } - - if (*algo == '!') { - m_flags |= Forced; - - return parseAlgorithm(algo + 1); - } - - for (size_t i = 0; i < ARRAY_SIZE(algorithms); i++) { - if ((strcasecmp(algo, algorithms[i].name) == 0) || (strcasecmp(algo, algorithms[i].shortName) == 0)) { - m_algo = algorithms[i].algo; - m_variant = algorithms[i].variant; - break; - } - } - - if (m_algo == INVALID_ALGO) { - assert(false); - } -} - - -void xmrig::Algorithm::parseVariant(const char *variant) -{ - m_variant = VARIANT_AUTO; - - if (variant == nullptr || strlen(variant) < 1) { - return; - } - - if (*variant == '!') { - m_flags |= Forced; - - return parseVariant(variant + 1); - } - - for (size_t i = 0; i < ARRAY_SIZE(variants); i++) { - if (strcasecmp(variant, variants[i]) == 0) { - m_variant = static_cast(i); - return; - } - } - - if (strcasecmp(variant, "xtlv9") == 0) { - m_variant = VARIANT_HALF; - } -} - - -void xmrig::Algorithm::parseVariant(int variant) -{ - assert(variant >= -1 && variant <= 2); - - switch (variant) { - case -1: - case 0: - case 1: - m_variant = static_cast(variant); - break; - - case 2: - m_variant = VARIANT_2; - break; - - default: - break; - } -} - - -void xmrig::Algorithm::setAlgo(Algo algo) -{ - m_algo = algo; - - if (m_algo == CRYPTONIGHT_PICO && m_variant == VARIANT_AUTO) { - m_variant = xmrig::VARIANT_TRTL; - } -} - - -#ifdef XMRIG_PROXY_PROJECT -void xmrig::Algorithm::parseXmrStakAlgorithm(const char *algo) -{ - m_algo = INVALID_ALGO; - m_variant = VARIANT_AUTO; - - assert(algo != nullptr); - if (algo == nullptr) { - return; - } - - for (size_t i = 0; i < ARRAY_SIZE(xmrStakAlgorithms); i++) { - if (strcasecmp(algo, xmrStakAlgorithms[i].name) == 0) { - m_algo = xmrStakAlgorithms[i].algo; - m_variant = xmrStakAlgorithms[i].variant; - break; - } - } - - if (m_algo == INVALID_ALGO) { - assert(false); - } -} -#endif +} /* namespace xmrig */ const char *xmrig::Algorithm::name(bool shortName) const { - for (size_t i = 0; i < ARRAY_SIZE(algorithms); i++) { - if (algorithms[i].algo == m_algo && algorithms[i].variant == m_variant) { - return shortName ? algorithms[i].shortName : algorithms[i].name; + for (size_t i = 0; i < ARRAY_SIZE(algorithm_names); i++) { + if (algorithm_names[i].id == m_id) { + return shortName ? algorithm_names[i].shortName : algorithm_names[i].name; } } return "invalid"; } + + +xmrig::Algorithm::Id xmrig::Algorithm::parse(const char *name) +{ + if (name == nullptr || strlen(name) < 1) { + return INVALID; + } + + for (size_t i = 0; i < ARRAY_SIZE(algorithm_names); i++) { + if ((strcasecmp(name, algorithm_names[i].name) == 0) || (algorithm_names[i].shortName != nullptr && strcasecmp(name, algorithm_names[i].shortName) == 0)) { + return algorithm_names[i].id; + } + } + + return INVALID; +} diff --git a/src/crypto/common/Algorithm.h b/src/crypto/common/Algorithm.h index 664552aa..c70e0caa 100644 --- a/src/crypto/common/Algorithm.h +++ b/src/crypto/common/Algorithm.h @@ -30,68 +30,63 @@ #include -#include "common/xmrig.h" - - namespace xmrig { class Algorithm { public: - enum Flags { - None = 0, - Forced = 1 + enum Id : int { + INVALID = -1, + CN_0, // "cn/0" Original CryptoNight + CN_1, // "cn/1" CryptoNight variant 1 also known as Monero7 and CryptoNightV7 + CN_2, // "cn/2" CryptoNight variant 2 + CN_R, // "cn/r" CryptoNightR (Monero's variant 4) + CN_WOW, // "cn/wow" CryptoNightR (Wownero) + CN_FAST, // "cn/fast" CryptoNight variant 1 with half iterations + CN_HALF, // "cn/half" CryptoNight variant 2 with half iterations (Masari/Stellite) + CN_XAO, // "cn/xao" Modified CryptoNight variant 0 (Alloy only) + CN_RTO, // "cn/rto" Modified CryptoNight variant 1 (Arto only) + CN_RWZ, // "cn/rwz" CryptoNight variant 2 with 3/4 iterations and reversed shuffle operation (Graft) + CN_ZLS, // "cn/zls" CryptoNight variant 2 with 3/4 iterations (Zelerius) + CN_DOUBLE, // "cn/double" CryptoNight variant 2 with double iterations (X-CASH) +# ifdef XMRIG_ALGO_CN_GPU + CN_GPU, // "cn/gpu" CryptoNight-GPU (Ryo) +# endif +# ifdef XMRIG_ALGO_CN_LITE + CN_LITE_0, // "cn-lite/0" CryptoNight-Lite (1 MB) variant 0 + CN_LITE_1, // "cn-lite/1" CryptoNight-Lite (1 MB) variant 1 +# endif +# ifdef XMRIG_ALGO_CN_HEAVY + CN_HEAVY_0, // "cn-heavy/0" CryptoNight-Heavy (4 MB) + CN_HEAVY_TUBE, // "cn-heavy/tube" Modified CryptoNight-Heavy (TUBE only) + CN_HEAVY_XHV, // "cn-heavy/xhv" Modified CryptoNight-Heavy (Haven Protocol only) +# endif +# ifdef XMRIG_ALGO_CN_PICO + CN_PICO, // "cn-pico" CryptoNight Turtle (TRTL) +# endif + MAX }; - inline Algorithm() : - m_algo(INVALID_ALGO), - m_flags(0), - m_variant(VARIANT_AUTO) - {} + inline Algorithm() {} + inline Algorithm(const char *algo) : m_id(parse(algo)) {} + inline Algorithm(Id id) : m_id(id) {} - inline Algorithm(Algo algo, Variant variant) : - m_flags(0), - m_variant(variant) - { - setAlgo(algo); - } - - inline Algorithm(const char *algo) : - m_flags(0) - { - parseAlgorithm(algo); - } - - inline Algo algo() const { return m_algo; } - inline bool isEqual(const Algorithm &other) const { return m_algo == other.m_algo && m_variant == other.m_variant; } - inline bool isForced() const { return m_flags & Forced; } + inline bool isEqual(const Algorithm &other) const { return m_id == other.m_id; } inline const char *name() const { return name(false); } inline const char *shortName() const { return name(true); } - inline int flags() const { return m_flags; } - inline Variant variant() const { return m_variant; } - inline void setVariant(Variant variant) { m_variant = variant; } + inline Id id() const { return m_id; } + inline bool isValid() const { return m_id != INVALID; } inline bool operator!=(const Algorithm &other) const { return !isEqual(other); } inline bool operator==(const Algorithm &other) const { return isEqual(other); } - bool isValid() const; - const char *variantName() const; - void parseAlgorithm(const char *algo); - void parseVariant(const char *variant); - void parseVariant(int variant); - void setAlgo(Algo algo); - -# ifdef XMRIG_PROXY_PROJECT - void parseXmrStakAlgorithm(const char *algo); -# endif + static Id parse(const char *name); private: const char *name(bool shortName) const; - Algo m_algo; - int m_flags; - Variant m_variant; + Id m_id = INVALID; }; @@ -100,4 +95,5 @@ typedef std::vector Algorithms; } /* namespace xmrig */ -#endif /* __ALGORITHM_H__ */ + +#endif /* XMRIG_ALGORITHM_H */ diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 1ab42236..16669f52 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -231,8 +231,7 @@ void xmrig::Network::getConnection(rapidjson::Value &reply, rapidjson::Document using namespace rapidjson; auto &allocator = doc.GetAllocator(); - const Algorithm &algo = m_strategy->client()->job().algorithm(); - reply.AddMember("algo", StringRef((algo.isValid() ? algo : m_controller->config()->algorithm()).shortName()), allocator); + reply.AddMember("algo", StringRef(m_strategy->client()->job().algorithm().shortName()), allocator); Value connection(kObjectType); connection.AddMember("pool", StringRef(m_state.pool), allocator); diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp index fb958a4c..3d913087 100644 --- a/src/net/strategies/DonateStrategy.cpp +++ b/src/net/strategies/DonateStrategy.cpp @@ -79,9 +79,9 @@ xmrig::DonateStrategy::DonateStrategy(Controller *controller, IStrategyListener # endif m_pools.push_back(Pool(kDonateHost, 3333, m_userId, nullptr, 0, true)); - for (Pool &pool : m_pools) { - pool.adjust(Algorithm(controller->config()->algorithm().algo(), VARIANT_AUTO)); - } +// for (Pool &pool : m_pools) { +// pool.adjust(Algorithm()); // FIXME +// } if (m_pools.size() > 1) { m_strategy = new FailoverStrategy(m_pools, 1, 2, this, true); diff --git a/src/workers/MultiWorker.cpp b/src/workers/MultiWorker.cpp index e4a5fb0c..30c43000 100644 --- a/src/workers/MultiWorker.cpp +++ b/src/workers/MultiWorker.cpp @@ -126,7 +126,8 @@ void MultiWorker::start() storeStats(); } - m_thread->fn(m_state.job.algorithm().variant())(m_state.blob, m_state.job.size(), m_hash, m_ctx, m_state.job.height()); + // FIXME +// m_thread->fn(m_state.job.algorithm().variant())(m_state.blob, m_state.job.size(), m_hash, m_ctx, m_state.job.height()); for (size_t i = 0; i < N; ++i) { if (*reinterpret_cast(m_hash + (i * 32) + 24) < m_state.job.target()) { diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index b95d8b85..62cbd1cf 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -176,7 +176,7 @@ void Workers::start(xmrig::Controller *controller) m_controller = controller; const std::vector &threads = controller->config()->threads(); - m_status.algo = controller->config()->algorithm().algo(); +// m_status.algo = controller->config()->algorithm().algo(); // FIXME m_status.threads = threads.size(); for (const xmrig::IThread *thread : threads) { From 1f0e3e501cece285744e700d0da95ede52a37fc5 Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 13 Jun 2019 22:08:52 +0700 Subject: [PATCH 02/48] Implemented new style algorithm definitions (except ARM), removed Algo and Variant enums. --- CMakeLists.txt | 6 +- cmake/asm.cmake | 5 +- src/Mem.cpp | 13 +- src/Mem.h | 4 +- src/Mem_win.cpp | 1 - src/Summary.cpp | 4 +- src/common/cpu/BasicCpuInfo.cpp | 2 +- src/common/xmrig.h | 33 -- src/core/config/Config.cpp | 57 +- src/core/config/Config.h | 2 +- src/crypto/cn/CnAlgo.h | 207 +++++++ src/crypto/cn/CnHash.cpp | 269 +++++++++ src/crypto/cn/CnHash.h | 63 ++ src/crypto/cn/CryptoNight.h | 4 +- src/crypto/cn/CryptoNight_constants.h | 251 -------- src/crypto/cn/CryptoNight_monero.h | 36 +- src/crypto/cn/CryptoNight_test.h | 15 - src/crypto/cn/CryptoNight_x86.h | 784 ++++++++++++++----------- src/crypto/cn/gpu/cn_gpu_avx.cpp | 6 +- src/crypto/cn/gpu/cn_gpu_ssse3.cpp | 6 +- src/crypto/cn/r/variant4_random_math.h | 19 +- src/crypto/common/Algorithm.cpp | 81 ++- src/crypto/common/Algorithm.h | 15 +- src/interfaces/IThread.h | 4 +- src/workers/CpuThread.cpp | 544 +---------------- src/workers/CpuThread.h | 20 +- src/workers/MultiWorker.cpp | 88 +-- src/workers/MultiWorker.h | 17 +- src/workers/Workers.cpp | 21 +- src/workers/Workers.h | 5 +- 30 files changed, 1223 insertions(+), 1359 deletions(-) create mode 100644 src/crypto/cn/CnAlgo.h create mode 100644 src/crypto/cn/CnHash.cpp create mode 100644 src/crypto/cn/CnHash.h delete mode 100644 src/crypto/cn/CryptoNight_constants.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 30625d28..9c70a673 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,7 +59,8 @@ set(HEADERS_CRYPTO src/crypto/cn/c_groestl.h src/crypto/cn/c_jh.h src/crypto/cn/c_skein.h - src/crypto/cn/CryptoNight_constants.h + src/crypto/cn/CnAlgo.h + src/crypto/cn/CnHash.h src/crypto/cn/CryptoNight_monero.h src/crypto/cn/CryptoNight_test.h src/crypto/cn/CryptoNight.h @@ -102,10 +103,11 @@ set(SOURCES ) set(SOURCES_CRYPTO - src/crypto/cn/c_groestl.c src/crypto/cn/c_blake256.c + src/crypto/cn/c_groestl.c src/crypto/cn/c_jh.c src/crypto/cn/c_skein.c + src/crypto/cn/CnHash.cpp src/crypto/common/Algorithm.cpp ) diff --git a/cmake/asm.cmake b/cmake/asm.cmake index 25cccead..d3010e51 100644 --- a/cmake/asm.cmake +++ b/cmake/asm.cmake @@ -38,8 +38,11 @@ if (WITH_ASM AND NOT XMRIG_ARM AND CMAKE_SIZEOF_VOID_P EQUAL 8) add_library(${XMRIG_ASM_LIBRARY} STATIC ${XMRIG_ASM_FILES}) set(XMRIG_ASM_SOURCES src/crypto/cn/Asm.h src/crypto/cn/Asm.cpp src/crypto/cn/r/CryptonightR_gen.cpp) set_property(TARGET ${XMRIG_ASM_LIBRARY} PROPERTY LINKER_LANGUAGE C) + + add_definitions(/DXMRIG_FEATURE_ASM) else() set(XMRIG_ASM_SOURCES "") set(XMRIG_ASM_LIBRARY "") - add_definitions(/DXMRIG_NO_ASM) + + remove_definitions(/DXMRIG_FEATURE_ASM) endif() diff --git a/src/Mem.cpp b/src/Mem.cpp index b9e0fbf9..574c5ff2 100644 --- a/src/Mem.cpp +++ b/src/Mem.cpp @@ -27,7 +27,6 @@ #include -#include "crypto/cn/CryptoNight_constants.h" #include "crypto/cn/CryptoNight.h" #include "crypto/common/portable/mm_malloc.h" #include "crypto/common/VirtualMemory.h" @@ -38,12 +37,14 @@ bool Mem::m_enabled = true; int Mem::m_flags = 0; -MemInfo Mem::create(cryptonight_ctx **ctx, xmrig::Algo algorithm, size_t count) +MemInfo Mem::create(cryptonight_ctx **ctx, const xmrig::Algorithm &algorithm, size_t count) { using namespace xmrig; + constexpr CnAlgo props; + MemInfo info; - info.size = cn_select_memory(algorithm) * count; + info.size = props.memory(algorithm.id()) * count; constexpr const size_t align_size = 2 * 1024 * 1024; info.size = ((info.size + align_size - 1) / align_size) * align_size; @@ -53,10 +54,10 @@ MemInfo Mem::create(cryptonight_ctx **ctx, xmrig::Algo algorithm, size_t count) for (size_t i = 0; i < count; ++i) { cryptonight_ctx *c = static_cast(_mm_malloc(sizeof(cryptonight_ctx), 4096)); - c->memory = info.memory + (i * cn_select_memory(algorithm)); + c->memory = info.memory + (i * props.memory(algorithm.id())); - c->generated_code = reinterpret_cast(xmrig::VirtualMemory::allocateExecutableMemory(0x4000)); - c->generated_code_data.variant = xmrig::VARIANT_MAX; + c->generated_code = reinterpret_cast(VirtualMemory::allocateExecutableMemory(0x4000)); + c->generated_code_data.algo = Algorithm::INVALID; c->generated_code_data.height = std::numeric_limits::max(); ctx[i] = c; diff --git a/src/Mem.h b/src/Mem.h index bfb36b00..f43e005d 100644 --- a/src/Mem.h +++ b/src/Mem.h @@ -31,7 +31,7 @@ #include -#include "common/xmrig.h" +#include "crypto/cn/CnAlgo.h" struct cryptonight_ctx; @@ -56,7 +56,7 @@ public: Lock = 4 }; - static MemInfo create(cryptonight_ctx **ctx, xmrig::Algo algorithm, size_t count); + static MemInfo create(cryptonight_ctx **ctx, const xmrig::Algorithm &algorithm, size_t count); static void init(bool enabled); static void release(cryptonight_ctx **ctx, size_t count, MemInfo &info); diff --git a/src/Mem_win.cpp b/src/Mem_win.cpp index 76cbf434..34460e9d 100644 --- a/src/Mem_win.cpp +++ b/src/Mem_win.cpp @@ -34,7 +34,6 @@ #include "common/xmrig.h" #include "crypto/common/portable/mm_malloc.h" #include "crypto/common/VirtualMemory.h" -#include "crypto/cn/CryptoNight_constants.h" #include "crypto/cn/CryptoNight.h" #include "Mem.h" diff --git a/src/Summary.cpp b/src/Summary.cpp index d780d64f..2ba0fd57 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -39,7 +39,7 @@ #include "version.h" -#ifndef XMRIG_NO_ASM +#ifdef XMRIG_FEATURE_ASM static const char *coloredAsmNames[] = { RED_BOLD("none"), "auto", @@ -108,7 +108,7 @@ static void print_threads(xmrig::Config *config) ); } -# ifndef XMRIG_NO_ASM +# ifdef XMRIG_FEATURE_ASM if (config->assembly() == xmrig::ASM_AUTO) { const xmrig::Assembly assembly = xmrig::Cpu::info()->assembly(); diff --git a/src/common/cpu/BasicCpuInfo.cpp b/src/common/cpu/BasicCpuInfo.cpp index d7778bdd..c5b8ed0a 100644 --- a/src/common/cpu/BasicCpuInfo.cpp +++ b/src/common/cpu/BasicCpuInfo.cpp @@ -129,7 +129,7 @@ xmrig::BasicCpuInfo::BasicCpuInfo() : { cpu_brand_string(m_brand); -# ifndef XMRIG_NO_ASM +# ifdef XMRIG_FEATURE_ASM if (hasAES()) { char vendor[13] = { 0 }; int32_t data[4] = { 0 }; diff --git a/src/common/xmrig.h b/src/common/xmrig.h index e8ca8857..5dd41845 100644 --- a/src/common/xmrig.h +++ b/src/common/xmrig.h @@ -30,16 +30,6 @@ namespace xmrig { -enum Algo { - INVALID_ALGO = -1, - CRYPTONIGHT, /* CryptoNight (2 MB) */ - CRYPTONIGHT_LITE, /* CryptoNight (1 MB) */ - CRYPTONIGHT_HEAVY, /* CryptoNight (4 MB) */ - CRYPTONIGHT_PICO, /* CryptoNight (256 KB) */ - ALGO_MAX -}; - - //--av=1 For CPUs with hardware AES. //--av=2 Lower power mode (double hash) of 1. //--av=3 Software AES implementation. @@ -60,29 +50,6 @@ enum AlgoVariant { }; -enum Variant { - VARIANT_AUTO = -1, // Autodetect - VARIANT_0 = 0, // Original CryptoNight or CryptoNight-Heavy - VARIANT_1 = 1, // CryptoNight variant 1 also known as Monero7 and CryptoNightV7 - VARIANT_TUBE = 2, // Modified CryptoNight-Heavy (TUBE only) - VARIANT_XTL = 3, // Modified CryptoNight variant 1 (Stellite only) - VARIANT_MSR = 4, // Modified CryptoNight variant 1 (Masari only) - VARIANT_XHV = 5, // Modified CryptoNight-Heavy (Haven Protocol only) - VARIANT_XAO = 6, // Modified CryptoNight variant 0 (Alloy only) - VARIANT_RTO = 7, // Modified CryptoNight variant 1 (Arto only) - VARIANT_2 = 8, // CryptoNight variant 2 - VARIANT_HALF = 9, // CryptoNight variant 2 with half iterations (Masari/Stellite) - VARIANT_TRTL = 10, // CryptoNight Turtle (TRTL) - VARIANT_GPU = 11, // CryptoNight-GPU (Ryo) - VARIANT_WOW = 12, // CryptoNightR (Wownero) - VARIANT_4 = 13, // CryptoNightR (Monero's variant 4) - VARIANT_RWZ = 14, // CryptoNight variant 2 with 3/4 iterations and reversed shuffle operation (Graft) - VARIANT_ZLS = 15, // CryptoNight variant 2 with 3/4 iterations (Zelerius) - VARIANT_DOUBLE = 16, // CryptoNight variant 2 with double iterations (X-CASH) - VARIANT_MAX -}; - - enum AlgoVerify { VERIFY_HW_AES = 1, VERIFY_SOFT_AES = 2 diff --git a/src/core/config/Config.cpp b/src/core/config/Config.cpp index fbb12ffa..d82c3225 100644 --- a/src/core/config/Config.cpp +++ b/src/core/config/Config.cpp @@ -33,7 +33,6 @@ #include "common/cpu/Cpu.h" #include "core/config/Config.h" #include "crypto/cn/Asm.h" -#include "crypto/cn/CryptoNight_constants.h" #include "rapidjson/document.h" #include "rapidjson/filewritestream.h" #include "rapidjson/prettywriter.h" @@ -71,7 +70,7 @@ bool xmrig::Config::read(const IJsonReader &reader, const char *fileName) setPriority(reader.getInt("cpu-priority", -1)); setThreads(reader.getValue("threads")); -# ifndef XMRIG_NO_ASM +# ifdef XMRIG_FEATURE_ASM setAssembly(reader.getValue("asm")); # endif @@ -93,7 +92,7 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const doc.AddMember("api", api, allocator); doc.AddMember("http", m_http.toJSON(doc), allocator); -# ifndef XMRIG_NO_ASM +# ifdef XMRIG_FEATURE_ASM doc.AddMember("asm", Asm::toJSON(m_assembly), allocator); # endif @@ -144,37 +143,39 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const bool xmrig::Config::finalize() { -// if (!m_threads.cpu.empty()) { // FIXME -// m_threads.mode = Advanced; -// const bool softAES = (m_aesMode == AES_AUTO ? (Cpu::info()->hasAES() ? AES_HW : AES_SOFT) : m_aesMode) == AES_SOFT; + Algorithm algorithm(Algorithm::CN_0); // FIXME algo -// for (size_t i = 0; i < m_threads.cpu.size(); ++i) { -//// m_threads.list.push_back(CpuThread::createFromData(i, m_algorithm.algo(), m_threads.cpu[i], m_priority, softAES)); -// } + if (!m_threads.cpu.empty()) { + m_threads.mode = Advanced; + const bool softAES = (m_aesMode == AES_AUTO ? (Cpu::info()->hasAES() ? AES_HW : AES_SOFT) : m_aesMode) == AES_SOFT; -// return true; -// } + for (size_t i = 0; i < m_threads.cpu.size(); ++i) { + m_threads.list.push_back(CpuThread::createFromData(i, algorithm, m_threads.cpu[i], m_priority, softAES)); + } -// const AlgoVariant av = getAlgoVariant(); -// m_threads.mode = m_threads.count ? Simple : Automatic; + return true; + } -//// const size_t size = CpuThread::multiway(av) * cn_select_memory(m_algorithm.algo()) / 1024; + const AlgoVariant av = getAlgoVariant(); + m_threads.mode = m_threads.count ? Simple : Automatic; -// if (!m_threads.count) { -// m_threads.count = Cpu::info()->optimalThreadsCount(size, m_maxCpuUsage); -// } -// else if (m_safe) { -// const size_t count = Cpu::info()->optimalThreadsCount(size, m_maxCpuUsage); -// if (m_threads.count > count) { -// m_threads.count = count; -// } -// } + const size_t size = CpuThread::multiway(av) * CnAlgo<>::memory(algorithm) / 1024; -// for (size_t i = 0; i < m_threads.count; ++i) { -// m_threads.list.push_back(CpuThread::createFromAV(i, m_algorithm.algo(), av, m_threads.mask, m_priority, m_assembly)); -// } + if (!m_threads.count) { + m_threads.count = Cpu::info()->optimalThreadsCount(size, m_maxCpuUsage); + } + else if (m_safe) { + const size_t count = Cpu::info()->optimalThreadsCount(size, m_maxCpuUsage); + if (m_threads.count > count) { + m_threads.count = count; + } + } -// m_shouldSave = m_threads.mode == Automatic; + for (size_t i = 0; i < m_threads.count; ++i) { + m_threads.list.push_back(CpuThread::createFromAV(i, algorithm, av, m_threads.mask, m_priority, m_assembly)); + } + + m_shouldSave = m_threads.mode == Automatic; return true; } @@ -276,7 +277,7 @@ xmrig::AlgoVariant xmrig::Config::getAlgoVariantLite() const #endif -#ifndef XMRIG_NO_ASM +#ifdef XMRIG_FEATURE_ASM void xmrig::Config::setAssembly(const rapidjson::Value &assembly) { m_assembly = Asm::parse(assembly); diff --git a/src/core/config/Config.h b/src/core/config/Config.h index 4bcb8bba..637f80df 100644 --- a/src/core/config/Config.h +++ b/src/core/config/Config.h @@ -94,7 +94,7 @@ private: AlgoVariant getAlgoVariantLite() const; # endif -# ifndef XMRIG_NO_ASM +# ifdef XMRIG_FEATURE_ASM void setAssembly(const rapidjson::Value &assembly); # endif diff --git a/src/crypto/cn/CnAlgo.h b/src/crypto/cn/CnAlgo.h new file mode 100644 index 00000000..74ade22b --- /dev/null +++ b/src/crypto/cn/CnAlgo.h @@ -0,0 +1,207 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2019 XMR-Stak , + * Copyright 2018 Lee Clagett + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_CN_ALGO_H +#define XMRIG_CN_ALGO_H + + +#include +#include + + +#include "crypto/common/Algorithm.h" + + +namespace xmrig +{ + + +template +class CnAlgo +{ +public: + constexpr inline CnAlgo() + { + static_assert(ALGO != Algorithm::INVALID && m_memory[ALGO] > 0, "invalid CRYPTONIGHT algorithm"); + static_assert(sizeof(m_memory) / sizeof(m_memory)[0] == Algorithm::MAX, "memory table size mismatch"); + static_assert(sizeof(m_iterations) / sizeof(m_iterations)[0] == Algorithm::MAX, "iterations table size mismatch"); + static_assert(sizeof(m_base) / sizeof(m_base)[0] == Algorithm::MAX, "iterations table size mismatch"); + } + + constexpr inline Algorithm::Id base() const { return m_base[ALGO]; } + constexpr inline bool isHeavy() const { return memory() == CN_MEMORY * 2; } + constexpr inline bool isR() const { return ALGO == Algorithm::CN_R || ALGO == Algorithm::CN_WOW; } + constexpr inline size_t memory() const { return m_memory[ALGO]; } + constexpr inline uint32_t iterations() const { return m_iterations[ALGO]; } + constexpr inline uint32_t mask() const { return ((memory() - 1) / 16) * 16; } + + inline static size_t memory(Algorithm::Id algo) + { + switch (Algorithm::family(algo)) { + case Algorithm::CN: + return CN_MEMORY; + + case Algorithm::CN_LITE: + return CN_MEMORY / 2; + + case Algorithm::CN_HEAVY: + return CN_MEMORY * 2; + + case Algorithm::CN_PICO: + return CN_MEMORY / 8; + + default: + break; + } + + return 0; + } + + inline static uint32_t mask(Algorithm::Id algo) + { +# ifdef XMRIG_ALGO_CN_GPU + if (algo == Algorithm::CN_GPU) { + return 0x1FFFC0; + } +# endif + +# ifdef XMRIG_ALGO_CN_PICO + if (algo == Algorithm::CN_PICO_0) { + return 0x1FFF0; + } +# endif + + return ((memory(algo) - 1) / 16) * 16; + } + +private: + constexpr const static size_t CN_MEMORY = 0x200000; + constexpr const static uint32_t CN_ITER = 0x80000; + + constexpr const static size_t m_memory[] = { + CN_MEMORY, // CN_0 + CN_MEMORY, // CN_1 + CN_MEMORY, // CN_2 + CN_MEMORY, // CN_R + CN_MEMORY, // CN_WOW + CN_MEMORY, // CN_FAST + CN_MEMORY, // CN_HALF + CN_MEMORY, // CN_XAO + CN_MEMORY, // CN_RTO + CN_MEMORY, // CN_RWZ + CN_MEMORY, // CN_ZLS + CN_MEMORY, // CN_DOUBLE +# ifdef XMRIG_ALGO_CN_GPU + CN_MEMORY, // CN_GPU +# endif +# ifdef XMRIG_ALGO_CN_LITE + CN_MEMORY / 2, // CN_LITE_0 + CN_MEMORY / 2, // CN_LITE_1 +# endif +# ifdef XMRIG_ALGO_CN_HEAVY + CN_MEMORY * 2, // CN_HEAVY_0 + CN_MEMORY * 2, // CN_HEAVY_TUBE + CN_MEMORY * 2, // CN_HEAVY_XHV +# endif +# ifdef XMRIG_ALGO_CN_PICO + CN_MEMORY / 8, // CN_PICO_0 +# endif + }; + + constexpr const static uint32_t m_iterations[] = { + CN_ITER, // CN_0 + CN_ITER, // CN_1 + CN_ITER, // CN_2 + CN_ITER, // CN_R + CN_ITER, // CN_WOW + CN_ITER / 2, // CN_FAST + CN_ITER / 2, // CN_HALF + CN_ITER * 2, // CN_XAO + CN_ITER, // CN_RTO + 0x60000, // CN_RWZ + 0x60000, // CN_ZLS + CN_ITER * 2, // CN_DOUBLE +# ifdef XMRIG_ALGO_CN_GPU + 0xC000, // CN_GPU +# endif +# ifdef XMRIG_ALGO_CN_LITE + CN_ITER / 2, // CN_LITE_0 + CN_ITER / 2, // CN_LITE_1 +# endif +# ifdef XMRIG_ALGO_CN_HEAVY + CN_ITER / 2, // CN_HEAVY_0 + CN_ITER / 2, // CN_HEAVY_TUBE + CN_ITER / 2, // CN_HEAVY_XHV +# endif +# ifdef XMRIG_ALGO_CN_PICO + CN_ITER / 8, // CN_PICO_0 +# endif + }; + + constexpr const static Algorithm::Id m_base[] = { + Algorithm::CN_0, // CN_0 + Algorithm::CN_1, // CN_1 + Algorithm::CN_2, // CN_2 + Algorithm::CN_2, // CN_R + Algorithm::CN_2, // CN_WOW + Algorithm::CN_1, // CN_FAST + Algorithm::CN_2, // CN_HALF + Algorithm::CN_0, // CN_XAO + Algorithm::CN_1, // CN_RTO + Algorithm::CN_2, // CN_RWZ + Algorithm::CN_2, // CN_ZLS + Algorithm::CN_2, // CN_DOUBLE +# ifdef XMRIG_ALGO_CN_GPU + Algorithm::CN_GPU, // CN_GPU +# endif +# ifdef XMRIG_ALGO_CN_LITE + Algorithm::CN_0, // CN_LITE_0 + Algorithm::CN_1, // CN_LITE_1 +# endif +# ifdef XMRIG_ALGO_CN_HEAVY + Algorithm::CN_0, // CN_HEAVY_0 + Algorithm::CN_1, // CN_HEAVY_TUBE + Algorithm::CN_0, // CN_HEAVY_XHV +# endif +# ifdef XMRIG_ALGO_CN_PICO + Algorithm::CN_2, // CN_PICO_0 +# endif + }; +}; + + +#ifdef XMRIG_ALGO_CN_GPU +template<> constexpr inline uint32_t CnAlgo::mask() const { return 0x1FFFC0; } +#endif + +#ifdef XMRIG_ALGO_CN_PICO +template<> constexpr inline uint32_t CnAlgo::mask() const { return 0x1FFF0; } +#endif + + +} /* namespace xmrig */ + + +#endif /* XMRIG_CN_ALGO_H */ diff --git a/src/crypto/cn/CnHash.cpp b/src/crypto/cn/CnHash.cpp new file mode 100644 index 00000000..61d2ea69 --- /dev/null +++ b/src/crypto/cn/CnHash.cpp @@ -0,0 +1,269 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2019 XMR-Stak , + * Copyright 2018 Lee Clagett + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + + +#include "common/cpu/Cpu.h" +#include "crypto/cn/CnHash.h" +#include "crypto/common/VirtualMemory.h" + + +#if defined(XMRIG_ARM) +# include "crypto/cn/CryptoNight_arm.h" +#else +# include "crypto/cn/CryptoNight_x86.h" +#endif + + +#define ADD_FN(algo) \ + m_map[algo][AV_SINGLE][ASM_NONE] = cryptonight_single_hash; \ + m_map[algo][AV_SINGLE_SOFT][ASM_NONE] = cryptonight_single_hash; \ + m_map[algo][AV_DOUBLE][ASM_NONE] = cryptonight_double_hash; \ + m_map[algo][AV_DOUBLE_SOFT][ASM_NONE] = cryptonight_double_hash; \ + m_map[algo][AV_TRIPLE][ASM_NONE] = cryptonight_triple_hash; \ + m_map[algo][AV_TRIPLE_SOFT][ASM_NONE] = cryptonight_triple_hash; \ + m_map[algo][AV_QUAD][ASM_NONE] = cryptonight_quad_hash; \ + m_map[algo][AV_QUAD_SOFT][ASM_NONE] = cryptonight_quad_hash; \ + m_map[algo][AV_PENTA][ASM_NONE] = cryptonight_penta_hash; \ + m_map[algo][AV_PENTA_SOFT][ASM_NONE] = cryptonight_penta_hash; + + +#ifdef XMRIG_FEATURE_ASM +# define ADD_FN_ASM(algo) \ + m_map[algo][AV_SINGLE][ASM_INTEL] = cryptonight_single_hash_asm; \ + m_map[algo][AV_SINGLE][ASM_RYZEN] = cryptonight_single_hash_asm; \ + m_map[algo][AV_SINGLE][ASM_BULLDOZER] = cryptonight_single_hash_asm; \ + m_map[algo][AV_DOUBLE][ASM_INTEL] = cryptonight_double_hash_asm; \ + m_map[algo][AV_DOUBLE][ASM_RYZEN] = cryptonight_double_hash_asm; \ + m_map[algo][AV_DOUBLE][ASM_BULLDOZER] = cryptonight_double_hash_asm; + + +extern "C" void cnv2_mainloop_ivybridge_asm(cryptonight_ctx **ctx); +extern "C" void cnv2_mainloop_ryzen_asm(cryptonight_ctx **ctx); +extern "C" void cnv2_mainloop_bulldozer_asm(cryptonight_ctx **ctx); +extern "C" void cnv2_double_mainloop_sandybridge_asm(cryptonight_ctx **ctx); + + +namespace xmrig { + + +cn_mainloop_fun cn_half_mainloop_ivybridge_asm = nullptr; +cn_mainloop_fun cn_half_mainloop_ryzen_asm = nullptr; +cn_mainloop_fun cn_half_mainloop_bulldozer_asm = nullptr; +cn_mainloop_fun cn_half_double_mainloop_sandybridge_asm = nullptr; + +cn_mainloop_fun cn_trtl_mainloop_ivybridge_asm = nullptr; +cn_mainloop_fun cn_trtl_mainloop_ryzen_asm = nullptr; +cn_mainloop_fun cn_trtl_mainloop_bulldozer_asm = nullptr; +cn_mainloop_fun cn_trtl_double_mainloop_sandybridge_asm = nullptr; + +cn_mainloop_fun cn_zls_mainloop_ivybridge_asm = nullptr; +cn_mainloop_fun cn_zls_mainloop_ryzen_asm = nullptr; +cn_mainloop_fun cn_zls_mainloop_bulldozer_asm = nullptr; +cn_mainloop_fun cn_zls_double_mainloop_sandybridge_asm = nullptr; + +cn_mainloop_fun cn_double_mainloop_ivybridge_asm = nullptr; +cn_mainloop_fun cn_double_mainloop_ryzen_asm = nullptr; +cn_mainloop_fun cn_double_mainloop_bulldozer_asm = nullptr; +cn_mainloop_fun cn_double_double_mainloop_sandybridge_asm = nullptr; + + +template +static void patchCode(T dst, U src, const uint32_t iterations, const uint32_t mask = CnAlgo().mask()) +{ + const uint8_t* p = reinterpret_cast(src); + + // Workaround for Visual Studio placing trampoline in debug builds. +# if defined(_MSC_VER) + if (p[0] == 0xE9) { + p += *(int32_t*)(p + 1) + 5; + } +# endif + + size_t size = 0; + while (*(uint32_t*)(p + size) != 0xDEADC0DE) { + ++size; + } + + size += sizeof(uint32_t); + + memcpy((void*) dst, (const void*) src, size); + + uint8_t* patched_data = reinterpret_cast(dst); + for (size_t i = 0; i + sizeof(uint32_t) <= size; ++i) { + switch (*(uint32_t*)(patched_data + i)) { + case CnAlgo().iterations(): + *(uint32_t*)(patched_data + i) = iterations; + break; + + case CnAlgo().mask(): + *(uint32_t*)(patched_data + i) = mask; + break; + } + } +} + + +static void patchAsmVariants() +{ + const int allocation_size = 65536; + uint8_t *base = static_cast(VirtualMemory::allocateExecutableMemory(allocation_size)); + + cn_half_mainloop_ivybridge_asm = reinterpret_cast (base + 0x0000); + cn_half_mainloop_ryzen_asm = reinterpret_cast (base + 0x1000); + cn_half_mainloop_bulldozer_asm = reinterpret_cast (base + 0x2000); + cn_half_double_mainloop_sandybridge_asm = reinterpret_cast (base + 0x3000); + +# ifdef XMRIG_ALGO_CN_PICO + cn_trtl_mainloop_ivybridge_asm = reinterpret_cast (base + 0x4000); + cn_trtl_mainloop_ryzen_asm = reinterpret_cast (base + 0x5000); + cn_trtl_mainloop_bulldozer_asm = reinterpret_cast (base + 0x6000); + cn_trtl_double_mainloop_sandybridge_asm = reinterpret_cast (base + 0x7000); +# endif + + cn_zls_mainloop_ivybridge_asm = reinterpret_cast (base + 0x8000); + cn_zls_mainloop_ryzen_asm = reinterpret_cast (base + 0x9000); + cn_zls_mainloop_bulldozer_asm = reinterpret_cast (base + 0xA000); + cn_zls_double_mainloop_sandybridge_asm = reinterpret_cast (base + 0xB000); + + cn_double_mainloop_ivybridge_asm = reinterpret_cast (base + 0xC000); + cn_double_mainloop_ryzen_asm = reinterpret_cast (base + 0xD000); + cn_double_mainloop_bulldozer_asm = reinterpret_cast (base + 0xE000); + cn_double_double_mainloop_sandybridge_asm = reinterpret_cast (base + 0xF000); + + { + constexpr uint32_t ITER = CnAlgo().iterations(); + + patchCode(cn_half_mainloop_ivybridge_asm, cnv2_mainloop_ivybridge_asm, ITER); + patchCode(cn_half_mainloop_ryzen_asm, cnv2_mainloop_ryzen_asm, ITER); + patchCode(cn_half_mainloop_bulldozer_asm, cnv2_mainloop_bulldozer_asm, ITER); + patchCode(cn_half_double_mainloop_sandybridge_asm, cnv2_double_mainloop_sandybridge_asm, ITER); + } + +# ifdef XMRIG_ALGO_CN_PICO + { + constexpr uint32_t ITER = CnAlgo().iterations(); + constexpr uint32_t MASK = CnAlgo().mask(); + + patchCode(cn_trtl_mainloop_ivybridge_asm, cnv2_mainloop_ivybridge_asm, ITER, MASK); + patchCode(cn_trtl_mainloop_ryzen_asm, cnv2_mainloop_ryzen_asm, ITER, MASK); + patchCode(cn_trtl_mainloop_bulldozer_asm, cnv2_mainloop_bulldozer_asm, ITER, MASK); + patchCode(cn_trtl_double_mainloop_sandybridge_asm, cnv2_double_mainloop_sandybridge_asm, ITER, MASK); + } +# endif + + { + constexpr uint32_t ITER = CnAlgo().iterations(); + + patchCode(cn_zls_mainloop_ivybridge_asm, cnv2_mainloop_ivybridge_asm, ITER); + patchCode(cn_zls_mainloop_ryzen_asm, cnv2_mainloop_ryzen_asm, ITER); + patchCode(cn_zls_mainloop_bulldozer_asm, cnv2_mainloop_bulldozer_asm, ITER); + patchCode(cn_zls_double_mainloop_sandybridge_asm, cnv2_double_mainloop_sandybridge_asm, ITER); + } + + { + constexpr uint32_t ITER = CnAlgo().iterations(); + + patchCode(cn_double_mainloop_ivybridge_asm, cnv2_mainloop_ivybridge_asm, ITER); + patchCode(cn_double_mainloop_ryzen_asm, cnv2_mainloop_ryzen_asm, ITER); + patchCode(cn_double_mainloop_bulldozer_asm, cnv2_mainloop_bulldozer_asm, ITER); + patchCode(cn_double_double_mainloop_sandybridge_asm, cnv2_double_mainloop_sandybridge_asm, ITER); + } + + VirtualMemory::protectExecutableMemory(base, allocation_size); + VirtualMemory::flushInstructionCache(base, allocation_size); +} +} // namespace xmrig +#else +# define ADD_FN_ASM(algo) +#endif + + +xmrig::CnHash::CnHash() +{ + ADD_FN(Algorithm::CN_0); + ADD_FN(Algorithm::CN_1); + ADD_FN(Algorithm::CN_2); + ADD_FN(Algorithm::CN_R); + ADD_FN(Algorithm::CN_WOW); + ADD_FN(Algorithm::CN_FAST); + ADD_FN(Algorithm::CN_HALF); + ADD_FN(Algorithm::CN_XAO); + ADD_FN(Algorithm::CN_RTO); + ADD_FN(Algorithm::CN_RWZ); + ADD_FN(Algorithm::CN_ZLS); + ADD_FN(Algorithm::CN_DOUBLE); + + ADD_FN_ASM(Algorithm::CN_2); + ADD_FN_ASM(Algorithm::CN_HALF); + ADD_FN_ASM(Algorithm::CN_R); + ADD_FN_ASM(Algorithm::CN_WOW); + ADD_FN_ASM(Algorithm::CN_RWZ); + ADD_FN_ASM(Algorithm::CN_ZLS); + ADD_FN_ASM(Algorithm::CN_DOUBLE); + +# ifdef XMRIG_ALGO_CN_GPU + m_map[Algorithm::CN_GPU][AV_SINGLE][ASM_NONE] = cryptonight_single_hash_gpu; + m_map[Algorithm::CN_GPU][AV_SINGLE_SOFT][ASM_NONE] = cryptonight_single_hash_gpu; +# endif + +# ifdef XMRIG_ALGO_CN_LITE + ADD_FN(Algorithm::CN_LITE_0); + ADD_FN(Algorithm::CN_LITE_1); +# endif + +# ifdef XMRIG_ALGO_CN_HEAVY + ADD_FN(Algorithm::CN_HEAVY_0); + ADD_FN(Algorithm::CN_HEAVY_TUBE); + ADD_FN(Algorithm::CN_HEAVY_XHV); +# endif + +# ifdef XMRIG_ALGO_CN_PICO + ADD_FN(Algorithm::CN_PICO_0); + ADD_FN_ASM(Algorithm::CN_PICO_0); +# endif + +# ifdef XMRIG_FEATURE_ASM + patchAsmVariants(); +# endif +} + + +xmrig::cn_hash_fun xmrig::CnHash::fn(const Algorithm &algorithm, AlgoVariant av, Assembly assembly) const +{ + if (!algorithm.isValid()) { + return nullptr; + } + +# ifdef XMRIG_FEATURE_ASM + cn_hash_fun fun = m_map[algorithm][av][assembly == ASM_AUTO ? Cpu::info()->assembly() : assembly]; + if (fun) { + return fun; + } +# endif + + return m_map[algorithm][av][ASM_NONE]; +} diff --git a/src/crypto/cn/CnHash.h b/src/crypto/cn/CnHash.h new file mode 100644 index 00000000..5fbf5c8a --- /dev/null +++ b/src/crypto/cn/CnHash.h @@ -0,0 +1,63 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2019 XMR-Stak , + * Copyright 2018 Lee Clagett + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_CN_HASH_H +#define XMRIG_CN_HASH_H + + +#include +#include + + +#include "common/xmrig.h" +#include "crypto/cn/CnAlgo.h" + + +struct cryptonight_ctx; + + +namespace xmrig +{ + +typedef void (*cn_hash_fun)(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx **ctx, uint64_t height); +typedef void (*cn_mainloop_fun)(cryptonight_ctx **ctx); + + +class CnHash +{ +public: + CnHash(); + + cn_hash_fun fn(const Algorithm &algorithm, AlgoVariant av, Assembly assembly) const; + +private: + cn_hash_fun m_map[Algorithm::MAX][AV_MAX][ASM_MAX] = {}; +}; + + +} /* namespace xmrig */ + + +#endif /* XMRIG_CN_HASH_H */ diff --git a/src/crypto/cn/CryptoNight.h b/src/crypto/cn/CryptoNight.h index f50966ed..434c34f8 100644 --- a/src/crypto/cn/CryptoNight.h +++ b/src/crypto/cn/CryptoNight.h @@ -42,10 +42,10 @@ typedef void(*cn_mainloop_fun_ms_abi)(cryptonight_ctx**) ABI_ATTRIBUTE; struct cryptonight_r_data { - int variant; + int algo; uint64_t height; - bool match(const int v, const uint64_t h) const { return (v == variant) && (h == height); } + bool match(const int a, const uint64_t h) const { return (a == algo) && (h == height); } }; diff --git a/src/crypto/cn/CryptoNight_constants.h b/src/crypto/cn/CryptoNight_constants.h deleted file mode 100644 index 1bc06a3b..00000000 --- a/src/crypto/cn/CryptoNight_constants.h +++ /dev/null @@ -1,251 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017-2019 XMR-Stak , - * Copyright 2018 Lee Clagett - * Copyright 2018-2019 SChernykh - * Copyright 2016-2019 XMRig , - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef XMRIG_CRYPTONIGHT_CONSTANTS_H -#define XMRIG_CRYPTONIGHT_CONSTANTS_H - - -#include -#include - - -#include "common/xmrig.h" - - -namespace xmrig -{ - -constexpr const size_t CRYPTONIGHT_MEMORY = 2 * 1024 * 1024; -constexpr const uint32_t CRYPTONIGHT_MASK = 0x1FFFF0; -constexpr const uint32_t CRYPTONIGHT_ITER = 0x80000; -constexpr const uint32_t CRYPTONIGHT_HALF_ITER = 0x40000; -constexpr const uint32_t CRYPTONIGHT_XAO_ITER = 0x100000; -constexpr const uint32_t CRYPTONIGHT_DOUBLE_ITER = 0x100000; -constexpr const uint32_t CRYPTONIGHT_WALTZ_ITER = 0x60000; -constexpr const uint32_t CRYPTONIGHT_ZLS_ITER = 0x60000; - -constexpr const uint32_t CRYPTONIGHT_GPU_ITER = 0xC000; -constexpr const uint32_t CRYPTONIGHT_GPU_MASK = 0x1FFFC0; - -constexpr const size_t CRYPTONIGHT_LITE_MEMORY = 1 * 1024 * 1024; -constexpr const uint32_t CRYPTONIGHT_LITE_MASK = 0xFFFF0; -constexpr const uint32_t CRYPTONIGHT_LITE_ITER = 0x40000; - -constexpr const size_t CRYPTONIGHT_HEAVY_MEMORY = 4 * 1024 * 1024; -constexpr const uint32_t CRYPTONIGHT_HEAVY_MASK = 0x3FFFF0; -constexpr const uint32_t CRYPTONIGHT_HEAVY_ITER = 0x40000; - -constexpr const size_t CRYPTONIGHT_PICO_MEMORY = 256 * 1024; -constexpr const uint32_t CRYPTONIGHT_PICO_MASK = 0x1FFF0; -constexpr const uint32_t CRYPTONIGHT_PICO_ITER = 0x40000; -constexpr const uint32_t CRYPTONIGHT_TRTL_ITER = 0x10000; - - -template inline constexpr size_t cn_select_memory() { return 0; } -template<> inline constexpr size_t cn_select_memory() { return CRYPTONIGHT_MEMORY; } -template<> inline constexpr size_t cn_select_memory() { return CRYPTONIGHT_LITE_MEMORY; } -template<> inline constexpr size_t cn_select_memory() { return CRYPTONIGHT_HEAVY_MEMORY; } -template<> inline constexpr size_t cn_select_memory() { return CRYPTONIGHT_PICO_MEMORY; } - - -inline size_t cn_select_memory(Algo algorithm) -{ - switch(algorithm) - { - case CRYPTONIGHT: - return CRYPTONIGHT_MEMORY; - - case CRYPTONIGHT_LITE: - return CRYPTONIGHT_LITE_MEMORY; - - case CRYPTONIGHT_HEAVY: - return CRYPTONIGHT_HEAVY_MEMORY; - - case CRYPTONIGHT_PICO: - return CRYPTONIGHT_PICO_MEMORY; - - default: - break; - } - - return 0; -} - - -template inline constexpr uint32_t cn_select_mask() { return 0; } -template<> inline constexpr uint32_t cn_select_mask() { return CRYPTONIGHT_MASK; } -template<> inline constexpr uint32_t cn_select_mask() { return CRYPTONIGHT_LITE_MASK; } -template<> inline constexpr uint32_t cn_select_mask() { return CRYPTONIGHT_HEAVY_MASK; } -template<> inline constexpr uint32_t cn_select_mask() { return CRYPTONIGHT_PICO_MASK; } - - -inline uint32_t cn_select_mask(Algo algorithm) -{ - switch(algorithm) - { - case CRYPTONIGHT: - return CRYPTONIGHT_MASK; - - case CRYPTONIGHT_LITE: - return CRYPTONIGHT_LITE_MASK; - - case CRYPTONIGHT_HEAVY: - return CRYPTONIGHT_HEAVY_MASK; - - case CRYPTONIGHT_PICO: - return CRYPTONIGHT_PICO_MASK; - - default: - break; - } - - return 0; -} - - -template inline constexpr uint32_t cn_select_iter() { return 0; } -template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_ITER; } -template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_ITER; } -template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_ITER; } -template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_ITER; } -template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_ITER; } -template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_ITER; } -template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_HALF_ITER; } -template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_HALF_ITER; } -template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_XAO_ITER; } -template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_ITER; } -template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_GPU_ITER; } -template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_WALTZ_ITER; } -template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_ZLS_ITER; } -template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_DOUBLE_ITER; } -template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_LITE_ITER; } -template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_LITE_ITER; } -template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_HEAVY_ITER; } -template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_HEAVY_ITER; } -template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_HEAVY_ITER; } -template<> inline constexpr uint32_t cn_select_iter() { return CRYPTONIGHT_TRTL_ITER; } - - -inline uint32_t cn_select_iter(Algo algorithm, Variant variant) -{ - switch (variant) { - case VARIANT_MSR: - case VARIANT_HALF: - return CRYPTONIGHT_HALF_ITER; - - case VARIANT_GPU: - return CRYPTONIGHT_GPU_ITER; - - case VARIANT_RTO: - case VARIANT_DOUBLE: - return CRYPTONIGHT_XAO_ITER; - - case VARIANT_TRTL: - return CRYPTONIGHT_TRTL_ITER; - - case VARIANT_RWZ: - case VARIANT_ZLS: - return CRYPTONIGHT_WALTZ_ITER; - - default: - break; - } - - switch(algorithm) - { - case CRYPTONIGHT: - return CRYPTONIGHT_ITER; - - case CRYPTONIGHT_LITE: - return CRYPTONIGHT_LITE_ITER; - - case CRYPTONIGHT_HEAVY: - return CRYPTONIGHT_HEAVY_ITER; - - case CRYPTONIGHT_PICO: - return CRYPTONIGHT_TRTL_ITER; - - default: - break; - } - - return 0; -} - - -template inline constexpr Variant cn_base_variant() { return VARIANT_0; } -template<> inline constexpr Variant cn_base_variant() { return VARIANT_0; } -template<> inline constexpr Variant cn_base_variant() { return VARIANT_1; } -template<> inline constexpr Variant cn_base_variant() { return VARIANT_1; } -template<> inline constexpr Variant cn_base_variant() { return VARIANT_1; } -template<> inline constexpr Variant cn_base_variant() { return VARIANT_1; } -template<> inline constexpr Variant cn_base_variant() { return VARIANT_0; } -template<> inline constexpr Variant cn_base_variant() { return VARIANT_0; } -template<> inline constexpr Variant cn_base_variant() { return VARIANT_1; } -template<> inline constexpr Variant cn_base_variant() { return VARIANT_2; } -template<> inline constexpr Variant cn_base_variant() { return VARIANT_2; } -template<> inline constexpr Variant cn_base_variant() { return VARIANT_2; } -template<> inline constexpr Variant cn_base_variant() { return VARIANT_GPU; } -template<> inline constexpr Variant cn_base_variant() { return VARIANT_2; } -template<> inline constexpr Variant cn_base_variant() { return VARIANT_2; } -template<> inline constexpr Variant cn_base_variant() { return VARIANT_2; } -template<> inline constexpr Variant cn_base_variant() { return VARIANT_2; } -template<> inline constexpr Variant cn_base_variant() { return VARIANT_2; } - - -inline Variant cn_base_variant(Variant variant) -{ - switch (variant) { - case VARIANT_0: - case VARIANT_XHV: - case VARIANT_XAO: - return VARIANT_0; - - case VARIANT_1: - case VARIANT_TUBE: - case VARIANT_XTL: - case VARIANT_MSR: - case VARIANT_RTO: - return VARIANT_1; - - case VARIANT_GPU: - return VARIANT_GPU; - - default: - break; - } - - return VARIANT_2; -} - - -template inline constexpr bool cn_is_cryptonight_r() { return false; } -template<> inline constexpr bool cn_is_cryptonight_r() { return true; } -template<> inline constexpr bool cn_is_cryptonight_r() { return true; } - -} /* namespace xmrig */ - - -#endif /* XMRIG_CRYPTONIGHT_CONSTANTS_H */ diff --git a/src/crypto/cn/CryptoNight_monero.h b/src/crypto/cn/CryptoNight_monero.h index 94a18c45..259cb3b6 100644 --- a/src/crypto/cn/CryptoNight_monero.h +++ b/src/crypto/cn/CryptoNight_monero.h @@ -33,21 +33,21 @@ #ifndef XMRIG_ARM # define VARIANT1_INIT(part) \ uint64_t tweak1_2_##part = 0; \ - if (BASE == xmrig::VARIANT_1) { \ + if (BASE == Algorithm::CN_1) { \ tweak1_2_##part = (*reinterpret_cast(input + 35 + part * size) ^ \ *(reinterpret_cast(ctx[part]->state) + 24)); \ } #else # define VARIANT1_INIT(part) \ uint64_t tweak1_2_##part = 0; \ - if (BASE == xmrig::VARIANT_1) { \ + if (BASE == Algorithm::CN_1) { \ memcpy(&tweak1_2_##part, input + 35 + part * size, sizeof tweak1_2_##part); \ tweak1_2_##part ^= *(reinterpret_cast(ctx[part]->state) + 24); \ } #endif #define VARIANT1_1(p) \ - if (BASE == xmrig::VARIANT_1) { \ + if (BASE == Algorithm::CN_1) { \ const uint8_t tmp = reinterpret_cast(p)[11]; \ static const uint32_t table = 0x75310; \ const uint8_t index = (((tmp >> 3) & 6) | (tmp & 1)) << 1; \ @@ -55,20 +55,20 @@ } #define VARIANT1_2(p, part) \ - if (BASE == xmrig::VARIANT_1) { \ + if (BASE == Algorithm::CN_1) { \ (p) ^= tweak1_2_##part; \ } #ifndef XMRIG_ARM # define VARIANT2_INIT(part) \ - __m128i division_result_xmm_##part = _mm_cvtsi64_si128(h##part[12]); \ - __m128i sqrt_result_xmm_##part = _mm_cvtsi64_si128(h##part[13]); + __m128i division_result_xmm_##part = _mm_cvtsi64_si128(static_cast(h##part[12])); \ + __m128i sqrt_result_xmm_##part = _mm_cvtsi64_si128(static_cast(h##part[13])); #ifdef _MSC_VER -# define VARIANT2_SET_ROUNDING_MODE() if (BASE == xmrig::VARIANT_2) { _control87(RC_DOWN, MCW_RC); } +# define VARIANT2_SET_ROUNDING_MODE() if (BASE == Algorithm::CN_2) { _control87(RC_DOWN, MCW_RC); } #else -# define VARIANT2_SET_ROUNDING_MODE() if (BASE == xmrig::VARIANT_2) { fesetround(FE_DOWNWARD); } +# define VARIANT2_SET_ROUNDING_MODE() if (BASE == Algorithm::CN_2) { fesetround(FE_DOWNWARD); } #endif # define VARIANT2_INTEGER_MATH(part, cl, cx) \ @@ -91,7 +91,7 @@ _mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x10)), _mm_add_epi64(chunk3, _b1)); \ _mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x20)), _mm_add_epi64(chunk1, _b)); \ _mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x30)), _mm_add_epi64(chunk2, _a)); \ - if (VARIANT == xmrig::VARIANT_4) { \ + if (ALGO == Algorithm::CN_R) { \ _c = _mm_xor_si128(_mm_xor_si128(_c, chunk3), _mm_xor_si128(chunk1, chunk2)); \ } \ } while (0) @@ -141,7 +141,7 @@ vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x10)), vaddq_u64(chunk3, vreinterpretq_u64_u8(_b1))); \ vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x20)), vaddq_u64(chunk1, vreinterpretq_u64_u8(_b))); \ vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x30)), vaddq_u64(chunk2, vreinterpretq_u64_u8(_a))); \ - if (VARIANT == xmrig::VARIANT_4) { \ + if (ALGO == Algorithm::CN_4) { \ _c = veorq_u64(veorq_u64(_c, chunk3), veorq_u64(chunk1, chunk2)); \ } \ } while (0) @@ -184,17 +184,17 @@ #define VARIANT4_RANDOM_MATH_INIT(part) \ uint32_t r##part[9]; \ struct V4_Instruction code##part[256]; \ - if ((VARIANT == xmrig::VARIANT_WOW) || (VARIANT == xmrig::VARIANT_4)) { \ - r##part[0] = (uint32_t)(h##part[12]); \ - r##part[1] = (uint32_t)(h##part[12] >> 32); \ - r##part[2] = (uint32_t)(h##part[13]); \ - r##part[3] = (uint32_t)(h##part[13] >> 32); \ + if (props.isR()) { \ + r##part[0] = static_cast(h##part[12]); \ + r##part[1] = static_cast(h##part[12] >> 32); \ + r##part[2] = static_cast(h##part[13]); \ + r##part[3] = static_cast(h##part[13] >> 32); \ } \ - v4_random_math_init(code##part, height); + v4_random_math_init(code##part, height); #define VARIANT4_RANDOM_MATH(part, al, ah, cl, bx0, bx1) \ - if ((VARIANT == xmrig::VARIANT_WOW) || (VARIANT == xmrig::VARIANT_4)) { \ - cl ^= (r##part[0] + r##part[1]) | ((uint64_t)(r##part[2] + r##part[3]) << 32); \ + if (props.isR()) { \ + cl ^= (r##part[0] + r##part[1]) | (static_cast(r##part[2] + r##part[3]) << 32); \ r##part[4] = static_cast(al); \ r##part[5] = static_cast(ah); \ r##part[6] = static_cast(_mm_cvtsi128_si32(bx0)); \ diff --git a/src/crypto/cn/CryptoNight_test.h b/src/crypto/cn/CryptoNight_test.h index 2429fc17..77cbbb8e 100644 --- a/src/crypto/cn/CryptoNight_test.h +++ b/src/crypto/cn/CryptoNight_test.h @@ -156,21 +156,6 @@ const static uint8_t test_output_v2[160] = { }; -// "cn/xtl" Stellite (XTL) -const static uint8_t test_output_xtl[160] = { - 0x8F, 0xE5, 0xF0, 0x5F, 0x02, 0x2A, 0x61, 0x7D, 0xE5, 0x3F, 0x79, 0x36, 0x4B, 0x25, 0xCB, 0xC3, - 0xC0, 0x8E, 0x0E, 0x1F, 0xE3, 0xBE, 0x48, 0x57, 0x07, 0x03, 0xFE, 0xE1, 0xEC, 0x0E, 0xB0, 0xB1, - 0x21, 0x26, 0xFF, 0x98, 0xE6, 0x86, 0x08, 0x5B, 0xC9, 0x96, 0x44, 0xA3, 0xB8, 0x4E, 0x28, 0x90, - 0x76, 0xED, 0xAD, 0xB9, 0xAA, 0xAC, 0x01, 0x94, 0x1D, 0xBE, 0x3E, 0xEA, 0xAD, 0xEE, 0xB2, 0xCF, - 0xB0, 0x43, 0x4B, 0x88, 0xFC, 0xB2, 0xF3, 0x82, 0x9D, 0xD7, 0xDF, 0x51, 0x97, 0x2C, 0x5A, 0xE3, - 0xC7, 0x16, 0x0B, 0xC8, 0x7C, 0xB7, 0x2F, 0x1C, 0x55, 0x33, 0xCA, 0xE1, 0xEE, 0x08, 0xA4, 0x86, - 0x60, 0xED, 0x6E, 0x9D, 0x2D, 0x05, 0x0D, 0x7D, 0x02, 0x49, 0x23, 0x39, 0x7C, 0xC3, 0x6D, 0x3D, - 0x05, 0x51, 0x28, 0xF1, 0x9B, 0x3C, 0xDF, 0xC4, 0xEA, 0x8A, 0xA6, 0x6A, 0x3C, 0x8B, 0xE2, 0xAF, - 0x47, 0x00, 0xFC, 0x36, 0xED, 0x50, 0xBB, 0xD2, 0x2E, 0x63, 0x4B, 0x93, 0x11, 0x0C, 0xA7, 0xBA, - 0x32, 0x6E, 0x47, 0x4D, 0xCE, 0xCC, 0x82, 0x54, 0x1D, 0x06, 0xF8, 0x06, 0x86, 0xBD, 0x22, 0x48 -}; - - // "cn/half" const static uint8_t test_output_half[160] = { 0x5D, 0x4F, 0xBC, 0x35, 0x60, 0x97, 0xEA, 0x64, 0x40, 0xB0, 0x88, 0x8E, 0xDE, 0xB6, 0x35, 0xDD, diff --git a/src/crypto/cn/CryptoNight_x86.h b/src/crypto/cn/CryptoNight_x86.h index 8d6792d2..994ee116 100644 --- a/src/crypto/cn/CryptoNight_x86.h +++ b/src/crypto/cn/CryptoNight_x86.h @@ -37,9 +37,9 @@ #include "common/cpu/Cpu.h" #include "common/crypto/keccak.h" -#include "crypto/cn/CryptoNight.h" -#include "crypto/cn/CryptoNight_constants.h" +#include "crypto/cn/CnAlgo.h" #include "crypto/cn/CryptoNight_monero.h" +#include "crypto/cn/CryptoNight.h" #include "crypto/cn/soft_aes.h" @@ -303,9 +303,14 @@ inline void mix_and_propagate(__m128i& x0, __m128i& x1, __m128i& x2, __m128i& x3 } -template +namespace xmrig { + + +template static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output) { + constexpr CnAlgo props; + __m128i xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7; __m128i k0, k1, k2, k3, k4, k5, k6, k7, k8, k9; @@ -320,7 +325,7 @@ static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output) xin6 = _mm_load_si128(input + 10); xin7 = _mm_load_si128(input + 11); - if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { + if (props.isHeavy()) { for (size_t i = 0; i < 16; i++) { aes_round(k0, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); aes_round(k1, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); @@ -337,7 +342,7 @@ static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output) } } - for (size_t i = 0; i < MEM / sizeof(__m128i); i += 8) { + for (size_t i = 0; i < props.memory() / sizeof(__m128i); i += 8) { aes_round(k0, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); aes_round(k1, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); aes_round(k2, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); @@ -361,37 +366,17 @@ static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output) } -#ifdef XMRIG_ALGO_CN_GPU -template -void cn_explode_scratchpad_gpu(const uint8_t *input, uint8_t *output) -{ - constexpr size_t hash_size = 200; // 25x8 bytes - alignas(16) uint64_t hash[25]; - - for (uint64_t i = 0; i < MEM / 512; i++) - { - memcpy(hash, input, hash_size); - hash[0] ^= i; - - xmrig::keccakf(hash, 24); - memcpy(output, hash, 160); - output += 160; - - xmrig::keccakf(hash, 24); - memcpy(output, hash, 176); - output += 176; - - xmrig::keccakf(hash, 24); - memcpy(output, hash, 176); - output += 176; - } -} -#endif - - -template +template static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) { + constexpr CnAlgo props; + +# ifdef XMRIG_ALGO_CN_GPU + constexpr bool IS_HEAVY = props.isHeavy() || ALGO == Algorithm::CN_GPU; +# else + constexpr bool IS_HEAVY = props.isHeavy(); +# endif + __m128i xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7; __m128i k0, k1, k2, k3, k4, k5, k6, k7, k8, k9; @@ -406,8 +391,7 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) xout6 = _mm_load_si128(output + 10); xout7 = _mm_load_si128(output + 11); - for (size_t i = 0; i < MEM / sizeof(__m128i); i += 8) - { + for (size_t i = 0; i < props.memory() / sizeof(__m128i); i += 8) { xout0 = _mm_xor_si128(_mm_load_si128(input + i + 0), xout0); xout1 = _mm_xor_si128(_mm_load_si128(input + i + 1), xout1); xout2 = _mm_xor_si128(_mm_load_si128(input + i + 2), xout2); @@ -428,13 +412,13 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) aes_round(k8, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); aes_round(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { + if (IS_HEAVY) { mix_and_propagate(xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7); } } - if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { - for (size_t i = 0; i < MEM / sizeof(__m128i); i += 8) { + if (IS_HEAVY) { + for (size_t i = 0; i < props.memory() / sizeof(__m128i); i += 8) { xout0 = _mm_xor_si128(_mm_load_si128(input + i + 0), xout0); xout1 = _mm_xor_si128(_mm_load_si128(input + i + 1), xout1); xout2 = _mm_xor_si128(_mm_load_si128(input + i + 2), xout2); @@ -485,6 +469,9 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) } +} /* namespace xmrig */ + + static inline __m128i aes_round_tweak_div(const __m128i &in, const __m128i &key) { alignas(16) uint32_t k[4]; @@ -527,12 +514,21 @@ static inline __m128i int_sqrt_v2(const uint64_t n0) } -template -static inline void cryptonight_monero_tweak(uint64_t* mem_out, const uint8_t* l, uint64_t idx, __m128i ax0, __m128i bx0, __m128i bx1, __m128i& cx) +void wow_soft_aes_compile_code(const V4_Instruction *code, int code_size, void *machine_code, xmrig::Assembly ASM); +void v4_soft_aes_compile_code(const V4_Instruction *code, int code_size, void *machine_code, xmrig::Assembly ASM); + + +namespace xmrig { + + +template +static inline void cryptonight_monero_tweak(uint64_t *mem_out, const uint8_t *l, uint64_t idx, __m128i ax0, __m128i bx0, __m128i bx1, __m128i& cx) { - if (BASE == xmrig::VARIANT_2) { - VARIANT2_SHUFFLE(l, idx, ax0, bx0, bx1, cx, (VARIANT == xmrig::VARIANT_RWZ ? 1 : 0)); - _mm_store_si128((__m128i *)mem_out, _mm_xor_si128(bx0, cx)); + constexpr CnAlgo props; + + if (props.base() == Algorithm::CN_2) { + VARIANT2_SHUFFLE(l, idx, ax0, bx0, bx1, cx, (ALGO == Algorithm::CN_RWZ ? 1 : 0)); + _mm_store_si128(reinterpret_cast<__m128i *>(mem_out), _mm_xor_si128(bx0, cx)); } else { __m128i tmp = _mm_xor_si128(bx0, cx); mem_out[0] = _mm_cvtsi128_si64(tmp); @@ -542,107 +538,105 @@ static inline void cryptonight_monero_tweak(uint64_t* mem_out, const uint8_t* l, uint8_t x = static_cast(vh >> 24); static const uint16_t table = 0x7531; - const uint8_t index = (((x >> (VARIANT == xmrig::VARIANT_XTL ? 4 : 3)) & 6) | (x & 1)) << 1; + const uint8_t index = (((x >> (3)) & 6) | (x & 1)) << 1; vh ^= ((table >> index) & 0x3) << 28; mem_out[1] = vh; } } -void wow_soft_aes_compile_code(const V4_Instruction* code, int code_size, void* machine_code, xmrig::Assembly ASM); -void v4_soft_aes_compile_code(const V4_Instruction* code, int code_size, void* machine_code, xmrig::Assembly ASM); -template +template inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx, uint64_t height) { - constexpr size_t MASK = xmrig::cn_select_mask(); - constexpr size_t ITERATIONS = xmrig::cn_select_iter(); - constexpr size_t MEM = xmrig::cn_select_memory(); - constexpr xmrig::Variant BASE = xmrig::cn_base_variant(); + constexpr CnAlgo props; + constexpr size_t MASK = props.mask(); + constexpr Algorithm::Id BASE = props.base(); - static_assert(MASK > 0 && ITERATIONS > 0 && MEM > 0, "unsupported algorithm/variant"); +# ifdef XMRIG_ALGO_CN_HEAVY + constexpr bool IS_CN_HEAVY_TUBE = ALGO == Algorithm::CN_HEAVY_TUBE; +# else + constexpr bool IS_CN_HEAVY_TUBE = false; +# endif - if (BASE == xmrig::VARIANT_1 && size < 43) { + if (BASE == Algorithm::CN_1 && size < 43) { memset(output, 0, 32); return; } - xmrig::keccak(input, size, ctx[0]->state); + keccak(input, size, ctx[0]->state); + cn_explode_scratchpad(reinterpret_cast(ctx[0]->state), reinterpret_cast<__m128i *>(ctx[0]->memory)); - cn_explode_scratchpad((__m128i*) ctx[0]->state, (__m128i*) ctx[0]->memory); + uint64_t *h0 = reinterpret_cast(ctx[0]->state); + uint8_t *l0 = ctx[0]->memory; - uint64_t* h0 = reinterpret_cast(ctx[0]->state); - -#ifndef XMRIG_NO_ASM - if (SOFT_AES && xmrig::cn_is_cryptonight_r()) - { - if (!ctx[0]->generated_code_data.match(VARIANT, height)) { +# ifdef XMRIG_FEATURE_ASM + if (SOFT_AES && props.isR()) { + if (!ctx[0]->generated_code_data.match(ALGO, height)) { V4_Instruction code[256]; - const int code_size = v4_random_math_init(code, height); + const int code_size = v4_random_math_init(code, height); - if (VARIANT == xmrig::VARIANT_WOW) - wow_soft_aes_compile_code(code, code_size, reinterpret_cast(ctx[0]->generated_code), xmrig::ASM_NONE); - else if (VARIANT == xmrig::VARIANT_4) - v4_soft_aes_compile_code(code, code_size, reinterpret_cast(ctx[0]->generated_code), xmrig::ASM_NONE); + if (ALGO == Algorithm::CN_WOW) { + wow_soft_aes_compile_code(code, code_size, reinterpret_cast(ctx[0]->generated_code), ASM_NONE); + } + else if (ALGO == Algorithm::CN_R) { + v4_soft_aes_compile_code(code, code_size, reinterpret_cast(ctx[0]->generated_code), ASM_NONE); + } - ctx[0]->generated_code_data.variant = VARIANT; - ctx[0]->generated_code_data.height = height; + ctx[0]->generated_code_data = { ALGO, height }; } - ctx[0]->saes_table = (const uint32_t*)saes_table; + ctx[0]->saes_table = reinterpret_cast(saes_table); ctx[0]->generated_code(ctx); } else { -#endif - - const uint8_t* l0 = ctx[0]->memory; +# endif VARIANT1_INIT(0); VARIANT2_INIT(0); VARIANT2_SET_ROUNDING_MODE(); VARIANT4_RANDOM_MATH_INIT(0); - uint64_t al0 = h0[0] ^ h0[4]; - uint64_t ah0 = h0[1] ^ h0[5]; - __m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); - __m128i bx1 = _mm_set_epi64x(h0[9] ^ h0[11], h0[8] ^ h0[10]); - + uint64_t al0 = h0[0] ^ h0[4]; + uint64_t ah0 = h0[1] ^ h0[5]; uint64_t idx0 = al0; + __m128i bx0 = _mm_set_epi64x(static_cast(h0[3] ^ h0[7]), static_cast(h0[2] ^ h0[6])); + __m128i bx1 = _mm_set_epi64x(static_cast(h0[9] ^ h0[11]), static_cast(h0[8] ^ h0[10])); - for (size_t i = 0; i < ITERATIONS; i++) { + for (size_t i = 0; i < props.iterations(); i++) { __m128i cx; - if (VARIANT == xmrig::VARIANT_TUBE || !SOFT_AES) { - cx = _mm_load_si128((__m128i *) &l0[idx0 & MASK]); + if (IS_CN_HEAVY_TUBE || !SOFT_AES) { + cx = _mm_load_si128(reinterpret_cast(&l0[idx0 & MASK])); } - const __m128i ax0 = _mm_set_epi64x(ah0, al0); - if (VARIANT == xmrig::VARIANT_TUBE) { + const __m128i ax0 = _mm_set_epi64x(static_cast(ah0), static_cast(al0)); + if (IS_CN_HEAVY_TUBE) { cx = aes_round_tweak_div(cx, ax0); } else if (SOFT_AES) { - cx = soft_aesenc((uint32_t*)&l0[idx0 & MASK], ax0, (const uint32_t*)saes_table); + cx = soft_aesenc(&l0[idx0 & MASK], ax0, reinterpret_cast(saes_table)); } else { cx = _mm_aesenc_si128(cx, ax0); } - if (BASE == xmrig::VARIANT_1 || BASE == xmrig::VARIANT_2) { - cryptonight_monero_tweak((uint64_t*)&l0[idx0 & MASK], l0, idx0 & MASK, ax0, bx0, bx1, cx); + if (BASE == Algorithm::CN_1 || BASE == Algorithm::CN_2) { + cryptonight_monero_tweak(reinterpret_cast(&l0[idx0 & MASK]), l0, idx0 & MASK, ax0, bx0, bx1, cx); } else { - _mm_store_si128((__m128i *)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx)); + _mm_store_si128(reinterpret_cast<__m128i *>(&l0[idx0 & MASK]), _mm_xor_si128(bx0, cx)); } - idx0 = _mm_cvtsi128_si64(cx); + idx0 = static_cast(_mm_cvtsi128_si64(cx)); uint64_t hi, lo, cl, ch; - cl = ((uint64_t*) &l0[idx0 & MASK])[0]; - ch = ((uint64_t*) &l0[idx0 & MASK])[1]; + cl = (reinterpret_cast(&l0[idx0 & MASK]))[0]; + ch = (reinterpret_cast(&l0[idx0 & MASK]))[1]; - if (BASE == xmrig::VARIANT_2) { - if ((VARIANT == xmrig::VARIANT_WOW) || (VARIANT == xmrig::VARIANT_4)) { + if (BASE == Algorithm::CN_2) { + if (props.isR()) { VARIANT4_RANDOM_MATH(0, al0, ah0, cl, bx0, bx1); - if (VARIANT == xmrig::VARIANT_4) { - al0 ^= r0[2] | ((uint64_t)(r0[3]) << 32); - ah0 ^= r0[0] | ((uint64_t)(r0[1]) << 32); + if (ALGO == Algorithm::CN_R) { + al0 ^= r0[2] | (static_cast(r0[3]) << 32); + ah0 ^= r0[0] | (static_cast(r0[1]) << 32); } } else { VARIANT2_INTEGER_MATH(0, cl, cx); @@ -651,63 +645,67 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si lo = __umul128(idx0, cl, &hi); - if (BASE == xmrig::VARIANT_2) { - if (VARIANT == xmrig::VARIANT_4) { + if (BASE == Algorithm::CN_2) { + if (ALGO == Algorithm::CN_R) { VARIANT2_SHUFFLE(l0, idx0 & MASK, ax0, bx0, bx1, cx, 0); } else { - VARIANT2_SHUFFLE2(l0, idx0 & MASK, ax0, bx0, bx1, hi, lo, (VARIANT == xmrig::VARIANT_RWZ ? 1 : 0)); + VARIANT2_SHUFFLE2(l0, idx0 & MASK, ax0, bx0, bx1, hi, lo, (ALGO == Algorithm::CN_RWZ ? 1 : 0)); } } al0 += hi; ah0 += lo; - ((uint64_t*)&l0[idx0 & MASK])[0] = al0; + reinterpret_cast(&l0[idx0 & MASK])[0] = al0; - if (BASE == xmrig::VARIANT_1 && (VARIANT == xmrig::VARIANT_TUBE || VARIANT == xmrig::VARIANT_RTO)) { - ((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0 ^ al0; - } else if (BASE == xmrig::VARIANT_1) { - ((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0; + if (IS_CN_HEAVY_TUBE || ALGO == Algorithm::CN_RTO) { + reinterpret_cast(&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0 ^ al0; + } else if (BASE == Algorithm::CN_1) { + reinterpret_cast(&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0; } else { - ((uint64_t*)&l0[idx0 & MASK])[1] = ah0; + reinterpret_cast(&l0[idx0 & MASK])[1] = ah0; } al0 ^= cl; ah0 ^= ch; idx0 = al0; - if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { +# ifdef XMRIG_ALGO_CN_HEAVY + if (props.isHeavy()) { int64_t n = ((int64_t*)&l0[idx0 & MASK])[0]; int32_t d = ((int32_t*)&l0[idx0 & MASK])[2]; int64_t q = n / (d | 0x5); ((int64_t*)&l0[idx0 & MASK])[0] = n ^ q; - if (VARIANT == xmrig::VARIANT_XHV) { + if (ALGO == Algorithm::CN_HEAVY_XHV) { d = ~d; } idx0 = d ^ q; } +# endif - if (BASE == xmrig::VARIANT_2) { + if (BASE == Algorithm::CN_2) { bx1 = bx0; } bx0 = cx; } -#ifndef XMRIG_NO_ASM +# ifdef XMRIG_FEATURE_ASM } -#endif - - cn_implode_scratchpad((__m128i*) ctx[0]->memory, (__m128i*) ctx[0]->state); +# endif - xmrig::keccakf(h0, 24); + cn_implode_scratchpad(reinterpret_cast(ctx[0]->memory), reinterpret_cast<__m128i *>(ctx[0]->state)); + keccakf(h0, 24); extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output); } +} /* namespace xmrig */ + + #ifdef XMRIG_ALGO_CN_GPU template void cn_gpu_inner_avx(const uint8_t *spad, uint8_t *lpad); @@ -717,17 +715,41 @@ template void cn_gpu_inner_ssse3(const uint8_t *spad, uint8_t *lpad); -template -inline void cryptonight_single_hash_gpu(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx, uint64_t height) +namespace xmrig { + + +template +void cn_explode_scratchpad_gpu(const uint8_t *input, uint8_t *output) { - constexpr size_t MASK = xmrig::CRYPTONIGHT_GPU_MASK; - constexpr size_t ITERATIONS = xmrig::cn_select_iter(); - constexpr size_t MEM = xmrig::cn_select_memory(); + constexpr size_t hash_size = 200; // 25x8 bytes + alignas(16) uint64_t hash[25]; - static_assert(MASK > 0 && ITERATIONS > 0 && MEM > 0, "unsupported algorithm/variant"); + for (uint64_t i = 0; i < MEM / 512; i++) { + memcpy(hash, input, hash_size); + hash[0] ^= i; - xmrig::keccak(input, size, ctx[0]->state); - cn_explode_scratchpad_gpu(ctx[0]->state, ctx[0]->memory); + xmrig::keccakf(hash, 24); + memcpy(output, hash, 160); + output += 160; + + xmrig::keccakf(hash, 24); + memcpy(output, hash, 176); + output += 176; + + xmrig::keccakf(hash, 24); + memcpy(output, hash, 176); + output += 176; + } +} + + +template +inline void cryptonight_single_hash_gpu(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx, uint64_t) +{ + constexpr CnAlgo props; + + keccak(input, size, ctx[0]->state); + cn_explode_scratchpad_gpu(ctx[0]->state, ctx[0]->memory); # ifdef _MSC_VER _control87(RC_NEAR, MCW_RC); @@ -736,20 +758,22 @@ inline void cryptonight_single_hash_gpu(const uint8_t *__restrict__ input, size_ # endif if (xmrig::Cpu::info()->hasAVX2()) { - cn_gpu_inner_avx(ctx[0]->state, ctx[0]->memory); + cn_gpu_inner_avx(ctx[0]->state, ctx[0]->memory); } else { - cn_gpu_inner_ssse3(ctx[0]->state, ctx[0]->memory); + cn_gpu_inner_ssse3(ctx[0]->state, ctx[0]->memory); } - cn_implode_scratchpad((__m128i*) ctx[0]->memory, (__m128i*) ctx[0]->state); - - xmrig::keccakf((uint64_t*) ctx[0]->state, 24); + cn_implode_scratchpad(reinterpret_cast(ctx[0]->memory), reinterpret_cast<__m128i *>(ctx[0]->state)); + keccakf(reinterpret_cast(ctx[0]->state), 24); memcpy(output, ctx[0]->state, 32); } + + +} /* namespace xmrig */ #endif -#ifndef XMRIG_NO_ASM +#ifdef XMRIG_FEATURE_ASM extern "C" void cnv2_mainloop_ivybridge_asm(cryptonight_ctx **ctx); extern "C" void cnv2_mainloop_ryzen_asm(cryptonight_ctx **ctx); extern "C" void cnv2_mainloop_bulldozer_asm(cryptonight_ctx **ctx); @@ -757,212 +781,243 @@ extern "C" void cnv2_double_mainloop_sandybridge_asm(cryptonight_ctx **ctx); extern "C" void cnv2_rwz_mainloop_asm(cryptonight_ctx **ctx); extern "C" void cnv2_rwz_double_mainloop_asm(cryptonight_ctx **ctx); -extern xmrig::CpuThread::cn_mainloop_fun cn_half_mainloop_ivybridge_asm; -extern xmrig::CpuThread::cn_mainloop_fun cn_half_mainloop_ryzen_asm; -extern xmrig::CpuThread::cn_mainloop_fun cn_half_mainloop_bulldozer_asm; -extern xmrig::CpuThread::cn_mainloop_fun cn_half_double_mainloop_sandybridge_asm; -extern xmrig::CpuThread::cn_mainloop_fun cn_trtl_mainloop_ivybridge_asm; -extern xmrig::CpuThread::cn_mainloop_fun cn_trtl_mainloop_ryzen_asm; -extern xmrig::CpuThread::cn_mainloop_fun cn_trtl_mainloop_bulldozer_asm; -extern xmrig::CpuThread::cn_mainloop_fun cn_trtl_double_mainloop_sandybridge_asm; +namespace xmrig { -extern xmrig::CpuThread::cn_mainloop_fun cn_zls_mainloop_ivybridge_asm; -extern xmrig::CpuThread::cn_mainloop_fun cn_zls_mainloop_ryzen_asm; -extern xmrig::CpuThread::cn_mainloop_fun cn_zls_mainloop_bulldozer_asm; -extern xmrig::CpuThread::cn_mainloop_fun cn_zls_double_mainloop_sandybridge_asm; -extern xmrig::CpuThread::cn_mainloop_fun cn_double_mainloop_ivybridge_asm; -extern xmrig::CpuThread::cn_mainloop_fun cn_double_mainloop_ryzen_asm; -extern xmrig::CpuThread::cn_mainloop_fun cn_double_mainloop_bulldozer_asm; -extern xmrig::CpuThread::cn_mainloop_fun cn_double_double_mainloop_sandybridge_asm; +extern cn_mainloop_fun cn_half_mainloop_ivybridge_asm; +extern cn_mainloop_fun cn_half_mainloop_ryzen_asm; +extern cn_mainloop_fun cn_half_mainloop_bulldozer_asm; +extern cn_mainloop_fun cn_half_double_mainloop_sandybridge_asm; + +extern cn_mainloop_fun cn_trtl_mainloop_ivybridge_asm; +extern cn_mainloop_fun cn_trtl_mainloop_ryzen_asm; +extern cn_mainloop_fun cn_trtl_mainloop_bulldozer_asm; +extern cn_mainloop_fun cn_trtl_double_mainloop_sandybridge_asm; + +extern cn_mainloop_fun cn_zls_mainloop_ivybridge_asm; +extern cn_mainloop_fun cn_zls_mainloop_ryzen_asm; +extern cn_mainloop_fun cn_zls_mainloop_bulldozer_asm; +extern cn_mainloop_fun cn_zls_double_mainloop_sandybridge_asm; + +extern cn_mainloop_fun cn_double_mainloop_ivybridge_asm; +extern cn_mainloop_fun cn_double_mainloop_ryzen_asm; +extern cn_mainloop_fun cn_double_mainloop_bulldozer_asm; +extern cn_mainloop_fun cn_double_double_mainloop_sandybridge_asm; + + +} // namespace xmrig + void wow_compile_code(const V4_Instruction* code, int code_size, void* machine_code, xmrig::Assembly ASM); void v4_compile_code(const V4_Instruction* code, int code_size, void* machine_code, xmrig::Assembly ASM); void wow_compile_code_double(const V4_Instruction* code, int code_size, void* machine_code, xmrig::Assembly ASM); void v4_compile_code_double(const V4_Instruction* code, int code_size, void* machine_code, xmrig::Assembly ASM); -template + +template void cn_r_compile_code(const V4_Instruction* code, int code_size, void* machine_code, xmrig::Assembly ASM) { v4_compile_code(code, code_size, machine_code, ASM); } -template + +template void cn_r_compile_code_double(const V4_Instruction* code, int code_size, void* machine_code, xmrig::Assembly ASM) { v4_compile_code_double(code, code_size, machine_code, ASM); } + template<> -void cn_r_compile_code(const V4_Instruction* code, int code_size, void* machine_code, xmrig::Assembly ASM) +void cn_r_compile_code(const V4_Instruction* code, int code_size, void* machine_code, xmrig::Assembly ASM) { wow_compile_code(code, code_size, machine_code, ASM); } + template<> -void cn_r_compile_code_double(const V4_Instruction* code, int code_size, void* machine_code, xmrig::Assembly ASM) +void cn_r_compile_code_double(const V4_Instruction* code, int code_size, void* machine_code, xmrig::Assembly ASM) { wow_compile_code_double(code, code_size, machine_code, ASM); } -template + +namespace xmrig { + + +template inline void cryptonight_single_hash_asm(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx, uint64_t height) { - constexpr size_t MEM = xmrig::cn_select_memory(); + constexpr CnAlgo props; - if (xmrig::cn_is_cryptonight_r() && !ctx[0]->generated_code_data.match(VARIANT, height)) { + if (props.isR() && !ctx[0]->generated_code_data.match(ALGO, height)) { V4_Instruction code[256]; - const int code_size = v4_random_math_init(code, height); - cn_r_compile_code(code, code_size, reinterpret_cast(ctx[0]->generated_code), ASM); - ctx[0]->generated_code_data.variant = VARIANT; - ctx[0]->generated_code_data.height = height; + const int code_size = v4_random_math_init(code, height); + cn_r_compile_code(code, code_size, reinterpret_cast(ctx[0]->generated_code), ASM); + + ctx[0]->generated_code_data = { ALGO, height }; } - xmrig::keccak(input, size, ctx[0]->state); - cn_explode_scratchpad(reinterpret_cast<__m128i*>(ctx[0]->state), reinterpret_cast<__m128i*>(ctx[0]->memory)); + keccak(input, size, ctx[0]->state); + cn_explode_scratchpad(reinterpret_cast(ctx[0]->state), reinterpret_cast<__m128i*>(ctx[0]->memory)); - if (VARIANT == xmrig::VARIANT_2) { - if (ASM == xmrig::ASM_INTEL) { + if (ALGO == Algorithm::CN_2) { + if (ASM == ASM_INTEL) { cnv2_mainloop_ivybridge_asm(ctx); } - else if (ASM == xmrig::ASM_RYZEN) { + else if (ASM == ASM_RYZEN) { cnv2_mainloop_ryzen_asm(ctx); } else { cnv2_mainloop_bulldozer_asm(ctx); } } - else if (VARIANT == xmrig::VARIANT_HALF) { - if (ASM == xmrig::ASM_INTEL) { + else if (ALGO == Algorithm::CN_HALF) { + if (ASM == ASM_INTEL) { cn_half_mainloop_ivybridge_asm(ctx); } - else if (ASM == xmrig::ASM_RYZEN) { + else if (ASM == ASM_RYZEN) { cn_half_mainloop_ryzen_asm(ctx); } else { cn_half_mainloop_bulldozer_asm(ctx); } } - else if (VARIANT == xmrig::VARIANT_TRTL) { - if (ASM == xmrig::ASM_INTEL) { +# ifdef XMRIG_ALGO_CN_PICO + else if (ALGO == Algorithm::CN_PICO_0) { + if (ASM == ASM_INTEL) { cn_trtl_mainloop_ivybridge_asm(ctx); } - else if (ASM == xmrig::ASM_RYZEN) { + else if (ASM == ASM_RYZEN) { cn_trtl_mainloop_ryzen_asm(ctx); } else { cn_trtl_mainloop_bulldozer_asm(ctx); } } - else if (VARIANT == xmrig::VARIANT_RWZ) { +# endif + else if (ALGO == Algorithm::CN_RWZ) { cnv2_rwz_mainloop_asm(ctx); } - else if (VARIANT == xmrig::VARIANT_ZLS) { - if (ASM == xmrig::ASM_INTEL) { + else if (ALGO == Algorithm::CN_ZLS) { + if (ASM == ASM_INTEL) { cn_zls_mainloop_ivybridge_asm(ctx); } - else if (ASM == xmrig::ASM_RYZEN) { + else if (ASM == ASM_RYZEN) { cn_zls_mainloop_ryzen_asm(ctx); } else { cn_zls_mainloop_bulldozer_asm(ctx); } } - else if (VARIANT == xmrig::VARIANT_DOUBLE) { - if (ASM == xmrig::ASM_INTEL) { + else if (ALGO == Algorithm::CN_DOUBLE) { + if (ASM == ASM_INTEL) { cn_double_mainloop_ivybridge_asm(ctx); } - else if (ASM == xmrig::ASM_RYZEN) { + else if (ASM == ASM_RYZEN) { cn_double_mainloop_ryzen_asm(ctx); } else { cn_double_mainloop_bulldozer_asm(ctx); } } - else if (xmrig::cn_is_cryptonight_r()) { + else if (props.isR()) { ctx[0]->generated_code(ctx); } - cn_implode_scratchpad(reinterpret_cast<__m128i*>(ctx[0]->memory), reinterpret_cast<__m128i*>(ctx[0]->state)); - xmrig::keccakf(reinterpret_cast(ctx[0]->state), 24); + cn_implode_scratchpad(reinterpret_cast(ctx[0]->memory), reinterpret_cast<__m128i*>(ctx[0]->state)); + keccakf(reinterpret_cast(ctx[0]->state), 24); extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output); } -template +template inline void cryptonight_double_hash_asm(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx, uint64_t height) { - constexpr size_t MEM = xmrig::cn_select_memory(); + constexpr CnAlgo props; - if (xmrig::cn_is_cryptonight_r() && !ctx[0]->generated_code_data.match(VARIANT, height)) { + if (props.isR() && !ctx[0]->generated_code_data.match(ALGO, height)) { V4_Instruction code[256]; - const int code_size = v4_random_math_init(code, height); - cn_r_compile_code_double(code, code_size, reinterpret_cast(ctx[0]->generated_code), ASM); - ctx[0]->generated_code_data.variant = VARIANT; - ctx[0]->generated_code_data.height = height; + const int code_size = v4_random_math_init(code, height); + cn_r_compile_code_double(code, code_size, reinterpret_cast(ctx[0]->generated_code), ASM); + + ctx[0]->generated_code_data = { ALGO, height }; } - xmrig::keccak(input, size, ctx[0]->state); - xmrig::keccak(input + size, size, ctx[1]->state); + keccak(input, size, ctx[0]->state); + keccak(input + size, size, ctx[1]->state); - cn_explode_scratchpad(reinterpret_cast<__m128i*>(ctx[0]->state), reinterpret_cast<__m128i*>(ctx[0]->memory)); - cn_explode_scratchpad(reinterpret_cast<__m128i*>(ctx[1]->state), reinterpret_cast<__m128i*>(ctx[1]->memory)); + cn_explode_scratchpad(reinterpret_cast(ctx[0]->state), reinterpret_cast<__m128i*>(ctx[0]->memory)); + cn_explode_scratchpad(reinterpret_cast(ctx[1]->state), reinterpret_cast<__m128i*>(ctx[1]->memory)); - if (VARIANT == xmrig::VARIANT_2) { + if (ALGO == Algorithm::CN_2) { cnv2_double_mainloop_sandybridge_asm(ctx); } - else if (VARIANT == xmrig::VARIANT_HALF) { + else if (ALGO == Algorithm::CN_HALF) { cn_half_double_mainloop_sandybridge_asm(ctx); } - else if (VARIANT == xmrig::VARIANT_TRTL) { +# ifdef XMRIG_ALGO_CN_PICO + else if (ALGO == Algorithm::CN_PICO_0) { cn_trtl_double_mainloop_sandybridge_asm(ctx); } - else if (VARIANT == xmrig::VARIANT_RWZ) { +# endif + else if (ALGO == Algorithm::CN_RWZ) { cnv2_rwz_double_mainloop_asm(ctx); } - else if (VARIANT == xmrig::VARIANT_ZLS) { + else if (ALGO == Algorithm::CN_ZLS) { cn_zls_double_mainloop_sandybridge_asm(ctx); } - else if (VARIANT == xmrig::VARIANT_DOUBLE) { + else if (ALGO == Algorithm::CN_DOUBLE) { cn_double_double_mainloop_sandybridge_asm(ctx); } - else if (xmrig::cn_is_cryptonight_r()) { + else if (props.isR()) { ctx[0]->generated_code(ctx); } - cn_implode_scratchpad(reinterpret_cast<__m128i*>(ctx[0]->memory), reinterpret_cast<__m128i*>(ctx[0]->state)); - cn_implode_scratchpad(reinterpret_cast<__m128i*>(ctx[1]->memory), reinterpret_cast<__m128i*>(ctx[1]->state)); + cn_implode_scratchpad(reinterpret_cast(ctx[0]->memory), reinterpret_cast<__m128i*>(ctx[0]->state)); + cn_implode_scratchpad(reinterpret_cast(ctx[1]->memory), reinterpret_cast<__m128i*>(ctx[1]->state)); - xmrig::keccakf(reinterpret_cast(ctx[0]->state), 24); - xmrig::keccakf(reinterpret_cast(ctx[1]->state), 24); + keccakf(reinterpret_cast(ctx[0]->state), 24); + keccakf(reinterpret_cast(ctx[1]->state), 24); extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output); extra_hashes[ctx[1]->state[0] & 3](ctx[1]->state, 200, output + 32); } + + +} /* namespace xmrig */ #endif -template +namespace xmrig { + + +template inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx, uint64_t height) { - constexpr size_t MASK = xmrig::cn_select_mask(); - constexpr size_t ITERATIONS = xmrig::cn_select_iter(); - constexpr size_t MEM = xmrig::cn_select_memory(); - constexpr xmrig::Variant BASE = xmrig::cn_base_variant(); + constexpr CnAlgo props; + constexpr size_t MASK = props.mask(); + constexpr Algorithm::Id BASE = props.base(); - if (BASE == xmrig::VARIANT_1 && size < 43) { +# ifdef XMRIG_ALGO_CN_HEAVY + constexpr bool IS_CN_HEAVY_TUBE = ALGO == Algorithm::CN_HEAVY_TUBE; +# else + constexpr bool IS_CN_HEAVY_TUBE = false; +# endif + + if (BASE == Algorithm::CN_1 && size < 43) { memset(output, 0, 64); return; } - xmrig::keccak(input, size, ctx[0]->state); - xmrig::keccak(input + size, size, ctx[1]->state); + keccak(input, size, ctx[0]->state); + keccak(input + size, size, ctx[1]->state); - const uint8_t* l0 = ctx[0]->memory; - const uint8_t* l1 = ctx[1]->memory; - uint64_t* h0 = reinterpret_cast(ctx[0]->state); - uint64_t* h1 = reinterpret_cast(ctx[1]->state); + uint8_t *l0 = ctx[0]->memory; + uint8_t *l1 = ctx[1]->memory; + uint64_t *h0 = reinterpret_cast(ctx[0]->state); + uint64_t *h1 = reinterpret_cast(ctx[1]->state); VARIANT1_INIT(0); VARIANT1_INIT(1); @@ -972,8 +1027,8 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si VARIANT4_RANDOM_MATH_INIT(0); VARIANT4_RANDOM_MATH_INIT(1); - cn_explode_scratchpad((__m128i*) h0, (__m128i*) l0); - cn_explode_scratchpad((__m128i*) h1, (__m128i*) l1); + cn_explode_scratchpad(reinterpret_cast(h0), reinterpret_cast<__m128i *>(l0)); + cn_explode_scratchpad(reinterpret_cast(h1), reinterpret_cast<__m128i *>(l1)); uint64_t al0 = h0[0] ^ h0[4]; uint64_t al1 = h1[0] ^ h1[4]; @@ -988,31 +1043,31 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si uint64_t idx0 = al0; uint64_t idx1 = al1; - for (size_t i = 0; i < ITERATIONS; i++) { + for (size_t i = 0; i < props.iterations(); i++) { __m128i cx0, cx1; - if (VARIANT == xmrig::VARIANT_TUBE || !SOFT_AES) { - cx0 = _mm_load_si128((__m128i *) &l0[idx0 & MASK]); - cx1 = _mm_load_si128((__m128i *) &l1[idx1 & MASK]); + if (IS_CN_HEAVY_TUBE || !SOFT_AES) { + cx0 = _mm_load_si128(reinterpret_cast(&l0[idx0 & MASK])); + cx1 = _mm_load_si128(reinterpret_cast(&l1[idx1 & MASK])); } const __m128i ax0 = _mm_set_epi64x(ah0, al0); const __m128i ax1 = _mm_set_epi64x(ah1, al1); - if (VARIANT == xmrig::VARIANT_TUBE) { + if (IS_CN_HEAVY_TUBE) { cx0 = aes_round_tweak_div(cx0, ax0); cx1 = aes_round_tweak_div(cx1, ax1); } else if (SOFT_AES) { - cx0 = soft_aesenc((uint32_t*)&l0[idx0 & MASK], ax0, (const uint32_t*)saes_table); - cx1 = soft_aesenc((uint32_t*)&l1[idx1 & MASK], ax1, (const uint32_t*)saes_table); + cx0 = soft_aesenc(&l0[idx0 & MASK], ax0, reinterpret_cast(saes_table)); + cx1 = soft_aesenc(&l1[idx1 & MASK], ax1, reinterpret_cast(saes_table)); } else { cx0 = _mm_aesenc_si128(cx0, ax0); cx1 = _mm_aesenc_si128(cx1, ax1); } - if (BASE == xmrig::VARIANT_1 || (BASE == xmrig::VARIANT_2)) { - cryptonight_monero_tweak((uint64_t*)&l0[idx0 & MASK], l0, idx0 & MASK, ax0, bx00, bx01, cx0); - cryptonight_monero_tweak((uint64_t*)&l1[idx1 & MASK], l1, idx1 & MASK, ax1, bx10, bx11, cx1); + if (BASE == Algorithm::CN_1 || BASE == Algorithm::CN_2) { + cryptonight_monero_tweak((uint64_t*)&l0[idx0 & MASK], l0, idx0 & MASK, ax0, bx00, bx01, cx0); + cryptonight_monero_tweak((uint64_t*)&l1[idx1 & MASK], l1, idx1 & MASK, ax1, bx10, bx11, cx1); } else { _mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx00, cx0)); _mm_store_si128((__m128i *) &l1[idx1 & MASK], _mm_xor_si128(bx10, cx1)); @@ -1025,10 +1080,10 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si cl = ((uint64_t*) &l0[idx0 & MASK])[0]; ch = ((uint64_t*) &l0[idx0 & MASK])[1]; - if (BASE == xmrig::VARIANT_2) { - if ((VARIANT == xmrig::VARIANT_WOW) || (VARIANT == xmrig::VARIANT_4)) { + if (BASE == Algorithm::CN_2) { + if (props.isR()) { VARIANT4_RANDOM_MATH(0, al0, ah0, cl, bx00, bx01); - if (VARIANT == xmrig::VARIANT_4) { + if (ALGO == Algorithm::CN_R) { al0 ^= r0[2] | ((uint64_t)(r0[3]) << 32); ah0 ^= r0[0] | ((uint64_t)(r0[1]) << 32); } @@ -1039,11 +1094,11 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si lo = __umul128(idx0, cl, &hi); - if (BASE == xmrig::VARIANT_2) { - if (VARIANT == xmrig::VARIANT_4) { + if (BASE == Algorithm::CN_2) { + if (ALGO == Algorithm::CN_R) { VARIANT2_SHUFFLE(l0, idx0 & MASK, ax0, bx00, bx01, cx0, 0); } else { - VARIANT2_SHUFFLE2(l0, idx0 & MASK, ax0, bx00, bx01, hi, lo, (VARIANT == xmrig::VARIANT_RWZ ? 1 : 0)); + VARIANT2_SHUFFLE2(l0, idx0 & MASK, ax0, bx00, bx01, hi, lo, (ALGO == Algorithm::CN_RWZ ? 1 : 0)); } } @@ -1052,9 +1107,9 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si ((uint64_t*)&l0[idx0 & MASK])[0] = al0; - if (BASE == xmrig::VARIANT_1 && (VARIANT == xmrig::VARIANT_TUBE || VARIANT == xmrig::VARIANT_RTO)) { + if (IS_CN_HEAVY_TUBE || ALGO == Algorithm::CN_RTO) { ((uint64_t*) &l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0 ^ al0; - } else if (BASE == xmrig::VARIANT_1) { + } else if (BASE == Algorithm::CN_1) { ((uint64_t*) &l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0; } else { ((uint64_t*) &l0[idx0 & MASK])[1] = ah0; @@ -1064,27 +1119,29 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si ah0 ^= ch; idx0 = al0; - if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { +# ifdef XMRIG_ALGO_CN_HEAVY + if (props.isHeavy()) { int64_t n = ((int64_t*)&l0[idx0 & MASK])[0]; int32_t d = ((int32_t*)&l0[idx0 & MASK])[2]; int64_t q = n / (d | 0x5); ((int64_t*)&l0[idx0 & MASK])[0] = n ^ q; - if (VARIANT == xmrig::VARIANT_XHV) { + if (ALGO == Algorithm::CN_HEAVY_XHV) { d = ~d; } idx0 = d ^ q; } +# endif cl = ((uint64_t*) &l1[idx1 & MASK])[0]; ch = ((uint64_t*) &l1[idx1 & MASK])[1]; - if (BASE == xmrig::VARIANT_2) { - if ((VARIANT == xmrig::VARIANT_WOW) || (VARIANT == xmrig::VARIANT_4)) { + if (BASE == Algorithm::CN_2) { + if (props.isR()) { VARIANT4_RANDOM_MATH(1, al1, ah1, cl, bx10, bx11); - if (VARIANT == xmrig::VARIANT_4) { + if (ALGO == Algorithm::CN_R) { al1 ^= r1[2] | ((uint64_t)(r1[3]) << 32); ah1 ^= r1[0] | ((uint64_t)(r1[1]) << 32); } @@ -1095,11 +1152,11 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si lo = __umul128(idx1, cl, &hi); - if (BASE == xmrig::VARIANT_2) { - if (VARIANT == xmrig::VARIANT_4) { + if (BASE == Algorithm::CN_2) { + if (ALGO == Algorithm::CN_R) { VARIANT2_SHUFFLE(l1, idx1 & MASK, ax1, bx10, bx11, cx1, 0); } else { - VARIANT2_SHUFFLE2(l1, idx1 & MASK, ax1, bx10, bx11, hi, lo, (VARIANT == xmrig::VARIANT_RWZ ? 1 : 0)); + VARIANT2_SHUFFLE2(l1, idx1 & MASK, ax1, bx10, bx11, hi, lo, (ALGO == Algorithm::CN_RWZ ? 1 : 0)); } } @@ -1108,9 +1165,9 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si ((uint64_t*)&l1[idx1 & MASK])[0] = al1; - if (BASE == xmrig::VARIANT_1 && (VARIANT == xmrig::VARIANT_TUBE || VARIANT == xmrig::VARIANT_RTO)) { + if (IS_CN_HEAVY_TUBE || ALGO == Algorithm::CN_RTO) { ((uint64_t*)&l1[idx1 & MASK])[1] = ah1 ^ tweak1_2_1 ^ al1; - } else if (BASE == xmrig::VARIANT_1) { + } else if (BASE == Algorithm::CN_1) { ((uint64_t*)&l1[idx1 & MASK])[1] = ah1 ^ tweak1_2_1; } else { ((uint64_t*)&l1[idx1 & MASK])[1] = ah1; @@ -1120,21 +1177,23 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si ah1 ^= ch; idx1 = al1; - if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { +# ifdef XMRIG_ALGO_CN_HEAVY + if (props.isHeavy()) { int64_t n = ((int64_t*)&l1[idx1 & MASK])[0]; int32_t d = ((int32_t*)&l1[idx1 & MASK])[2]; int64_t q = n / (d | 0x5); ((int64_t*)&l1[idx1 & MASK])[0] = n ^ q; - if (VARIANT == xmrig::VARIANT_XHV) { + if (ALGO == Algorithm::CN_HEAVY_XHV) { d = ~d; } idx1 = d ^ q; } +# endif - if (BASE == xmrig::VARIANT_2) { + if (BASE == Algorithm::CN_2) { bx01 = bx00; bx11 = bx10; } @@ -1143,11 +1202,11 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si bx10 = cx1; } - cn_implode_scratchpad((__m128i*) l0, (__m128i*) h0); - cn_implode_scratchpad((__m128i*) l1, (__m128i*) h1); + cn_implode_scratchpad(reinterpret_cast(l0), reinterpret_cast<__m128i *>(h0)); + cn_implode_scratchpad(reinterpret_cast(l1), reinterpret_cast<__m128i *>(h1)); - xmrig::keccakf(h0, 24); - xmrig::keccakf(h1, 24); + keccakf(h0, 24); + keccakf(h1, 24); extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output); extra_hashes[ctx[1]->state[0] & 3](ctx[1]->state, 200, output + 32); @@ -1159,20 +1218,20 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si c = _mm_load_si128(ptr); -#define CN_STEP2(a, b0, b1, c, l, ptr, idx) \ - if (VARIANT == xmrig::VARIANT_TUBE) { \ - c = aes_round_tweak_div(c, a); \ - } \ - else if (SOFT_AES) { \ - c = soft_aesenc(&c, a, (const uint32_t*)saes_table); \ - } else { \ - c = _mm_aesenc_si128(c, a); \ - } \ - \ - if (BASE == xmrig::VARIANT_1 || BASE == xmrig::VARIANT_2) { \ - cryptonight_monero_tweak((uint64_t*)ptr, l, idx & MASK, a, b0, b1, c); \ - } else { \ - _mm_store_si128(ptr, _mm_xor_si128(b0, c)); \ +#define CN_STEP2(a, b0, b1, c, l, ptr, idx) \ + if (IS_CN_HEAVY_TUBE) { \ + c = aes_round_tweak_div(c, a); \ + } \ + else if (SOFT_AES) { \ + c = soft_aesenc(&c, a, (const uint32_t*)saes_table); \ + } else { \ + c = _mm_aesenc_si128(c, a); \ + } \ + \ + if (BASE == Algorithm::CN_1 || BASE == Algorithm::CN_2) { \ + cryptonight_monero_tweak((uint64_t*)ptr, l, idx & MASK, a, b0, b1, c); \ + } else { \ + _mm_store_si128(ptr, _mm_xor_si128(b0, c)); \ } @@ -1183,62 +1242,60 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si uint64_t ch##part = ((uint64_t*)ptr)[1]; -#define CN_STEP4(part, a, b0, b1, c, l, mc, ptr, idx) \ - uint64_t al##part, ah##part; \ - if (BASE == xmrig::VARIANT_2) { \ - if ((VARIANT == xmrig::VARIANT_WOW) || (VARIANT == xmrig::VARIANT_4)) { \ - al##part = _mm_cvtsi128_si64(a); \ - ah##part = _mm_cvtsi128_si64(_mm_srli_si128(a, 8)); \ - VARIANT4_RANDOM_MATH(part, al##part, ah##part, cl##part, b0, b1); \ - if (VARIANT == xmrig::VARIANT_4) { \ - al##part ^= r##part[2] | ((uint64_t)(r##part[3]) << 32); \ - ah##part ^= r##part[0] | ((uint64_t)(r##part[1]) << 32); \ - } \ - } else { \ - VARIANT2_INTEGER_MATH(part, cl##part, c); \ - } \ - } \ - lo = __umul128(idx, cl##part, &hi); \ - if (BASE == xmrig::VARIANT_2) { \ - if (VARIANT == xmrig::VARIANT_4) { \ - VARIANT2_SHUFFLE(l, idx & MASK, a, b0, b1, c, 0); \ - } else { \ - VARIANT2_SHUFFLE2(l, idx & MASK, a, b0, b1, hi, lo, (VARIANT == xmrig::VARIANT_RWZ ? 1 : 0)); \ - } \ - } \ - if (VARIANT == xmrig::VARIANT_4) { \ - a = _mm_set_epi64x(ah##part, al##part); \ - } \ - a = _mm_add_epi64(a, _mm_set_epi64x(lo, hi)); \ - \ - if (BASE == xmrig::VARIANT_1) { \ - _mm_store_si128(ptr, _mm_xor_si128(a, mc)); \ - \ - if (VARIANT == xmrig::VARIANT_TUBE || \ - VARIANT == xmrig::VARIANT_RTO) { \ - ((uint64_t*)ptr)[1] ^= ((uint64_t*)ptr)[0]; \ - } \ - } else { \ - _mm_store_si128(ptr, a); \ - } \ - \ - a = _mm_xor_si128(a, _mm_set_epi64x(ch##part, cl##part)); \ - idx = _mm_cvtsi128_si64(a); \ - \ - if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { \ - int64_t n = ((int64_t*)&l[idx & MASK])[0]; \ - int32_t d = ((int32_t*)&l[idx & MASK])[2]; \ - int64_t q = n / (d | 0x5); \ - ((int64_t*)&l[idx & MASK])[0] = n ^ q; \ - if (VARIANT == xmrig::VARIANT_XHV) { \ - d = ~d; \ - } \ - \ - idx = d ^ q; \ - } \ - if (BASE == xmrig::VARIANT_2) { \ - b1 = b0; \ - } \ +#define CN_STEP4(part, a, b0, b1, c, l, mc, ptr, idx) \ + uint64_t al##part, ah##part; \ + if (BASE == Algorithm::CN_2) { \ + if (props.isR()) { \ + al##part = _mm_cvtsi128_si64(a); \ + ah##part = _mm_cvtsi128_si64(_mm_srli_si128(a, 8)); \ + VARIANT4_RANDOM_MATH(part, al##part, ah##part, cl##part, b0, b1); \ + if (ALGO == Algorithm::CN_R) { \ + al##part ^= r##part[2] | ((uint64_t)(r##part[3]) << 32); \ + ah##part ^= r##part[0] | ((uint64_t)(r##part[1]) << 32); \ + } \ + } else { \ + VARIANT2_INTEGER_MATH(part, cl##part, c); \ + } \ + } \ + lo = __umul128(idx, cl##part, &hi); \ + if (BASE == Algorithm::CN_2) { \ + if (ALGO == Algorithm::CN_R) { \ + VARIANT2_SHUFFLE(l, idx & MASK, a, b0, b1, c, 0); \ + } else { \ + VARIANT2_SHUFFLE2(l, idx & MASK, a, b0, b1, hi, lo, (ALGO == Algorithm::CN_RWZ ? 1 : 0)); \ + } \ + } \ + if (ALGO == Algorithm::CN_R) { \ + a = _mm_set_epi64x(ah##part, al##part); \ + } \ + a = _mm_add_epi64(a, _mm_set_epi64x(lo, hi)); \ + \ + if (BASE == Algorithm::CN_1) { \ + _mm_store_si128(ptr, _mm_xor_si128(a, mc)); \ + \ + if (IS_CN_HEAVY_TUBE || ALGO == Algorithm::CN_RTO) { \ + ((uint64_t*)ptr)[1] ^= ((uint64_t*)ptr)[0]; \ + } \ + } else { \ + _mm_store_si128(ptr, a); \ + } \ + \ + a = _mm_xor_si128(a, _mm_set_epi64x(ch##part, cl##part)); \ + idx = _mm_cvtsi128_si64(a); \ + if (props.isHeavy()) { \ + int64_t n = ((int64_t*)&l[idx & MASK])[0]; \ + int32_t d = ((int32_t*)&l[idx & MASK])[2]; \ + int64_t q = n / (d | 0x5); \ + ((int64_t*)&l[idx & MASK])[0] = n ^ q; \ + if (IS_CN_HEAVY_XHV) { \ + d = ~d; \ + } \ + \ + idx = d ^ q; \ + } \ + if (BASE == Algorithm::CN_2) { \ + b1 = b0; \ + } \ b0 = c; @@ -1246,11 +1303,11 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si __m128i mc##n; \ __m128i division_result_xmm_##n; \ __m128i sqrt_result_xmm_##n; \ - if (BASE == xmrig::VARIANT_1) { \ + if (BASE == Algorithm::CN_1) { \ mc##n = _mm_set_epi64x(*reinterpret_cast(input + n * size + 35) ^ \ *(reinterpret_cast((ctx)->state) + 24), 0); \ } \ - if (BASE == xmrig::VARIANT_2) { \ + if (BASE == Algorithm::CN_2) { \ division_result_xmm_##n = _mm_cvtsi64_si128(h##n[12]); \ sqrt_result_xmm_##n = _mm_cvtsi64_si128(h##n[13]); \ } \ @@ -1261,22 +1318,29 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si VARIANT4_RANDOM_MATH_INIT(n); -template +template inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx, uint64_t height) { - constexpr size_t MASK = xmrig::cn_select_mask(); - constexpr size_t ITERATIONS = xmrig::cn_select_iter(); - constexpr size_t MEM = xmrig::cn_select_memory(); - constexpr xmrig::Variant BASE = xmrig::cn_base_variant(); + constexpr CnAlgo props; + constexpr size_t MASK = props.mask(); + constexpr Algorithm::Id BASE = props.base(); - if (BASE == xmrig::VARIANT_1 && size < 43) { +# ifdef XMRIG_ALGO_CN_HEAVY + constexpr bool IS_CN_HEAVY_TUBE = ALGO == Algorithm::CN_HEAVY_TUBE; + constexpr bool IS_CN_HEAVY_XHV = ALGO == Algorithm::CN_HEAVY_XHV; +# else + constexpr bool IS_CN_HEAVY_TUBE = false; + constexpr bool IS_CN_HEAVY_XHV = false; +# endif + + if (BASE == Algorithm::CN_1 && size < 43) { memset(output, 0, 32 * 3); return; } for (size_t i = 0; i < 3; i++) { - xmrig::keccak(input + size * i, size, ctx[i]->state); - cn_explode_scratchpad(reinterpret_cast<__m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory)); + keccak(input + size * i, size, ctx[i]->state); + cn_explode_scratchpad(reinterpret_cast(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory)); } uint8_t* l0 = ctx[0]->memory; @@ -1296,7 +1360,7 @@ inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t si idx1 = _mm_cvtsi128_si64(ax1); idx2 = _mm_cvtsi128_si64(ax2); - for (size_t i = 0; i < ITERATIONS; i++) { + for (size_t i = 0; i < props.iterations(); i++) { uint64_t hi, lo; __m128i *ptr0, *ptr1, *ptr2; @@ -1318,29 +1382,36 @@ inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t si } for (size_t i = 0; i < 3; i++) { - cn_implode_scratchpad(reinterpret_cast<__m128i*>(ctx[i]->memory), reinterpret_cast<__m128i*>(ctx[i]->state)); - xmrig::keccakf(reinterpret_cast(ctx[i]->state), 24); + cn_implode_scratchpad(reinterpret_cast(ctx[i]->memory), reinterpret_cast<__m128i*>(ctx[i]->state)); + keccakf(reinterpret_cast(ctx[i]->state), 24); extra_hashes[ctx[i]->state[0] & 3](ctx[i]->state, 200, output + 32 * i); } } -template +template inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx, uint64_t height) { - constexpr size_t MASK = xmrig::cn_select_mask(); - constexpr size_t ITERATIONS = xmrig::cn_select_iter(); - constexpr size_t MEM = xmrig::cn_select_memory(); - constexpr xmrig::Variant BASE = xmrig::cn_base_variant(); + constexpr CnAlgo props; + constexpr size_t MASK = props.mask(); + constexpr Algorithm::Id BASE = props.base(); - if (BASE == xmrig::VARIANT_1 && size < 43) { +# ifdef XMRIG_ALGO_CN_HEAVY + constexpr bool IS_CN_HEAVY_TUBE = ALGO == Algorithm::CN_HEAVY_TUBE; + constexpr bool IS_CN_HEAVY_XHV = ALGO == Algorithm::CN_HEAVY_XHV; +# else + constexpr bool IS_CN_HEAVY_TUBE = false; + constexpr bool IS_CN_HEAVY_XHV = false; +# endif + + if (BASE == Algorithm::CN_1 && size < 43) { memset(output, 0, 32 * 4); return; } for (size_t i = 0; i < 4; i++) { - xmrig::keccak(input + size * i, size, ctx[i]->state); - cn_explode_scratchpad(reinterpret_cast<__m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory)); + keccak(input + size * i, size, ctx[i]->state); + cn_explode_scratchpad(reinterpret_cast(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory)); } uint8_t* l0 = ctx[0]->memory; @@ -1364,8 +1435,7 @@ inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size idx2 = _mm_cvtsi128_si64(ax2); idx3 = _mm_cvtsi128_si64(ax3); - for (size_t i = 0; i < ITERATIONS; i++) - { + for (size_t i = 0; i < props.iterations(); i++) { uint64_t hi, lo; __m128i *ptr0, *ptr1, *ptr2, *ptr3; @@ -1391,29 +1461,36 @@ inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size } for (size_t i = 0; i < 4; i++) { - cn_implode_scratchpad(reinterpret_cast<__m128i*>(ctx[i]->memory), reinterpret_cast<__m128i*>(ctx[i]->state)); - xmrig::keccakf(reinterpret_cast(ctx[i]->state), 24); + cn_implode_scratchpad(reinterpret_cast(ctx[i]->memory), reinterpret_cast<__m128i*>(ctx[i]->state)); + keccakf(reinterpret_cast(ctx[i]->state), 24); extra_hashes[ctx[i]->state[0] & 3](ctx[i]->state, 200, output + 32 * i); } } -template +template inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx, uint64_t height) { - constexpr size_t MASK = xmrig::cn_select_mask(); - constexpr size_t ITERATIONS = xmrig::cn_select_iter(); - constexpr size_t MEM = xmrig::cn_select_memory(); - constexpr xmrig::Variant BASE = xmrig::cn_base_variant(); + constexpr CnAlgo props; + constexpr size_t MASK = props.mask(); + constexpr Algorithm::Id BASE = props.base(); - if (BASE == xmrig::VARIANT_1 && size < 43) { +# ifdef XMRIG_ALGO_CN_HEAVY + constexpr bool IS_CN_HEAVY_TUBE = ALGO == Algorithm::CN_HEAVY_TUBE; + constexpr bool IS_CN_HEAVY_XHV = ALGO == Algorithm::CN_HEAVY_XHV; +# else + constexpr bool IS_CN_HEAVY_TUBE = false; + constexpr bool IS_CN_HEAVY_XHV = false; +# endif + + if (BASE == Algorithm::CN_1 && size < 43) { memset(output, 0, 32 * 5); return; } for (size_t i = 0; i < 5; i++) { - xmrig::keccak(input + size * i, size, ctx[i]->state); - cn_explode_scratchpad(reinterpret_cast<__m128i*>(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory)); + keccak(input + size * i, size, ctx[i]->state); + cn_explode_scratchpad(reinterpret_cast(ctx[i]->state), reinterpret_cast<__m128i*>(ctx[i]->memory)); } uint8_t* l0 = ctx[0]->memory; @@ -1441,8 +1518,7 @@ inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t siz idx3 = _mm_cvtsi128_si64(ax3); idx4 = _mm_cvtsi128_si64(ax4); - for (size_t i = 0; i < ITERATIONS; i++) - { + for (size_t i = 0; i < props.iterations(); i++) { uint64_t hi, lo; __m128i *ptr0, *ptr1, *ptr2, *ptr3, *ptr4; @@ -1472,10 +1548,14 @@ inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t siz } for (size_t i = 0; i < 5; i++) { - cn_implode_scratchpad(reinterpret_cast<__m128i*>(ctx[i]->memory), reinterpret_cast<__m128i*>(ctx[i]->state)); - xmrig::keccakf(reinterpret_cast(ctx[i]->state), 24); + cn_implode_scratchpad(reinterpret_cast(ctx[i]->memory), reinterpret_cast<__m128i*>(ctx[i]->state)); + keccakf(reinterpret_cast(ctx[i]->state), 24); extra_hashes[ctx[i]->state[0] & 3](ctx[i]->state, 200, output + 32 * i); } } + +} /* namespace xmrig */ + + #endif /* XMRIG_CRYPTONIGHT_X86_H */ diff --git a/src/crypto/cn/gpu/cn_gpu_avx.cpp b/src/crypto/cn/gpu/cn_gpu_avx.cpp index 382be570..38da9714 100644 --- a/src/crypto/cn/gpu/cn_gpu_avx.cpp +++ b/src/crypto/cn/gpu/cn_gpu_avx.cpp @@ -22,7 +22,9 @@ * along with this program. If not, see . */ -#include "crypto/cn/CryptoNight_constants.h" + +#include "crypto/cn/CnAlgo.h" + #ifdef __GNUC__ # include @@ -206,4 +208,4 @@ void cn_gpu_inner_avx(const uint8_t* spad, uint8_t* lpad) } } -template void cn_gpu_inner_avx(const uint8_t* spad, uint8_t* lpad); +template void cn_gpu_inner_avx().iterations(), xmrig::CnAlgo().mask()>(const uint8_t* spad, uint8_t* lpad); diff --git a/src/crypto/cn/gpu/cn_gpu_ssse3.cpp b/src/crypto/cn/gpu/cn_gpu_ssse3.cpp index 42a11a1d..7cca096e 100644 --- a/src/crypto/cn/gpu/cn_gpu_ssse3.cpp +++ b/src/crypto/cn/gpu/cn_gpu_ssse3.cpp @@ -22,7 +22,9 @@ * along with this program. If not, see . */ -#include "crypto/cn/CryptoNight_constants.h" + +#include "crypto/cn/CnAlgo.h" + #ifdef __GNUC__ # include @@ -207,4 +209,4 @@ void cn_gpu_inner_ssse3(const uint8_t* spad, uint8_t* lpad) } } -template void cn_gpu_inner_ssse3(const uint8_t* spad, uint8_t* lpad); +template void cn_gpu_inner_ssse3().iterations(), xmrig::CnAlgo().mask()>(const uint8_t* spad, uint8_t* lpad); diff --git a/src/crypto/cn/r/variant4_random_math.h b/src/crypto/cn/r/variant4_random_math.h index c384df7a..48f0f6ce 100644 --- a/src/crypto/cn/r/variant4_random_math.h +++ b/src/crypto/cn/r/variant4_random_math.h @@ -1,6 +1,13 @@ #ifndef VARIANT4_RANDOM_MATH_H #define VARIANT4_RANDOM_MATH_H + +#include + + +#include "crypto/common/Algorithm.h" + + extern "C" { #include "crypto/cn/c_blake256.h" @@ -182,7 +189,7 @@ static FORCEINLINE void check_data(size_t* data_index, const size_t bytes_needed // Generates as many random math operations as possible with given latency and ALU restrictions // "code" array must have space for NUM_INSTRUCTIONS_MAX+1 instructions -template +template static int v4_random_math_init(struct V4_Instruction* code, const uint64_t height) { // MUL is 3 cycles, 3-way addition and rotations are 2 cycles, SUB/XOR are 1 cycle @@ -204,8 +211,7 @@ static int v4_random_math_init(struct V4_Instruction* code, const uint64_t heigh memset(data, 0, sizeof(data)); uint64_t tmp = SWAP64LE(height); memcpy(data, &tmp, sizeof(uint64_t)); - if (VARIANT == xmrig::VARIANT_4) - { + if (ALGO == xmrig::Algorithm::CN_R) { data[20] = -38; } @@ -249,7 +255,7 @@ static int v4_random_math_init(struct V4_Instruction* code, const uint64_t heigh code_size = 0; int total_iterations = 0; - r8_used = (VARIANT == xmrig::VARIANT_WOW); + r8_used = (ALGO == xmrig::Algorithm::CN_WOW); // Generate random code to achieve minimal required latency for our abstract CPU // Try to get this latency for all 4 registers @@ -291,10 +297,9 @@ static int v4_random_math_init(struct V4_Instruction* code, const uint64_t heigh int b = src_index; // Don't do ADD/SUB/XOR with the same register - if (((opcode == ADD) || (opcode == SUB) || (opcode == XOR)) && (a == b)) - { + if (((opcode == ADD) || (opcode == SUB) || (opcode == XOR)) && (a == b)) { // a is always < 4, so we don't need to check bounds here - b = (VARIANT == xmrig::VARIANT_WOW) ? (a + 4) : 8; + b = (ALGO == xmrig::Algorithm::CN_WOW) ? (a + 4) : 8; src_index = b; } diff --git a/src/crypto/common/Algorithm.cpp b/src/crypto/common/Algorithm.cpp index f85b0a6f..78272f79 100644 --- a/src/crypto/common/Algorithm.cpp +++ b/src/crypto/common/Algorithm.cpp @@ -56,12 +56,12 @@ struct AlgoName static AlgoName const algorithm_names[] = { - { "cryptonight/0", "cn/0", Algorithm::CN_0 }, - { "cryptonight", "cn", Algorithm::CN_0 }, - { "cryptonight/1", "cn/1", Algorithm::CN_1 }, - { "cryptonight-monerov7", nullptr, Algorithm::CN_1 }, - { "cryptonight_v7", nullptr, Algorithm::CN_1 }, - { "cryptonight/2", "cn/2", Algorithm::CN_2 }, + { "cryptonight/0", "cn/0", Algorithm::CN_0 }, + { "cryptonight", "cn", Algorithm::CN_0 }, + { "cryptonight/1", "cn/1", Algorithm::CN_1 }, + { "cryptonight-monerov7", nullptr, Algorithm::CN_1 }, + { "cryptonight_v7", nullptr, Algorithm::CN_1 }, + { "cryptonight/2", "cn/2", Algorithm::CN_2 }, { "cryptonight-monerov8", nullptr, Algorithm::CN_2 }, { "cryptonight_v8", nullptr, Algorithm::CN_2 }, { "cryptonight/r", "cn/r", Algorithm::CN_R }, @@ -75,7 +75,7 @@ static AlgoName const algorithm_names[] = { { "cryptonight/rto", "cn/rto", Algorithm::CN_RTO }, { "cryptonight/rwz", "cn/rwz", Algorithm::CN_RWZ }, { "cryptonight/zls", "cn/zls", Algorithm::CN_ZLS }, - { "cryptonight/double", "cn/double", Algorithm::CN_ZLS }, + { "cryptonight/double", "cn/double", Algorithm::CN_DOUBLE }, # ifdef XMRIG_ALGO_CN_GPU { "cryptonight/gpu", "cn/gpu", Algorithm::CN_GPU }, { "cryptonight_gpu", nullptr, Algorithm::CN_GPU }, @@ -99,11 +99,11 @@ static AlgoName const algorithm_names[] = { { "cryptonight-bittube2", nullptr, Algorithm::CN_HEAVY_TUBE }, # endif # ifdef XMRIG_ALGO_CN_PICO - { "cryptonight-pico", "cn-pico", Algorithm::CN_PICO }, - { "cryptonight-pico/trtl", "cn-pico/trtl", Algorithm::CN_PICO }, - { "cryptonight-turtle", "cn-trtl", Algorithm::CN_PICO }, - { "cryptonight-ultralite", "cn-ultralite", Algorithm::CN_PICO }, - { "cryptonight_turtle", "cn_turtle", Algorithm::CN_PICO }, + { "cryptonight-pico", "cn-pico", Algorithm::CN_PICO_0 }, + { "cryptonight-pico/trtl", "cn-pico/trtl", Algorithm::CN_PICO_0 }, + { "cryptonight-turtle", "cn-trtl", Algorithm::CN_PICO_0 }, + { "cryptonight-ultralite", "cn-ultralite", Algorithm::CN_PICO_0 }, + { "cryptonight_turtle", "cn_turtle", Algorithm::CN_PICO_0 }, # endif }; @@ -111,15 +111,48 @@ static AlgoName const algorithm_names[] = { } /* namespace xmrig */ -const char *xmrig::Algorithm::name(bool shortName) const +xmrig::Algorithm::Family xmrig::Algorithm::family(Id id) { - for (size_t i = 0; i < ARRAY_SIZE(algorithm_names); i++) { - if (algorithm_names[i].id == m_id) { - return shortName ? algorithm_names[i].shortName : algorithm_names[i].name; - } + switch (id) { + case CN_0: + case CN_1: + case CN_2: + case CN_R: + case CN_WOW: + case CN_FAST: + case CN_HALF: + case CN_XAO: + case CN_RTO: + case CN_RWZ: + case CN_DOUBLE: +# ifdef XMRIG_ALGO_CN_GPU + case CN_GPU: +# endif + return CN; + +# ifdef XMRIG_ALGO_CN_LITE + case CN_LITE_0: + case CN_LITE_1: + return CN_LITE; +# endif + +# ifdef XMRIG_ALGO_CN_HEAVY + case CN_HEAVY_0: + case CN_HEAVY_TUBE: + case CN_HEAVY_XHV: + return CN_HEAVY; +# endif + +# ifdef XMRIG_ALGO_CN_PICO + case Algorithm::CN_PICO_0: + return CN_PICO; +# endif + + default: + break; } - return "invalid"; + return UNKNOWN; } @@ -137,3 +170,15 @@ xmrig::Algorithm::Id xmrig::Algorithm::parse(const char *name) return INVALID; } + + +const char *xmrig::Algorithm::name(bool shortName) const +{ + for (size_t i = 0; i < ARRAY_SIZE(algorithm_names); i++) { + if (algorithm_names[i].id == m_id) { + return shortName ? algorithm_names[i].shortName : algorithm_names[i].name; + } + } + + return "invalid"; +} diff --git a/src/crypto/common/Algorithm.h b/src/crypto/common/Algorithm.h index c70e0caa..c9388dee 100644 --- a/src/crypto/common/Algorithm.h +++ b/src/crypto/common/Algorithm.h @@ -63,24 +63,35 @@ public: CN_HEAVY_XHV, // "cn-heavy/xhv" Modified CryptoNight-Heavy (Haven Protocol only) # endif # ifdef XMRIG_ALGO_CN_PICO - CN_PICO, // "cn-pico" CryptoNight Turtle (TRTL) + CN_PICO_0, // "cn-pico" CryptoNight Turtle (TRTL) # endif MAX }; + enum Family : int { + UNKNOWN, + CN, + CN_LITE, + CN_HEAVY, + CN_PICO + }; + inline Algorithm() {} inline Algorithm(const char *algo) : m_id(parse(algo)) {} inline Algorithm(Id id) : m_id(id) {} inline bool isEqual(const Algorithm &other) const { return m_id == other.m_id; } + inline bool isValid() const { return m_id != INVALID; } inline const char *name() const { return name(false); } inline const char *shortName() const { return name(true); } + inline Family family() const { return family(m_id); } inline Id id() const { return m_id; } - inline bool isValid() const { return m_id != INVALID; } inline bool operator!=(const Algorithm &other) const { return !isEqual(other); } inline bool operator==(const Algorithm &other) const { return isEqual(other); } + inline operator Algorithm::Id() const { return m_id; } + static Family family(Id id); static Id parse(const char *name); private: diff --git a/src/interfaces/IThread.h b/src/interfaces/IThread.h index e74b5bca..3c0a7287 100644 --- a/src/interfaces/IThread.h +++ b/src/interfaces/IThread.h @@ -27,7 +27,7 @@ #include -#include "common/xmrig.h" +#include "crypto/common/Algorithm.h" #include "rapidjson/fwd.h" @@ -53,7 +53,7 @@ public: virtual ~IThread() = default; - virtual Algo algorithm() const = 0; + virtual Algorithm algorithm() const = 0; virtual int priority() const = 0; virtual int64_t affinity() const = 0; virtual Multiway multiway() const = 0; diff --git a/src/workers/CpuThread.cpp b/src/workers/CpuThread.cpp index 5c98a5b3..e26b8a0a 100644 --- a/src/workers/CpuThread.cpp +++ b/src/workers/CpuThread.cpp @@ -28,20 +28,20 @@ #include "base/io/log/Log.h" #include "common/cpu/Cpu.h" #include "crypto/cn/Asm.h" +#include "crypto/cn/CnHash.h" #include "crypto/common/VirtualMemory.h" #include "Mem.h" #include "rapidjson/document.h" #include "workers/CpuThread.h" -#if defined(XMRIG_ARM) -# include "crypto/cn/CryptoNight_arm.h" -#else -# include "crypto/cn/CryptoNight_x86.h" -#endif -xmrig::CpuThread::CpuThread(size_t index, Algo algorithm, AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch, Assembly assembly) : + +static const xmrig::CnHash cnHash; + + +xmrig::CpuThread::CpuThread(size_t index, Algorithm algorithm, AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch, Assembly assembly) : m_algorithm(algorithm), m_av(av), m_assembly(assembly), @@ -55,119 +55,12 @@ xmrig::CpuThread::CpuThread(size_t index, Algo algorithm, AlgoVariant av, Multiw } -#ifndef XMRIG_NO_ASM -template -static void patchCode(T dst, U src, const uint32_t iterations, const uint32_t mask) +xmrig::cn_hash_fun xmrig::CpuThread::fn(const Algorithm &algorithm) const { - const uint8_t* p = reinterpret_cast(src); - - // Workaround for Visual Studio placing trampoline in debug builds. -# if defined(_MSC_VER) - if (p[0] == 0xE9) { - p += *(int32_t*)(p + 1) + 5; - } -# endif - - size_t size = 0; - while (*(uint32_t*)(p + size) != 0xDEADC0DE) { - ++size; - } - size += sizeof(uint32_t); - - memcpy((void*) dst, (const void*) src, size); - - uint8_t* patched_data = reinterpret_cast(dst); - for (size_t i = 0; i + sizeof(uint32_t) <= size; ++i) { - switch (*(uint32_t*)(patched_data + i)) { - case xmrig::CRYPTONIGHT_ITER: - *(uint32_t*)(patched_data + i) = iterations; - break; - - case xmrig::CRYPTONIGHT_MASK: - *(uint32_t*)(patched_data + i) = mask; - break; - } - } + return cnHash.fn(algorithm, m_av, m_assembly); } -extern "C" void cnv2_mainloop_ivybridge_asm(cryptonight_ctx **ctx); -extern "C" void cnv2_mainloop_ryzen_asm(cryptonight_ctx **ctx); -extern "C" void cnv2_mainloop_bulldozer_asm(cryptonight_ctx **ctx); -extern "C" void cnv2_double_mainloop_sandybridge_asm(cryptonight_ctx **ctx); - - -xmrig::CpuThread::cn_mainloop_fun cn_half_mainloop_ivybridge_asm = nullptr; -xmrig::CpuThread::cn_mainloop_fun cn_half_mainloop_ryzen_asm = nullptr; -xmrig::CpuThread::cn_mainloop_fun cn_half_mainloop_bulldozer_asm = nullptr; -xmrig::CpuThread::cn_mainloop_fun cn_half_double_mainloop_sandybridge_asm = nullptr; - -xmrig::CpuThread::cn_mainloop_fun cn_trtl_mainloop_ivybridge_asm = nullptr; -xmrig::CpuThread::cn_mainloop_fun cn_trtl_mainloop_ryzen_asm = nullptr; -xmrig::CpuThread::cn_mainloop_fun cn_trtl_mainloop_bulldozer_asm = nullptr; -xmrig::CpuThread::cn_mainloop_fun cn_trtl_double_mainloop_sandybridge_asm = nullptr; - -xmrig::CpuThread::cn_mainloop_fun cn_zls_mainloop_ivybridge_asm = nullptr; -xmrig::CpuThread::cn_mainloop_fun cn_zls_mainloop_ryzen_asm = nullptr; -xmrig::CpuThread::cn_mainloop_fun cn_zls_mainloop_bulldozer_asm = nullptr; -xmrig::CpuThread::cn_mainloop_fun cn_zls_double_mainloop_sandybridge_asm = nullptr; - -xmrig::CpuThread::cn_mainloop_fun cn_double_mainloop_ivybridge_asm = nullptr; -xmrig::CpuThread::cn_mainloop_fun cn_double_mainloop_ryzen_asm = nullptr; -xmrig::CpuThread::cn_mainloop_fun cn_double_mainloop_bulldozer_asm = nullptr; -xmrig::CpuThread::cn_mainloop_fun cn_double_double_mainloop_sandybridge_asm = nullptr; - - -void xmrig::CpuThread::patchAsmVariants() -{ - const int allocation_size = 65536; - uint8_t *base = static_cast(VirtualMemory::allocateExecutableMemory(allocation_size)); - - cn_half_mainloop_ivybridge_asm = reinterpret_cast (base + 0x0000); - cn_half_mainloop_ryzen_asm = reinterpret_cast (base + 0x1000); - cn_half_mainloop_bulldozer_asm = reinterpret_cast (base + 0x2000); - cn_half_double_mainloop_sandybridge_asm = reinterpret_cast (base + 0x3000); - - cn_trtl_mainloop_ivybridge_asm = reinterpret_cast (base + 0x4000); - cn_trtl_mainloop_ryzen_asm = reinterpret_cast (base + 0x5000); - cn_trtl_mainloop_bulldozer_asm = reinterpret_cast (base + 0x6000); - cn_trtl_double_mainloop_sandybridge_asm = reinterpret_cast (base + 0x7000); - - cn_zls_mainloop_ivybridge_asm = reinterpret_cast (base + 0x8000); - cn_zls_mainloop_ryzen_asm = reinterpret_cast (base + 0x9000); - cn_zls_mainloop_bulldozer_asm = reinterpret_cast (base + 0xA000); - cn_zls_double_mainloop_sandybridge_asm = reinterpret_cast (base + 0xB000); - - cn_double_mainloop_ivybridge_asm = reinterpret_cast (base + 0xC000); - cn_double_mainloop_ryzen_asm = reinterpret_cast (base + 0xD000); - cn_double_mainloop_bulldozer_asm = reinterpret_cast (base + 0xE000); - cn_double_double_mainloop_sandybridge_asm = reinterpret_cast (base + 0xF000); - - patchCode(cn_half_mainloop_ivybridge_asm, cnv2_mainloop_ivybridge_asm, xmrig::CRYPTONIGHT_HALF_ITER, xmrig::CRYPTONIGHT_MASK); - patchCode(cn_half_mainloop_ryzen_asm, cnv2_mainloop_ryzen_asm, xmrig::CRYPTONIGHT_HALF_ITER, xmrig::CRYPTONIGHT_MASK); - patchCode(cn_half_mainloop_bulldozer_asm, cnv2_mainloop_bulldozer_asm, xmrig::CRYPTONIGHT_HALF_ITER, xmrig::CRYPTONIGHT_MASK); - patchCode(cn_half_double_mainloop_sandybridge_asm, cnv2_double_mainloop_sandybridge_asm, xmrig::CRYPTONIGHT_HALF_ITER, xmrig::CRYPTONIGHT_MASK); - - patchCode(cn_trtl_mainloop_ivybridge_asm, cnv2_mainloop_ivybridge_asm, xmrig::CRYPTONIGHT_TRTL_ITER, xmrig::CRYPTONIGHT_PICO_MASK); - patchCode(cn_trtl_mainloop_ryzen_asm, cnv2_mainloop_ryzen_asm, xmrig::CRYPTONIGHT_TRTL_ITER, xmrig::CRYPTONIGHT_PICO_MASK); - patchCode(cn_trtl_mainloop_bulldozer_asm, cnv2_mainloop_bulldozer_asm, xmrig::CRYPTONIGHT_TRTL_ITER, xmrig::CRYPTONIGHT_PICO_MASK); - patchCode(cn_trtl_double_mainloop_sandybridge_asm, cnv2_double_mainloop_sandybridge_asm, xmrig::CRYPTONIGHT_TRTL_ITER, xmrig::CRYPTONIGHT_PICO_MASK); - - patchCode(cn_zls_mainloop_ivybridge_asm, cnv2_mainloop_ivybridge_asm, xmrig::CRYPTONIGHT_ZLS_ITER, xmrig::CRYPTONIGHT_MASK); - patchCode(cn_zls_mainloop_ryzen_asm, cnv2_mainloop_ryzen_asm, xmrig::CRYPTONIGHT_ZLS_ITER, xmrig::CRYPTONIGHT_MASK); - patchCode(cn_zls_mainloop_bulldozer_asm, cnv2_mainloop_bulldozer_asm, xmrig::CRYPTONIGHT_ZLS_ITER, xmrig::CRYPTONIGHT_MASK); - patchCode(cn_zls_double_mainloop_sandybridge_asm, cnv2_double_mainloop_sandybridge_asm, xmrig::CRYPTONIGHT_ZLS_ITER, xmrig::CRYPTONIGHT_MASK); - - patchCode(cn_double_mainloop_ivybridge_asm, cnv2_mainloop_ivybridge_asm, xmrig::CRYPTONIGHT_DOUBLE_ITER, xmrig::CRYPTONIGHT_MASK); - patchCode(cn_double_mainloop_ryzen_asm, cnv2_mainloop_ryzen_asm, xmrig::CRYPTONIGHT_DOUBLE_ITER, xmrig::CRYPTONIGHT_MASK); - patchCode(cn_double_mainloop_bulldozer_asm, cnv2_mainloop_bulldozer_asm, xmrig::CRYPTONIGHT_DOUBLE_ITER, xmrig::CRYPTONIGHT_MASK); - patchCode(cn_double_double_mainloop_sandybridge_asm, cnv2_double_mainloop_sandybridge_asm, xmrig::CRYPTONIGHT_DOUBLE_ITER, xmrig::CRYPTONIGHT_MASK); - - VirtualMemory::protectExecutableMemory(base, allocation_size); - VirtualMemory::flushInstructionCache(base, allocation_size); -} -#endif - bool xmrig::CpuThread::isSoftAES(AlgoVariant av) { @@ -175,418 +68,7 @@ bool xmrig::CpuThread::isSoftAES(AlgoVariant av) } -#ifndef XMRIG_NO_ASM -template -static inline void add_asm_func(xmrig::CpuThread::cn_hash_fun(&asm_func_map)[xmrig::ALGO_MAX][xmrig::AV_MAX][xmrig::VARIANT_MAX][xmrig::ASM_MAX]) -{ - asm_func_map[algo][xmrig::AV_SINGLE][variant][xmrig::ASM_INTEL] = cryptonight_single_hash_asm; - asm_func_map[algo][xmrig::AV_SINGLE][variant][xmrig::ASM_RYZEN] = cryptonight_single_hash_asm; - asm_func_map[algo][xmrig::AV_SINGLE][variant][xmrig::ASM_BULLDOZER] = cryptonight_single_hash_asm; - - asm_func_map[algo][xmrig::AV_DOUBLE][variant][xmrig::ASM_INTEL] = cryptonight_double_hash_asm; - asm_func_map[algo][xmrig::AV_DOUBLE][variant][xmrig::ASM_RYZEN] = cryptonight_double_hash_asm; - asm_func_map[algo][xmrig::AV_DOUBLE][variant][xmrig::ASM_BULLDOZER] = cryptonight_double_hash_asm; -} -#endif - -xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant av, Variant variant, Assembly assembly) -{ - assert(variant >= VARIANT_0 && variant < VARIANT_MAX); - -# ifndef XMRIG_NO_ASM - if (assembly == ASM_AUTO) { - assembly = Cpu::info()->assembly(); - } - - static cn_hash_fun asm_func_map[ALGO_MAX][AV_MAX][VARIANT_MAX][ASM_MAX] = {}; - static bool asm_func_map_initialized = false; - - if (!asm_func_map_initialized) { - add_asm_func(asm_func_map); - add_asm_func(asm_func_map); - add_asm_func(asm_func_map); - add_asm_func(asm_func_map); - -# ifdef XMRIG_ALGO_CN_PICO - add_asm_func(asm_func_map); -# endif - - add_asm_func(asm_func_map); - add_asm_func(asm_func_map); - add_asm_func(asm_func_map); - - asm_func_map_initialized = true; - } - - cn_hash_fun fun = asm_func_map[algorithm][av][variant][assembly]; - if (fun) { - return fun; - } -# endif - - constexpr const size_t count = VARIANT_MAX * 10 * ALGO_MAX; - - static const cn_hash_fun func_table[] = { - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_TUBE - - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_XHV - - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_TRTL - -# ifdef XMRIG_ALGO_CN_GPU - cryptonight_single_hash_gpu, - nullptr, - cryptonight_single_hash_gpu, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, -# else - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_GPU -# endif - - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - -# ifdef XMRIG_ALGO_CN_LITE - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_TUBE - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_XTL - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_MSR - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_XHV - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_XAO - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RTO - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_2 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_HALF - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_TRTL - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_GPU - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_WOW - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_4 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RWZ - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_ZLS - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_DOUBLE -# else - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_0 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_1 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_TUBE - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_XTL - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_MSR - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_XHV - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_XAO - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RTO - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_2 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_HALF - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_TRTL - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_GPU - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_WOW - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_4 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RWZ - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_ZLS - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_DOUBLE -# endif - -# ifdef XMRIG_ALGO_CN_HEAVY - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_1 - - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_XTL - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_MSR - - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_XAO - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RTO - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_2 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_HALF - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_TRTL - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_GPU - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_WOW - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_4 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RWZ - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_ZLS - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_DOUBLE -# else - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_0 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_1 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_TUBE - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_XTL - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_MSR - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_XHV - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_XAO - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RTO - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_2 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_HALF - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_TRTL - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_GPU - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_WOW - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_4 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RWZ - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_ZLS - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_DOUBLE -# endif - -# ifdef XMRIG_ALGO_CN_PICO - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_0 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_1 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_TUBE - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_XTL - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_MSR - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_XHV - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_XAO - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RTO - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_2 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_HALF - - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_single_hash, - cryptonight_double_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - cryptonight_triple_hash, - cryptonight_quad_hash, - cryptonight_penta_hash, - - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_GPU - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_WOW - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_4 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RWZ - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_ZLS - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_DOUBLE -# else - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_0 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_1 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_TUBE - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_XTL - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_MSR - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_XHV - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_XAO - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RTO - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_2 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_HALF - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_TRTL - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_GPU - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_WOW - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_4 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_RWZ - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_ZLS - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, // VARIANT_DOUBLE -# endif - }; - - static_assert(count == sizeof(func_table) / sizeof(func_table[0]), "func_table size mismatch"); - - const size_t index = VARIANT_MAX * 10 * algorithm + 10 * variant + av - 1; - -# ifndef NDEBUG - cn_hash_fun func = func_table[index]; - - assert(index < sizeof(func_table) / sizeof(func_table[0])); - assert(func != nullptr); - - return func; -# else - return func_table[index]; -# endif -} - - -xmrig::CpuThread *xmrig::CpuThread::createFromAV(size_t index, Algo algorithm, AlgoVariant av, int64_t affinity, int priority, Assembly assembly) +xmrig::CpuThread *xmrig::CpuThread::createFromAV(size_t index, const Algorithm &algorithm, AlgoVariant av, int64_t affinity, int priority, Assembly assembly) { assert(av > AV_AUTO && av < AV_MAX); @@ -613,7 +95,7 @@ xmrig::CpuThread *xmrig::CpuThread::createFromAV(size_t index, Algo algorithm, A } -xmrig::CpuThread *xmrig::CpuThread::createFromData(size_t index, Algo algorithm, const CpuThread::Data &data, int priority, bool softAES) +xmrig::CpuThread *xmrig::CpuThread::createFromData(size_t index, const Algorithm &algorithm, const CpuThread::Data &data, int priority, bool softAES) { int av = AV_AUTO; const Multiway multiway = data.multiway; @@ -653,7 +135,7 @@ xmrig::CpuThread::Data xmrig::CpuThread::parse(const rapidjson::Value &object) data.affinity = affinity.GetInt64(); } -# ifndef XMRIG_NO_ASM +# ifdef XMRIG_FEATURE_ASM data.assembly = Asm::parse(object["asm"]); # endif @@ -698,7 +180,7 @@ void xmrig::CpuThread::print() const LOG_DEBUG(GREEN_BOLD("CPU thread: ") " index " WHITE_BOLD("%zu") ", multiway " WHITE_BOLD("%d") ", av " WHITE_BOLD("%d") ",", index(), static_cast(multiway()), static_cast(m_av)); -# ifndef XMRIG_NO_ASM +# ifdef XMRIG_FEATURE_ASM LOG_DEBUG(" assembly: %s, affine_to_cpu: %" PRId64, Asm::toString(m_assembly), affinity()); # else LOG_DEBUG(" affine_to_cpu: %" PRId64, affinity()); @@ -737,7 +219,7 @@ rapidjson::Value xmrig::CpuThread::toConfig(rapidjson::Document &doc) const obj.AddMember("low_power_mode", multiway(), allocator); obj.AddMember("affine_to_cpu", affinity() == -1L ? Value(kFalseType) : Value(affinity()), allocator); -# ifndef XMRIG_NO_ASM +# ifdef XMRIG_FEATURE_ASM obj.AddMember("asm", Asm::toJSON(m_assembly), allocator); # endif diff --git a/src/workers/CpuThread.h b/src/workers/CpuThread.h index 2af421be..08aa89cb 100644 --- a/src/workers/CpuThread.h +++ b/src/workers/CpuThread.h @@ -27,6 +27,7 @@ #include "common/xmrig.h" +#include "crypto/cn/CnHash.h" #include "interfaces/IThread.h" @@ -58,27 +59,20 @@ public: }; - CpuThread(size_t index, Algo algorithm, AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch, Assembly assembly); + CpuThread(size_t index, Algorithm algorithm, AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch, Assembly assembly); - typedef void (*cn_hash_fun)(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx **ctx, uint64_t height); - typedef void (*cn_mainloop_fun)(cryptonight_ctx **ctx); - -# ifndef XMRIG_NO_ASM - static void patchAsmVariants(); -# endif + cn_hash_fun fn(const Algorithm &algorithm) const; static bool isSoftAES(AlgoVariant av); - static cn_hash_fun fn(Algo algorithm, AlgoVariant av, Variant variant, Assembly assembly); - static CpuThread *createFromAV(size_t index, Algo algorithm, AlgoVariant av, int64_t affinity, int priority, Assembly assembly); - static CpuThread *createFromData(size_t index, Algo algorithm, const CpuThread::Data &data, int priority, bool softAES); + static CpuThread *createFromAV(size_t index, const Algorithm &algorithm, AlgoVariant av, int64_t affinity, int priority, Assembly assembly); + static CpuThread *createFromData(size_t index, const Algorithm &algorithm, const CpuThread::Data &data, int priority, bool softAES); static Data parse(const rapidjson::Value &object); static Multiway multiway(AlgoVariant av); inline bool isPrefetch() const { return m_prefetch; } inline bool isSoftAES() const { return m_softAES; } - inline cn_hash_fun fn(Variant variant) const { return fn(m_algorithm, m_av, variant, m_assembly); } - inline Algo algorithm() const override { return m_algorithm; } + inline Algorithm algorithm() const override { return m_algorithm; } inline int priority() const override { return m_priority; } inline int64_t affinity() const override { return m_affinity; } inline Multiway multiway() const override { return m_multiway; } @@ -97,7 +91,7 @@ protected: rapidjson::Value toConfig(rapidjson::Document &doc) const override; private: - const Algo m_algorithm; + const Algorithm m_algorithm; const AlgoVariant m_av; const Assembly m_assembly; const bool m_prefetch; diff --git a/src/workers/MultiWorker.cpp b/src/workers/MultiWorker.cpp index 30c43000..f209ca76 100644 --- a/src/workers/MultiWorker.cpp +++ b/src/workers/MultiWorker.cpp @@ -34,7 +34,7 @@ template -MultiWorker::MultiWorker(ThreadHandle *handle) +xmrig::MultiWorker::MultiWorker(ThreadHandle *handle) : Worker(handle) { m_memory = Mem::create(m_ctx, m_thread->algorithm(), N); @@ -42,61 +42,58 @@ MultiWorker::MultiWorker(ThreadHandle *handle) template -MultiWorker::~MultiWorker() +xmrig::MultiWorker::~MultiWorker() { Mem::release(m_ctx, N, m_memory); } template -bool MultiWorker::selfTest() +bool xmrig::MultiWorker::selfTest() { - using namespace xmrig; - - if (m_thread->algorithm() == CRYPTONIGHT) { - const bool rc = verify(VARIANT_0, test_output_v0) && - verify(VARIANT_1, test_output_v1) && - verify(VARIANT_2, test_output_v2) && - verify(VARIANT_XTL, test_output_xtl) && - verify(VARIANT_MSR, test_output_msr) && - verify(VARIANT_XAO, test_output_xao) && - verify(VARIANT_RTO, test_output_rto) && - verify(VARIANT_HALF, test_output_half) && - verify2(VARIANT_WOW, test_output_wow) && - verify2(VARIANT_4, test_output_r) && - verify(VARIANT_RWZ, test_output_rwz) && - verify(VARIANT_ZLS, test_output_zls) && - verify(VARIANT_DOUBLE, test_output_double); + if (m_thread->algorithm().family() == Algorithm::CN) { + const bool rc = verify(Algorithm::CN_0, test_output_v0) && + verify(Algorithm::CN_1, test_output_v1) && + verify(Algorithm::CN_2, test_output_v2) && + verify(Algorithm::CN_FAST, test_output_msr) && + verify(Algorithm::CN_XAO, test_output_xao) && + verify(Algorithm::CN_RTO, test_output_rto) && + verify(Algorithm::CN_HALF, test_output_half) && + verify2(Algorithm::CN_WOW, test_output_wow) && + verify2(Algorithm::CN_R, test_output_r) && + verify(Algorithm::CN_RWZ, test_output_rwz) && + verify(Algorithm::CN_ZLS, test_output_zls) && + verify(Algorithm::CN_DOUBLE, test_output_double); # ifdef XMRIG_ALGO_CN_GPU if (!rc || N > 1) { return rc; } - return verify(VARIANT_GPU, test_output_gpu); + return verify(Algorithm::CN_GPU, test_output_gpu); # else return rc; # endif } # ifdef XMRIG_ALGO_CN_LITE - if (m_thread->algorithm() == CRYPTONIGHT_LITE) { - return verify(VARIANT_0, test_output_v0_lite) && - verify(VARIANT_1, test_output_v1_lite); + if (m_thread->algorithm().family() == Algorithm::CN_LITE) { + return verify(Algorithm::CN_LITE_0, test_output_v0_lite) && + verify(Algorithm::CN_LITE_1, test_output_v1_lite); } # endif # ifdef XMRIG_ALGO_CN_HEAVY - if (m_thread->algorithm() == CRYPTONIGHT_HEAVY) { - return verify(VARIANT_0, test_output_v0_heavy) && - verify(VARIANT_XHV, test_output_xhv_heavy) && - verify(VARIANT_TUBE, test_output_tube_heavy); + if (m_thread->algorithm().family() == Algorithm::CN_HEAVY) { + return verify(Algorithm::CN_HEAVY_0, test_output_v0_heavy) && + verify(Algorithm::CN_HEAVY_XHV, test_output_xhv_heavy) && + verify(Algorithm::CN_HEAVY_TUBE, test_output_tube_heavy); } # endif # ifdef XMRIG_ALGO_CN_PICO - if (m_thread->algorithm() == CRYPTONIGHT_PICO) { - return verify(VARIANT_TRTL, test_output_pico_trtl); + if (m_thread->algorithm().family() == Algorithm::CN_PICO) { + return verify(Algorithm::CN_PICO_0, test_output_pico_trtl); } # endif @@ -105,7 +102,7 @@ bool MultiWorker::selfTest() template -void MultiWorker::start() +void xmrig::MultiWorker::start() { while (Workers::sequence() > 0) { if (Workers::isPaused()) { @@ -126,12 +123,11 @@ void MultiWorker::start() storeStats(); } - // FIXME -// m_thread->fn(m_state.job.algorithm().variant())(m_state.blob, m_state.job.size(), m_hash, m_ctx, m_state.job.height()); + m_thread->fn(m_state.job.algorithm())(m_state.blob, m_state.job.size(), m_hash, m_ctx, m_state.job.height()); for (size_t i = 0; i < N; ++i) { if (*reinterpret_cast(m_hash + (i * 32) + 24) < m_state.job.target()) { - Workers::submit(xmrig::JobResult(m_state.job.poolId(), m_state.job.id(), m_state.job.clientId(), *nonce(i), m_hash + (i * 32), m_state.job.diff(), m_state.job.algorithm())); + Workers::submit(JobResult(m_state.job.poolId(), m_state.job.id(), m_state.job.clientId(), *nonce(i), m_hash + (i * 32), m_state.job.diff(), m_state.job.algorithm())); } *nonce(i) += 1; @@ -148,7 +144,7 @@ void MultiWorker::start() template -bool MultiWorker::resume(const xmrig::Job &job) +bool xmrig::MultiWorker::resume(const xmrig::Job &job) { if (m_state.job.poolId() == -1 && job.poolId() >= 0 && job.id() == m_pausedState.job.id()) { m_state = m_pausedState; @@ -160,10 +156,9 @@ bool MultiWorker::resume(const xmrig::Job &job) template -bool MultiWorker::verify(xmrig::Variant variant, const uint8_t *referenceValue) +bool xmrig::MultiWorker::verify(const Algorithm &algorithm, const uint8_t *referenceValue) { - - xmrig::CpuThread::cn_hash_fun func = m_thread->fn(variant); + cn_hash_fun func = m_thread->fn(algorithm); if (!func) { return false; } @@ -174,9 +169,9 @@ bool MultiWorker::verify(xmrig::Variant variant, const uint8_t *referenceValu template -bool MultiWorker::verify2(xmrig::Variant variant, const uint8_t *referenceValue) +bool xmrig::MultiWorker::verify2(const Algorithm &algorithm, const uint8_t *referenceValue) { - xmrig::CpuThread::cn_hash_fun func = m_thread->fn(variant); + cn_hash_fun func = m_thread->fn(algorithm); if (!func) { return false; } @@ -201,9 +196,9 @@ bool MultiWorker::verify2(xmrig::Variant variant, const uint8_t *referenceVal template<> -bool MultiWorker<1>::verify2(xmrig::Variant variant, const uint8_t *referenceValue) +bool xmrig::MultiWorker<1>::verify2(const Algorithm &algorithm, const uint8_t *referenceValue) { - xmrig::CpuThread::cn_hash_fun func = m_thread->fn(variant); + cn_hash_fun func = m_thread->fn(algorithm); if (!func) { return false; } @@ -221,9 +216,9 @@ bool MultiWorker<1>::verify2(xmrig::Variant variant, const uint8_t *referenceVal template -void MultiWorker::consumeJob() +void xmrig::MultiWorker::consumeJob() { - xmrig::Job job = Workers::job(); + Job job = Workers::job(); m_sequence = Workers::sequence(); if (m_state.job == job) { return; @@ -258,7 +253,7 @@ void MultiWorker::consumeJob() template -void MultiWorker::save(const xmrig::Job &job) +void xmrig::MultiWorker::save(const Job &job) { if (job.poolId() == -1 && m_state.job.poolId() >= 0) { m_pausedState = m_state; @@ -266,8 +261,13 @@ void MultiWorker::save(const xmrig::Job &job) } +namespace xmrig { + template class MultiWorker<1>; template class MultiWorker<2>; template class MultiWorker<3>; template class MultiWorker<4>; template class MultiWorker<5>; + +} + diff --git a/src/workers/MultiWorker.h b/src/workers/MultiWorker.h index 99d37e44..82898e1e 100644 --- a/src/workers/MultiWorker.h +++ b/src/workers/MultiWorker.h @@ -33,7 +33,7 @@ #include "workers/Worker.h" -class Handle; +namespace xmrig { template @@ -48,11 +48,11 @@ protected: void start() override; private: - bool resume(const xmrig::Job &job); - bool verify(xmrig::Variant variant, const uint8_t *referenceValue); - bool verify2(xmrig::Variant variant, const uint8_t *referenceValue); + bool resume(const Job &job); + bool verify(const Algorithm &algorithm, const uint8_t *referenceValue); + bool verify2(const Algorithm &algorithm, const uint8_t *referenceValue); void consumeJob(); - void save(const xmrig::Job &job); + void save(const Job &job); inline uint32_t *nonce(size_t index) { @@ -61,8 +61,8 @@ private: struct State { - alignas(16) uint8_t blob[xmrig::Job::kMaxBlobSize * N]; - xmrig::Job job; + alignas(16) uint8_t blob[Job::kMaxBlobSize * N]; + Job job; }; @@ -73,4 +73,7 @@ private: }; +} // namespace xmrig + + #endif /* XMRIG_MULTIWORKER_H */ diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 62cbd1cf..1955677b 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -32,7 +32,6 @@ #include "base/tools/Handle.h" #include "core/config/Config.h" #include "core/Controller.h" -#include "crypto/cn/CryptoNight_constants.h" #include "interfaces/IJobResultListener.h" #include "interfaces/IThread.h" #include "Mem.h" @@ -169,14 +168,10 @@ void Workers::start(xmrig::Controller *controller) LOG_NOTICE("--------------------------------------------------------------------------"); # endif -# ifndef XMRIG_NO_ASM - xmrig::CpuThread::patchAsmVariants(); -# endif - m_controller = controller; const std::vector &threads = controller->config()->threads(); -// m_status.algo = controller->config()->algorithm().algo(); // FIXME + m_status.algo = xmrig::Algorithm::CN_0; // FIXME algo m_status.threads = threads.size(); for (const xmrig::IThread *thread : threads) { @@ -240,7 +235,7 @@ void Workers::threadsSummary(rapidjson::Document &doc) { uv_mutex_lock(&m_mutex); const uint64_t pages[2] = { m_status.hugePages, m_status.pages }; - const uint64_t memory = m_status.ways * xmrig::cn_select_memory(m_status.algo); + const uint64_t memory = m_status.ways * xmrig::CnAlgo<>::memory(m_status.algo); uv_mutex_unlock(&m_mutex); auto &allocator = doc.GetAllocator(); @@ -263,23 +258,23 @@ void Workers::onReady(void *arg) switch (handle->config()->multiway()) { case 1: - worker = new MultiWorker<1>(handle); + worker = new xmrig::MultiWorker<1>(handle); break; case 2: - worker = new MultiWorker<2>(handle); + worker = new xmrig::MultiWorker<2>(handle); break; case 3: - worker = new MultiWorker<3>(handle); + worker = new xmrig::MultiWorker<3>(handle); break; case 4: - worker = new MultiWorker<4>(handle); + worker = new xmrig::MultiWorker<4>(handle); break; case 5: - worker = new MultiWorker<5>(handle); + worker = new xmrig::MultiWorker<5>(handle); break; default: @@ -344,7 +339,7 @@ void Workers::start(IWorker *worker) if (m_status.started == m_status.threads) { const double percent = (double) m_status.hugePages / m_status.pages * 100.0; - const size_t memory = m_status.ways * xmrig::cn_select_memory(m_status.algo) / 1024; + const size_t memory = m_status.ways * xmrig::CnAlgo<>::memory(m_status.algo) / 1024; LOG_INFO(GREEN_BOLD("READY (CPU)") " threads " CYAN_BOLD("%zu(%zu)") " huge pages %s%zu/%zu %1.0f%%\x1B[0m memory " CYAN_BOLD("%zu KB") "", m_status.threads, m_status.ways, diff --git a/src/workers/Workers.h b/src/workers/Workers.h index 5b084fc2..24480517 100644 --- a/src/workers/Workers.h +++ b/src/workers/Workers.h @@ -86,8 +86,7 @@ private: pages(0), started(0), threads(0), - ways(0), - algo(xmrig::CRYPTONIGHT) + ways(0) {} size_t hugePages; @@ -95,7 +94,7 @@ private: size_t started; size_t threads; size_t ways; - xmrig::Algo algo; + xmrig::Algorithm algo; }; static bool m_active; From 088587fa7280abd8636f4e476aaba44dafa6ff53 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 14 Jun 2019 05:21:17 +0700 Subject: [PATCH 03/48] Fixed build on Linux. --- src/workers/MultiWorker.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/workers/MultiWorker.cpp b/src/workers/MultiWorker.cpp index f209ca76..ffa34dda 100644 --- a/src/workers/MultiWorker.cpp +++ b/src/workers/MultiWorker.cpp @@ -195,8 +195,10 @@ bool xmrig::MultiWorker::verify2(const Algorithm &algorithm, const uint8_t *r } +namespace xmrig { + template<> -bool xmrig::MultiWorker<1>::verify2(const Algorithm &algorithm, const uint8_t *referenceValue) +bool MultiWorker<1>::verify2(const Algorithm &algorithm, const uint8_t *referenceValue) { cn_hash_fun func = m_thread->fn(algorithm); if (!func) { @@ -214,6 +216,8 @@ bool xmrig::MultiWorker<1>::verify2(const Algorithm &algorithm, const uint8_t *r return true; } +} // namespace xmrig + template void xmrig::MultiWorker::consumeJob() @@ -269,5 +273,5 @@ template class MultiWorker<3>; template class MultiWorker<4>; template class MultiWorker<5>; -} +} // namespace xmrig From b73c204e73bb35a6883b1810c364d3b8d9377ef8 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 15 Jun 2019 00:28:16 +0700 Subject: [PATCH 04/48] Fixed ARM mining code. --- src/crypto/cn/CryptoNight_arm.h | 315 ++++++++++++++++------------- src/crypto/cn/CryptoNight_monero.h | 2 +- src/crypto/cn/gpu/cn_gpu_arm.cpp | 4 +- 3 files changed, 182 insertions(+), 139 deletions(-) diff --git a/src/crypto/cn/CryptoNight_arm.h b/src/crypto/cn/CryptoNight_arm.h index d9be454b..6d56b548 100644 --- a/src/crypto/cn/CryptoNight_arm.h +++ b/src/crypto/cn/CryptoNight_arm.h @@ -29,11 +29,11 @@ #include "common/crypto/keccak.h" -#include "crypto/common/portable/mm_malloc.h" -#include "crypto/cn/CryptoNight_constants.h" +#include "crypto/cn/CnAlgo.h" #include "crypto/cn/CryptoNight_monero.h" #include "crypto/cn/CryptoNight.h" #include "crypto/cn/soft_aes.h" +#include "crypto/common/portable/mm_malloc.h" extern "C" @@ -226,9 +226,14 @@ inline void mix_and_propagate(__m128i& x0, __m128i& x1, __m128i& x2, __m128i& x3 } -template +namespace xmrig { + + +template static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output) { + constexpr CnAlgo props; + __m128i xin0, xin1, xin2, xin3, xin4, xin5, xin6, xin7; __m128i k0, k1, k2, k3, k4, k5, k6, k7, k8, k9; @@ -243,7 +248,7 @@ static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output) xin6 = _mm_load_si128(input + 10); xin7 = _mm_load_si128(input + 11); - if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { + if (props.isHeavy()) { for (size_t i = 0; i < 16; i++) { aes_round(k0, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); aes_round(k1, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); @@ -260,7 +265,7 @@ static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output) } } - for (size_t i = 0; i < MEM / sizeof(__m128i); i += 8) { + for (size_t i = 0; i < props.memory() / sizeof(__m128i); i += 8) { aes_round(k0, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); aes_round(k1, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); aes_round(k2, &xin0, &xin1, &xin2, &xin3, &xin4, &xin5, &xin6, &xin7); @@ -284,37 +289,17 @@ static inline void cn_explode_scratchpad(const __m128i *input, __m128i *output) } -#ifdef XMRIG_ALGO_CN_GPU -template -void cn_explode_scratchpad_gpu(const uint8_t *input, uint8_t *output) -{ - constexpr size_t hash_size = 200; // 25x8 bytes - alignas(16) uint64_t hash[25]; - - for (uint64_t i = 0; i < MEM / 512; i++) - { - memcpy(hash, input, hash_size); - hash[0] ^= i; - - xmrig::keccakf(hash, 24); - memcpy(output, hash, 160); - output += 160; - - xmrig::keccakf(hash, 24); - memcpy(output, hash, 176); - output += 176; - - xmrig::keccakf(hash, 24); - memcpy(output, hash, 176); - output += 176; - } -} -#endif - - -template +template static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) { + constexpr CnAlgo props; + +# ifdef XMRIG_ALGO_CN_GPU + constexpr bool IS_HEAVY = props.isHeavy() || ALGO == Algorithm::CN_GPU; +# else + constexpr bool IS_HEAVY = props.isHeavy(); +# endif + __m128i xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7; __m128i k0, k1, k2, k3, k4, k5, k6, k7, k8, k9; @@ -329,8 +314,7 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) xout6 = _mm_load_si128(output + 10); xout7 = _mm_load_si128(output + 11); - for (size_t i = 0; i < MEM / sizeof(__m128i); i += 8) - { + for (size_t i = 0; i < props.memory() / sizeof(__m128i); i += 8) { xout0 = _mm_xor_si128(_mm_load_si128(input + i + 0), xout0); xout1 = _mm_xor_si128(_mm_load_si128(input + i + 1), xout1); xout2 = _mm_xor_si128(_mm_load_si128(input + i + 2), xout2); @@ -351,13 +335,13 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) aes_round(k8, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); aes_round(k9, &xout0, &xout1, &xout2, &xout3, &xout4, &xout5, &xout6, &xout7); - if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { + if (IS_HEAVY) { mix_and_propagate(xout0, xout1, xout2, xout3, xout4, xout5, xout6, xout7); } } - if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { - for (size_t i = 0; i < MEM / sizeof(__m128i); i += 8) { + if (IS_HEAVY) { + for (size_t i = 0; i < props.memory() / sizeof(__m128i); i += 8) { xout0 = _mm_xor_si128(_mm_load_si128(input + i + 0), xout0); xout1 = _mm_xor_si128(_mm_load_si128(input + i + 1), xout1); xout2 = _mm_xor_si128(_mm_load_si128(input + i + 2), xout2); @@ -408,6 +392,9 @@ static inline void cn_implode_scratchpad(const __m128i *input, __m128i *output) } +} /* namespace xmrig */ + + static inline __m128i aes_round_tweak_div(const __m128i &in, const __m128i &key) { alignas(16) uint32_t k[4]; @@ -430,13 +417,18 @@ static inline __m128i aes_round_tweak_div(const __m128i &in, const __m128i &key) } -template +namespace xmrig { + + +template static inline void cryptonight_monero_tweak(const uint8_t* l, uint64_t idx, __m128i ax0, __m128i bx0, __m128i bx1, __m128i& cx) { + constexpr CnAlgo props; + uint64_t* mem_out = (uint64_t*)&l[idx]; - if (BASE == xmrig::VARIANT_2) { - VARIANT2_SHUFFLE(l, idx, ax0, bx0, bx1, cx, (VARIANT == xmrig::VARIANT_RWZ ? 1 : 0)); + if (props.base() == Algorithm::CN_2) { + VARIANT2_SHUFFLE(l, idx, ax0, bx0, bx1, cx, (ALGO == Algorithm::CN_RWZ ? 1 : 0)); _mm_store_si128((__m128i *)mem_out, _mm_xor_si128(bx0, cx)); } else { __m128i tmp = _mm_xor_si128(bx0, cx); @@ -446,7 +438,7 @@ static inline void cryptonight_monero_tweak(const uint8_t* l, uint64_t idx, __m1 uint8_t x = vh >> 24; static const uint16_t table = 0x7531; - const uint8_t index = (((x >> (VARIANT == xmrig::VARIANT_XTL ? 4 : 3)) & 6) | (x & 1)) << 1; + const uint8_t index = (((x >> (3)) & 6) | (x & 1)) << 1; vh ^= ((table >> index) & 0x3) << 28; mem_out[1] = vh; @@ -454,24 +446,28 @@ static inline void cryptonight_monero_tweak(const uint8_t* l, uint64_t idx, __m1 } -template +template inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx, uint64_t height) { - constexpr size_t MASK = xmrig::cn_select_mask(); - constexpr size_t ITERATIONS = xmrig::cn_select_iter(); - constexpr size_t MEM = xmrig::cn_select_memory(); - constexpr xmrig::Variant BASE = xmrig::cn_base_variant(); + constexpr CnAlgo props; + constexpr size_t MASK = props.mask(); + constexpr Algorithm::Id BASE = props.base(); - if (BASE == xmrig::VARIANT_1 && size < 43) { +# ifdef XMRIG_ALGO_CN_HEAVY + constexpr bool IS_CN_HEAVY_TUBE = ALGO == Algorithm::CN_HEAVY_TUBE; +# else + constexpr bool IS_CN_HEAVY_TUBE = false; +# endif + + if (BASE == Algorithm::CN_1 && size < 43) { memset(output, 0, 32); return; } - xmrig::keccak(input, size, ctx[0]->state); + keccak(input, size, ctx[0]->state); + cn_explode_scratchpad(reinterpret_cast(ctx[0]->state), reinterpret_cast<__m128i *>(ctx[0]->memory)); - cn_explode_scratchpad((__m128i*) ctx[0]->state, (__m128i*) ctx[0]->memory); - - const uint8_t* l0 = ctx[0]->memory; + uint8_t* l0 = ctx[0]->memory; uint64_t* h0 = reinterpret_cast(ctx[0]->state); VARIANT1_INIT(0); @@ -480,19 +476,19 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si uint64_t al0 = h0[0] ^ h0[4]; uint64_t ah0 = h0[1] ^ h0[5]; - __m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); - __m128i bx1 = _mm_set_epi64x(h0[9] ^ h0[11], h0[8] ^ h0[10]); + __m128i bx0 = _mm_set_epi64x(h0[3] ^ h0[7], h0[2] ^ h0[6]); + __m128i bx1 = _mm_set_epi64x(h0[9] ^ h0[11], h0[8] ^ h0[10]); uint64_t idx0 = al0; - for (size_t i = 0; i < ITERATIONS; i++) { + for (size_t i = 0; i < props.iterations(); i++) { __m128i cx; - if (VARIANT == xmrig::VARIANT_TUBE || !SOFT_AES) { - cx = _mm_load_si128((__m128i *) &l0[idx0 & MASK]); + if (IS_CN_HEAVY_TUBE || !SOFT_AES) { + cx = _mm_load_si128(reinterpret_cast(&l0[idx0 & MASK])); } const __m128i ax0 = _mm_set_epi64x(ah0, al0); - if (VARIANT == xmrig::VARIANT_TUBE) { + if (IS_CN_HEAVY_TUBE) { cx = aes_round_tweak_div(cx, ax0); } else if (SOFT_AES) { @@ -502,8 +498,8 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si cx = _mm_aesenc_si128(cx, ax0); } - if (BASE == xmrig::VARIANT_1 || BASE == xmrig::VARIANT_2) { - cryptonight_monero_tweak(l0, idx0 & MASK, ax0, bx0, bx1, cx); + if (BASE == Algorithm::CN_1 || BASE == Algorithm::CN_2) { + cryptonight_monero_tweak(l0, idx0 & MASK, ax0, bx0, bx1, cx); } else { _mm_store_si128((__m128i *)&l0[idx0 & MASK], _mm_xor_si128(bx0, cx)); } @@ -514,10 +510,10 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si cl = ((uint64_t*) &l0[idx0 & MASK])[0]; ch = ((uint64_t*) &l0[idx0 & MASK])[1]; - if (BASE == xmrig::VARIANT_2) { - if ((VARIANT == xmrig::VARIANT_WOW) || (VARIANT == xmrig::VARIANT_4)) { + if (BASE == Algorithm::CN_2) { + if (props.isR()) { VARIANT4_RANDOM_MATH(0, al0, ah0, cl, bx0, bx1); - if (VARIANT == xmrig::VARIANT_4) { + if (ALGO == Algorithm::CN_R) { al0 ^= r0[2] | ((uint64_t)(r0[3]) << 32); ah0 ^= r0[0] | ((uint64_t)(r0[1]) << 32); } @@ -528,11 +524,11 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si lo = __umul128(idx0, cl, &hi); - if (BASE == xmrig::VARIANT_2) { - if (VARIANT == xmrig::VARIANT_4) { + if (BASE == Algorithm::CN_2) { + if (ALGO == Algorithm::CN_R) { VARIANT2_SHUFFLE(l0, idx0 & MASK, ax0, bx0, bx1, cx, 0); } else { - VARIANT2_SHUFFLE2(l0, idx0 & MASK, ax0, bx0, bx1, hi, lo, (VARIANT == xmrig::VARIANT_RWZ ? 1 : 0)); + VARIANT2_SHUFFLE2(l0, idx0 & MASK, ax0, bx0, bx1, hi, lo, (ALGO == Algorithm::CN_RWZ ? 1 : 0)); } } @@ -541,9 +537,9 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si ((uint64_t*)&l0[idx0 & MASK])[0] = al0; - if (BASE == xmrig::VARIANT_1 && (VARIANT == xmrig::VARIANT_TUBE || VARIANT == xmrig::VARIANT_RTO)) { + if (IS_CN_HEAVY_TUBE || ALGO == Algorithm::CN_RTO) { ((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0 ^ al0; - } else if (BASE == xmrig::VARIANT_1) { + } else if (BASE == Algorithm::CN_1) { ((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0; } else { ((uint64_t*)&l0[idx0 & MASK])[1] = ah0; @@ -553,7 +549,8 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si ah0 ^= ch; idx0 = al0; - if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { +# ifdef XMRIG_ALGO_CN_HEAVY + if (props.isHeavy()) { const int64x2_t x = vld1q_s64(reinterpret_cast(&l0[idx0 & MASK])); const int64_t n = vgetq_lane_s64(x, 0); const int32_t d = vgetq_lane_s32(x, 2); @@ -561,77 +558,113 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si ((int64_t*)&l0[idx0 & MASK])[0] = n ^ q; - if (VARIANT == xmrig::VARIANT_XHV) { + if (ALGO == Algorithm::CN_HEAVY_XHV) { idx0 = (~d) ^ q; } else { idx0 = d ^ q; } } +# endif - if (BASE == xmrig::VARIANT_2) { + if (BASE == Algorithm::CN_2) { bx1 = bx0; } bx0 = cx; } - cn_implode_scratchpad((__m128i*) ctx[0]->memory, (__m128i*) ctx[0]->state); - - xmrig::keccakf(h0, 24); + cn_implode_scratchpad(reinterpret_cast(ctx[0]->memory), reinterpret_cast<__m128i *>(ctx[0]->state)); + keccakf(h0, 24); extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output); } +} /* namespace xmrig */ + + #ifdef XMRIG_ALGO_CN_GPU template void cn_gpu_inner_arm(const uint8_t *spad, uint8_t *lpad); -template +namespace xmrig { + + +template +void cn_explode_scratchpad_gpu(const uint8_t *input, uint8_t *output) +{ + constexpr size_t hash_size = 200; // 25x8 bytes + alignas(16) uint64_t hash[25]; + + for (uint64_t i = 0; i < MEM / 512; i++) { + memcpy(hash, input, hash_size); + hash[0] ^= i; + + xmrig::keccakf(hash, 24); + memcpy(output, hash, 160); + output += 160; + + xmrig::keccakf(hash, 24); + memcpy(output, hash, 176); + output += 176; + + xmrig::keccakf(hash, 24); + memcpy(output, hash, 176); + output += 176; + } +} + + +template inline void cryptonight_single_hash_gpu(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx, uint64_t height) { - constexpr size_t MASK = xmrig::CRYPTONIGHT_GPU_MASK; - constexpr size_t ITERATIONS = xmrig::cn_select_iter(); - constexpr size_t MEM = xmrig::cn_select_memory(); + constexpr CnAlgo props; - static_assert(MASK > 0 && ITERATIONS > 0 && MEM > 0, "unsupported algorithm/variant"); - - xmrig::keccak(input, size, ctx[0]->state); - cn_explode_scratchpad_gpu(ctx[0]->state, ctx[0]->memory); + keccak(input, size, ctx[0]->state); + cn_explode_scratchpad_gpu(ctx[0]->state, ctx[0]->memory); fesetround(FE_TONEAREST); - cn_gpu_inner_arm(ctx[0]->state, ctx[0]->memory); + cn_gpu_inner_arm(ctx[0]->state, ctx[0]->memory); - cn_implode_scratchpad((__m128i*) ctx[0]->memory, (__m128i*) ctx[0]->state); - - xmrig::keccakf((uint64_t*) ctx[0]->state, 24); + cn_implode_scratchpad(reinterpret_cast(ctx[0]->memory), reinterpret_cast<__m128i *>(ctx[0]->state)); + keccakf(reinterpret_cast(ctx[0]->state), 24); memcpy(output, ctx[0]->state, 32); } + +} /* namespace xmrig */ #endif -template +namespace xmrig { + + +template inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx **__restrict__ ctx, uint64_t height) { - constexpr size_t MASK = xmrig::cn_select_mask(); - constexpr size_t ITERATIONS = xmrig::cn_select_iter(); - constexpr size_t MEM = xmrig::cn_select_memory(); - constexpr xmrig::Variant BASE = xmrig::cn_base_variant(); + constexpr CnAlgo props; + constexpr size_t MASK = props.mask(); + constexpr Algorithm::Id BASE = props.base(); - if (BASE == xmrig::VARIANT_1 && size < 43) { +# ifdef XMRIG_ALGO_CN_HEAVY + constexpr bool IS_CN_HEAVY_TUBE = ALGO == Algorithm::CN_HEAVY_TUBE; +# else + constexpr bool IS_CN_HEAVY_TUBE = false; +# endif + + if (BASE == Algorithm::CN_1 && size < 43) { memset(output, 0, 64); return; } - xmrig::keccak(input, size, ctx[0]->state); - xmrig::keccak(input + size, size, ctx[1]->state); + keccak(input, size, ctx[0]->state); + keccak(input + size, size, ctx[1]->state); - const uint8_t* l0 = ctx[0]->memory; - const uint8_t* l1 = ctx[1]->memory; - uint64_t* h0 = reinterpret_cast(ctx[0]->state); - uint64_t* h1 = reinterpret_cast(ctx[1]->state); + uint8_t *l0 = ctx[0]->memory; + uint8_t *l1 = ctx[1]->memory; + uint64_t *h0 = reinterpret_cast(ctx[0]->state); + uint64_t *h1 = reinterpret_cast(ctx[1]->state); VARIANT1_INIT(0); VARIANT1_INIT(1); @@ -640,8 +673,8 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si VARIANT4_RANDOM_MATH_INIT(0); VARIANT4_RANDOM_MATH_INIT(1); - cn_explode_scratchpad((__m128i*) h0, (__m128i*) l0); - cn_explode_scratchpad((__m128i*) h1, (__m128i*) l1); + cn_explode_scratchpad(reinterpret_cast(h0), reinterpret_cast<__m128i *>(l0)); + cn_explode_scratchpad(reinterpret_cast(h1), reinterpret_cast<__m128i *>(l1)); uint64_t al0 = h0[0] ^ h0[4]; uint64_t al1 = h1[0] ^ h1[4]; @@ -656,16 +689,16 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si uint64_t idx0 = al0; uint64_t idx1 = al1; - for (size_t i = 0; i < ITERATIONS; i++) { + for (size_t i = 0; i < props.iterations(); i++) { __m128i cx0, cx1; - if (VARIANT == xmrig::VARIANT_TUBE || !SOFT_AES) { + if (IS_CN_HEAVY_TUBE || !SOFT_AES) { cx0 = _mm_load_si128((__m128i *) &l0[idx0 & MASK]); cx1 = _mm_load_si128((__m128i *) &l1[idx1 & MASK]); } const __m128i ax0 = _mm_set_epi64x(ah0, al0); const __m128i ax1 = _mm_set_epi64x(ah1, al1); - if (VARIANT == xmrig::VARIANT_TUBE) { + if (IS_CN_HEAVY_TUBE) { cx0 = aes_round_tweak_div(cx0, ax0); cx1 = aes_round_tweak_div(cx1, ax1); } @@ -678,9 +711,9 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si cx1 = _mm_aesenc_si128(cx1, ax1); } - if (BASE == xmrig::VARIANT_1 || (BASE == xmrig::VARIANT_2)) { - cryptonight_monero_tweak(l0, idx0 & MASK, ax0, bx00, bx01, cx0); - cryptonight_monero_tweak(l1, idx1 & MASK, ax1, bx10, bx11, cx1); + if (BASE == Algorithm::CN_1 || BASE == Algorithm::CN_2) { + cryptonight_monero_tweak(l0, idx0 & MASK, ax0, bx00, bx01, cx0); + cryptonight_monero_tweak(l1, idx1 & MASK, ax1, bx10, bx11, cx1); } else { _mm_store_si128((__m128i *) &l0[idx0 & MASK], _mm_xor_si128(bx00, cx0)); _mm_store_si128((__m128i *) &l1[idx1 & MASK], _mm_xor_si128(bx10, cx1)); @@ -693,10 +726,10 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si cl = ((uint64_t*) &l0[idx0 & MASK])[0]; ch = ((uint64_t*) &l0[idx0 & MASK])[1]; - if (BASE == xmrig::VARIANT_2) { - if ((VARIANT == xmrig::VARIANT_WOW) || (VARIANT == xmrig::VARIANT_4)) { + if (BASE == Algorithm::CN_2) { + if (props.isR()) { VARIANT4_RANDOM_MATH(0, al0, ah0, cl, bx00, bx01); - if (VARIANT == xmrig::VARIANT_4) { + if (ALGO == Algorithm::CN_R) { al0 ^= r0[2] | ((uint64_t)(r0[3]) << 32); ah0 ^= r0[0] | ((uint64_t)(r0[1]) << 32); } @@ -707,11 +740,11 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si lo = __umul128(idx0, cl, &hi); - if (BASE == xmrig::VARIANT_2) { - if (VARIANT == xmrig::VARIANT_4) { + if (BASE == Algorithm::CN_2) { + if (ALGO == Algorithm::CN_R) { VARIANT2_SHUFFLE(l0, idx0 & MASK, ax0, bx00, bx01, cx0, 0); } else { - VARIANT2_SHUFFLE2(l0, idx0 & MASK, ax0, bx00, bx01, hi, lo, (VARIANT == xmrig::VARIANT_RWZ ? 1 : 0)); + VARIANT2_SHUFFLE2(l0, idx0 & MASK, ax0, bx00, bx01, hi, lo, (ALGO == Algorithm::CN_RWZ ? 1 : 0)); } } @@ -720,9 +753,9 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si ((uint64_t*)&l0[idx0 & MASK])[0] = al0; - if (BASE == xmrig::VARIANT_1 && (VARIANT == xmrig::VARIANT_TUBE || VARIANT == xmrig::VARIANT_RTO)) { + if (IS_CN_HEAVY_TUBE || ALGO == Algorithm::CN_RTO) { ((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0 ^ al0; - } else if (BASE == xmrig::VARIANT_1) { + } else if (BASE == Algorithm::CN_1) { ((uint64_t*)&l0[idx0 & MASK])[1] = ah0 ^ tweak1_2_0; } else { ((uint64_t*)&l0[idx0 & MASK])[1] = ah0; @@ -732,7 +765,8 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si ah0 ^= ch; idx0 = al0; - if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { +# ifdef XMRIG_ALGO_CN_HEAVY + if (props.isHeavy()) { const int64x2_t x = vld1q_s64(reinterpret_cast(&l0[idx0 & MASK])); const int64_t n = vgetq_lane_s64(x, 0); const int32_t d = vgetq_lane_s32(x, 2); @@ -740,21 +774,22 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si ((int64_t*)&l0[idx0 & MASK])[0] = n ^ q; - if (VARIANT == xmrig::VARIANT_XHV) { + if (ALGO == Algorithm::CN_HEAVY_XHV) { idx0 = (~d) ^ q; } else { idx0 = d ^ q; } } +# endif cl = ((uint64_t*) &l1[idx1 & MASK])[0]; ch = ((uint64_t*) &l1[idx1 & MASK])[1]; - if (BASE == xmrig::VARIANT_2) { - if ((VARIANT == xmrig::VARIANT_WOW) || (VARIANT == xmrig::VARIANT_4)) { + if (BASE == Algorithm::CN_2) { + if (props.isR()) { VARIANT4_RANDOM_MATH(1, al1, ah1, cl, bx10, bx11); - if (VARIANT == xmrig::VARIANT_4) { + if (ALGO == Algorithm::CN_R) { al1 ^= r1[2] | ((uint64_t)(r1[3]) << 32); ah1 ^= r1[0] | ((uint64_t)(r1[1]) << 32); } @@ -765,11 +800,11 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si lo = __umul128(idx1, cl, &hi); - if (BASE == xmrig::VARIANT_2) { - if (VARIANT == xmrig::VARIANT_4) { + if (BASE == Algorithm::CN_2) { + if (ALGO == Algorithm::CN_R) { VARIANT2_SHUFFLE(l1, idx1 & MASK, ax1, bx10, bx11, cx1, 0); } else { - VARIANT2_SHUFFLE2(l1, idx1 & MASK, ax1, bx10, bx11, hi, lo, (VARIANT == xmrig::VARIANT_RWZ ? 1 : 0)); + VARIANT2_SHUFFLE2(l1, idx1 & MASK, ax1, bx10, bx11, hi, lo, (ALGO == Algorithm::CN_RWZ ? 1 : 0)); } } @@ -778,9 +813,9 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si ((uint64_t*)&l1[idx1 & MASK])[0] = al1; - if (BASE == xmrig::VARIANT_1 && (VARIANT == xmrig::VARIANT_TUBE || VARIANT == xmrig::VARIANT_RTO)) { + if (IS_CN_HEAVY_TUBE || ALGO == Algorithm::CN_RTO) { ((uint64_t*)&l1[idx1 & MASK])[1] = ah1 ^ tweak1_2_1 ^ al1; - } else if (BASE == xmrig::VARIANT_1) { + } else if (BASE == Algorithm::CN_1) { ((uint64_t*)&l1[idx1 & MASK])[1] = ah1 ^ tweak1_2_1; } else { ((uint64_t*)&l1[idx1 & MASK])[1] = ah1; @@ -790,7 +825,8 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si ah1 ^= ch; idx1 = al1; - if (ALGO == xmrig::CRYPTONIGHT_HEAVY) { +# ifdef XMRIG_ALGO_CN_HEAVY + if (props.isHeavy()) { const int64x2_t x = vld1q_s64(reinterpret_cast(&l1[idx1 & MASK])); const int64_t n = vgetq_lane_s64(x, 0); const int32_t d = vgetq_lane_s32(x, 2); @@ -798,47 +834,54 @@ inline void cryptonight_double_hash(const uint8_t *__restrict__ input, size_t si ((int64_t*)&l1[idx1 & MASK])[0] = n ^ q; - if (VARIANT == xmrig::VARIANT_XHV) { + if (ALGO == Algorithm::CN_HEAVY_XHV) { idx1 = (~d) ^ q; } else { idx1 = d ^ q; } } - if (BASE == xmrig::VARIANT_2) { +# endif + + if (BASE == Algorithm::CN_2) { bx01 = bx00; bx11 = bx10; } + bx00 = cx0; bx10 = cx1; } - cn_implode_scratchpad((__m128i*) l0, (__m128i*) h0); - cn_implode_scratchpad((__m128i*) l1, (__m128i*) h1); + cn_implode_scratchpad(reinterpret_cast(l0), reinterpret_cast<__m128i *>(h0)); + cn_implode_scratchpad(reinterpret_cast(l1), reinterpret_cast<__m128i *>(h1)); - xmrig::keccakf(h0, 24); - xmrig::keccakf(h1, 24); + keccakf(h0, 24); + keccakf(h1, 24); extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output); extra_hashes[ctx[1]->state[0] & 3](ctx[1]->state, 200, output + 32); } -template +template inline void cryptonight_triple_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx **__restrict__ ctx, uint64_t height) { } -template +template inline void cryptonight_quad_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx **__restrict__ ctx, uint64_t height) { } -template +template inline void cryptonight_penta_hash(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, struct cryptonight_ctx **__restrict__ ctx, uint64_t height) { } -#endif /* __CRYPTONIGHT_ARM_H__ */ + +} /* namespace xmrig */ + + +#endif /* XMRIG_CRYPTONIGHT_ARM_H */ diff --git a/src/crypto/cn/CryptoNight_monero.h b/src/crypto/cn/CryptoNight_monero.h index 259cb3b6..13948dcd 100644 --- a/src/crypto/cn/CryptoNight_monero.h +++ b/src/crypto/cn/CryptoNight_monero.h @@ -141,7 +141,7 @@ vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x10)), vaddq_u64(chunk3, vreinterpretq_u64_u8(_b1))); \ vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x20)), vaddq_u64(chunk1, vreinterpretq_u64_u8(_b))); \ vst1q_u64((uint64_t*)((base_ptr) + ((offset) ^ 0x30)), vaddq_u64(chunk2, vreinterpretq_u64_u8(_a))); \ - if (ALGO == Algorithm::CN_4) { \ + if (ALGO == Algorithm::CN_R) { \ _c = veorq_u64(veorq_u64(_c, chunk3), veorq_u64(chunk1, chunk2)); \ } \ } while (0) diff --git a/src/crypto/cn/gpu/cn_gpu_arm.cpp b/src/crypto/cn/gpu/cn_gpu_arm.cpp index a1df0cc7..520d3fc8 100644 --- a/src/crypto/cn/gpu/cn_gpu_arm.cpp +++ b/src/crypto/cn/gpu/cn_gpu_arm.cpp @@ -26,7 +26,7 @@ #include -#include "crypto/cn/CryptoNight_constants.h" +#include "crypto/cn/CnAlgo.h" inline void vandq_f32(float32x4_t &v, uint32_t v2) @@ -237,4 +237,4 @@ void cn_gpu_inner_arm(const uint8_t *spad, uint8_t *lpad) } } -template void cn_gpu_inner_arm(const uint8_t* spad, uint8_t* lpad); +template void cn_gpu_inner_arm().iterations(), xmrig::CnAlgo().mask()>(const uint8_t* spad, uint8_t* lpad); From 69903246812919f12ad1fa6f5fdae888da74c62b Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 16 Jun 2019 03:50:22 +0700 Subject: [PATCH 05/48] Allow null algorithm for pools. --- src/base/net/stratum/Client.cpp | 36 ++++++++++++++++----------------- src/base/net/stratum/Pool.cpp | 36 +++++++++++++++++++++------------ src/base/net/stratum/Pools.cpp | 2 +- src/crypto/common/Algorithm.cpp | 9 +++++++++ src/crypto/common/Algorithm.h | 5 +++++ 5 files changed, 56 insertions(+), 32 deletions(-) diff --git a/src/base/net/stratum/Client.cpp b/src/base/net/stratum/Client.cpp index 05e53c78..4234407c 100644 --- a/src/base/net/stratum/Client.cpp +++ b/src/base/net/stratum/Client.cpp @@ -421,28 +421,28 @@ bool xmrig::Client::send(BIO *bio) bool xmrig::Client::verifyAlgorithm(const Algorithm &algorithm) const { -# ifdef XMRIG_PROXY_PROJECT - if (m_pool.algorithm().variant() == VARIANT_AUTO || m_id == -1) { - return true; - } -# endif +//# ifdef XMRIG_PROXY_PROJECT +// if (m_pool.algorithm().variant() == VARIANT_AUTO || m_id == -1) { +// return true; +// } +//# endif - if (m_pool.algorithm() == algorithm) { // FIXME - return true; - } +// if (m_pool.algorithm() == algorithm) { // FIXME +// return true; +// } - if (isQuiet()) { - return false; - } +// if (isQuiet()) { +// return false; +// } - if (algorithm.isValid()) { - LOG_ERR("Incompatible algorithm \"%s\" detected, reconnect", algorithm.name()); - } - else { - LOG_ERR("Unknown/unsupported algorithm detected, reconnect"); - } +// if (algorithm.isValid()) { +// LOG_ERR("Incompatible algorithm \"%s\" detected, reconnect", algorithm.name()); +// } +// else { +// LOG_ERR("Unknown/unsupported algorithm detected, reconnect"); +// } - return false; + return true; } diff --git a/src/base/net/stratum/Pool.cpp b/src/base/net/stratum/Pool.cpp index bb3fab72..b11e1159 100644 --- a/src/base/net/stratum/Pool.cpp +++ b/src/base/net/stratum/Pool.cpp @@ -172,7 +172,11 @@ bool xmrig::Pool::isEnabled() const } # endif - return m_flags.test(FLAG_ENABLED) && isValid() && algorithm().isValid(); + if (isDaemon() && !algorithm().isValid()) { + return false; + } + + return m_flags.test(FLAG_ENABLED) && isValid(); } @@ -259,28 +263,34 @@ rapidjson::Value xmrig::Pool::toJSON(rapidjson::Document &doc) const Value obj(kObjectType); - obj.AddMember(StringRef(kAlgo), StringRef(m_algorithm.shortName()), allocator); + obj.AddMember(StringRef(kAlgo), m_algorithm.toJSON(), allocator); obj.AddMember(StringRef(kUrl), m_url.toJSON(), allocator); obj.AddMember(StringRef(kUser), m_user.toJSON(), allocator); - obj.AddMember(StringRef(kPass), m_password.toJSON(), allocator); - obj.AddMember(StringRef(kRigId), m_rigId.toJSON(), allocator); -# ifndef XMRIG_PROXY_PROJECT - obj.AddMember(StringRef(kNicehash), isNicehash(), allocator); -# endif + if (!isDaemon()) { + obj.AddMember(StringRef(kPass), m_password.toJSON(), allocator); + obj.AddMember(StringRef(kRigId), m_rigId.toJSON(), allocator); - if (m_keepAlive == 0 || m_keepAlive == kKeepAliveTimeout) { - obj.AddMember(StringRef(kKeepalive), m_keepAlive > 0, allocator); - } - else { - obj.AddMember(StringRef(kKeepalive), m_keepAlive, allocator); +# ifndef XMRIG_PROXY_PROJECT + obj.AddMember(StringRef(kNicehash), isNicehash(), allocator); +# endif + + if (m_keepAlive == 0 || m_keepAlive == kKeepAliveTimeout) { + obj.AddMember(StringRef(kKeepalive), m_keepAlive > 0, allocator); + } + else { + obj.AddMember(StringRef(kKeepalive), m_keepAlive, allocator); + } } obj.AddMember(StringRef(kEnabled), m_flags.test(FLAG_ENABLED), allocator); obj.AddMember(StringRef(kTls), isTLS(), allocator); obj.AddMember(StringRef(kFingerprint), m_fingerprint.toJSON(), allocator); obj.AddMember(StringRef(kDaemon), m_flags.test(FLAG_DAEMON), allocator); - obj.AddMember(StringRef(kDaemonPollInterval), m_pollInterval, allocator); + + if (isDaemon()) { + obj.AddMember(StringRef(kDaemonPollInterval), m_pollInterval, allocator); + } return obj; } diff --git a/src/base/net/stratum/Pools.cpp b/src/base/net/stratum/Pools.cpp index 985e5d4e..4641ecd4 100644 --- a/src/base/net/stratum/Pools.cpp +++ b/src/base/net/stratum/Pools.cpp @@ -139,7 +139,7 @@ void xmrig::Pools::print() const i, (pool.isEnabled() ? (pool.isTLS() ? 32 : 36) : 31), pool.url().data(), - pool.algorithm().shortName() + pool.algorithm().isValid() ? pool.algorithm().shortName() : "auto" ); i++; diff --git a/src/crypto/common/Algorithm.cpp b/src/crypto/common/Algorithm.cpp index 78272f79..b2f93896 100644 --- a/src/crypto/common/Algorithm.cpp +++ b/src/crypto/common/Algorithm.cpp @@ -31,6 +31,7 @@ #include "crypto/common/Algorithm.h" +#include "rapidjson/document.h" #ifdef _MSC_VER @@ -111,6 +112,14 @@ static AlgoName const algorithm_names[] = { } /* namespace xmrig */ +rapidjson::Value xmrig::Algorithm::toJSON() const +{ + using namespace rapidjson; + + return isValid() ? Value(StringRef(shortName())) : Value(kNullType); +} + + xmrig::Algorithm::Family xmrig::Algorithm::family(Id id) { switch (id) { diff --git a/src/crypto/common/Algorithm.h b/src/crypto/common/Algorithm.h index c9388dee..690814e7 100644 --- a/src/crypto/common/Algorithm.h +++ b/src/crypto/common/Algorithm.h @@ -30,6 +30,9 @@ #include +#include "rapidjson/fwd.h" + + namespace xmrig { @@ -91,6 +94,8 @@ public: inline bool operator==(const Algorithm &other) const { return isEqual(other); } inline operator Algorithm::Id() const { return m_id; } + rapidjson::Value toJSON() const; + static Family family(Id id); static Id parse(const char *name); From b38e432647e41accf7a8f5f10a261592d9a10217 Mon Sep 17 00:00:00 2001 From: XMRig Date: Mon, 17 Jun 2019 04:06:38 +0700 Subject: [PATCH 06/48] Moved keccak files. --- CMakeLists.txt | 4 ++-- src/api/Api.cpp | 2 +- src/crypto/cn/CryptoNight_arm.h | 2 +- src/crypto/cn/CryptoNight_x86.h | 5 ++++- src/{common/crypto => crypto/common}/keccak.cpp | 2 +- src/{common/crypto => crypto/common}/keccak.h | 0 src/net/strategies/DonateStrategy.cpp | 2 +- 7 files changed, 10 insertions(+), 7 deletions(-) rename src/{common/crypto => crypto/common}/keccak.cpp (99%) rename src/{common/crypto => crypto/common}/keccak.h (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c70a673..2dfd52e0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,7 +25,6 @@ set(HEADERS src/api/interfaces/IApiListener.h src/App.h src/common/cpu/Cpu.h - src/common/crypto/keccak.h src/common/interfaces/ICpuInfo.h src/common/Platform.h src/common/xmrig.h @@ -69,6 +68,7 @@ set(HEADERS_CRYPTO src/crypto/cn/skein_port.h src/crypto/cn/soft_aes.h src/crypto/common/Algorithm.h + src/crypto/common/keccak.h src/crypto/common/portable/mm_malloc.h src/crypto/common/VirtualMemory.h ) @@ -83,7 +83,6 @@ set(SOURCES "${SOURCES_BASE}" "${SOURCES_BASE_HTTP}" src/App.cpp - src/common/crypto/keccak.cpp src/common/Platform.cpp src/core/config/Config.cpp src/core/config/ConfigTransform.cpp @@ -109,6 +108,7 @@ set(SOURCES_CRYPTO src/crypto/cn/c_skein.c src/crypto/cn/CnHash.cpp src/crypto/common/Algorithm.cpp + src/crypto/common/keccak.cpp ) if (WIN32) diff --git a/src/api/Api.cpp b/src/api/Api.cpp index a11325f3..caebcba7 100644 --- a/src/api/Api.cpp +++ b/src/api/Api.cpp @@ -39,9 +39,9 @@ #include "base/kernel/Base.h" #include "base/tools/Buffer.h" #include "base/tools/Chrono.h" -#include "common/crypto/keccak.h" #include "core/config/Config.h" #include "core/Controller.h" +#include "crypto/common/keccak.h" #include "version.h" diff --git a/src/crypto/cn/CryptoNight_arm.h b/src/crypto/cn/CryptoNight_arm.h index 6d56b548..02266634 100644 --- a/src/crypto/cn/CryptoNight_arm.h +++ b/src/crypto/cn/CryptoNight_arm.h @@ -28,11 +28,11 @@ #define XMRIG_CRYPTONIGHT_ARM_H -#include "common/crypto/keccak.h" #include "crypto/cn/CnAlgo.h" #include "crypto/cn/CryptoNight_monero.h" #include "crypto/cn/CryptoNight.h" #include "crypto/cn/soft_aes.h" +#include "crypto/common/keccak.h" #include "crypto/common/portable/mm_malloc.h" diff --git a/src/crypto/cn/CryptoNight_x86.h b/src/crypto/cn/CryptoNight_x86.h index 994ee116..fc21c7b0 100644 --- a/src/crypto/cn/CryptoNight_x86.h +++ b/src/crypto/cn/CryptoNight_x86.h @@ -36,11 +36,11 @@ #include "common/cpu/Cpu.h" -#include "common/crypto/keccak.h" #include "crypto/cn/CnAlgo.h" #include "crypto/cn/CryptoNight_monero.h" #include "crypto/cn/CryptoNight.h" #include "crypto/cn/soft_aes.h" +#include "crypto/common/keccak.h" extern "C" @@ -785,6 +785,9 @@ extern "C" void cnv2_rwz_double_mainloop_asm(cryptonight_ctx **ctx); namespace xmrig { +typedef void (*cn_mainloop_fun)(cryptonight_ctx **ctx); + + extern cn_mainloop_fun cn_half_mainloop_ivybridge_asm; extern cn_mainloop_fun cn_half_mainloop_ryzen_asm; extern cn_mainloop_fun cn_half_mainloop_bulldozer_asm; diff --git a/src/common/crypto/keccak.cpp b/src/crypto/common/keccak.cpp similarity index 99% rename from src/common/crypto/keccak.cpp rename to src/crypto/common/keccak.cpp index 0219ce36..132ae0a8 100644 --- a/src/common/crypto/keccak.cpp +++ b/src/crypto/common/keccak.cpp @@ -27,7 +27,7 @@ #include -#include "common/crypto/keccak.h" +#include "crypto/common/keccak.h" #define HASH_DATA_AREA 136 diff --git a/src/common/crypto/keccak.h b/src/crypto/common/keccak.h similarity index 100% rename from src/common/crypto/keccak.h rename to src/crypto/common/keccak.h diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp index 3d913087..9669db9a 100644 --- a/src/net/strategies/DonateStrategy.cpp +++ b/src/net/strategies/DonateStrategy.cpp @@ -32,11 +32,11 @@ #include "base/net/stratum/strategies/SinglePoolStrategy.h" #include "base/tools/Buffer.h" #include "base/tools/Timer.h" -#include "common/crypto/keccak.h" #include "common/Platform.h" #include "common/xmrig.h" #include "core/config/Config.h" #include "core/Controller.h" +#include "crypto/common/keccak.h" #include "net/Network.h" #include "net/strategies/DonateStrategy.h" #include "rapidjson/document.h" From 66d62de681bde910eb7e36f3a3a58c49016f1430 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 28 Jun 2019 13:08:08 +0700 Subject: [PATCH 07/48] Merge Assembly enum and Asm class. --- cmake/asm.cmake | 6 +- src/Summary.cpp | 6 +- src/common/cpu/BasicCpuInfo.h | 2 +- src/common/interfaces/ICpuInfo.h | 6 +- src/common/xmrig.h | 10 --- src/core/config/Config.cpp | 7 +- src/core/cpu/AdvancedCpuInfo.cpp | 5 +- src/core/cpu/AdvancedCpuInfo.h | 2 +- src/crypto/cn/Asm.h | 50 ------------ src/crypto/cn/CnHash.cpp | 42 +++++----- src/crypto/cn/CnHash.h | 5 +- src/crypto/cn/CryptoNight_x86.h | 28 +++---- src/crypto/cn/r/CryptonightR_gen.cpp | 5 +- src/crypto/common/Algorithm.cpp | 1 - src/crypto/common/Algorithm.h | 2 +- .../{cn/Asm.cpp => common/Assembly.cpp} | 35 ++++---- src/crypto/common/Assembly.h | 79 +++++++++++++++++++ src/workers/CpuThread.cpp | 10 +-- src/workers/CpuThread.h | 2 +- 19 files changed, 164 insertions(+), 139 deletions(-) delete mode 100644 src/crypto/cn/Asm.h rename src/crypto/{cn/Asm.cpp => common/Assembly.cpp} (72%) create mode 100644 src/crypto/common/Assembly.h diff --git a/cmake/asm.cmake b/cmake/asm.cmake index d3010e51..e445defd 100644 --- a/cmake/asm.cmake +++ b/cmake/asm.cmake @@ -36,7 +36,11 @@ if (WITH_ASM AND NOT XMRIG_ARM AND CMAKE_SIZEOF_VOID_P EQUAL 8) endif() add_library(${XMRIG_ASM_LIBRARY} STATIC ${XMRIG_ASM_FILES}) - set(XMRIG_ASM_SOURCES src/crypto/cn/Asm.h src/crypto/cn/Asm.cpp src/crypto/cn/r/CryptonightR_gen.cpp) + set(XMRIG_ASM_SOURCES + src/crypto/common/Assembly.h + src/crypto/common/Assembly.cpp + src/crypto/cn/r/CryptonightR_gen.cpp + ) set_property(TARGET ${XMRIG_ASM_LIBRARY} PROPERTY LINKER_LANGUAGE C) add_definitions(/DXMRIG_FEATURE_ASM) diff --git a/src/Summary.cpp b/src/Summary.cpp index 2ba0fd57..13973c0f 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -33,7 +33,7 @@ #include "common/cpu/Cpu.h" #include "core/config/Config.h" #include "core/Controller.h" -#include "crypto/cn/Asm.h" +#include "crypto/common/Assembly.h" #include "Mem.h" #include "Summary.h" #include "version.h" @@ -49,7 +49,7 @@ static const char *coloredAsmNames[] = { }; -inline static const char *asmName(xmrig::Assembly assembly) +inline static const char *asmName(xmrig::Assembly::Id assembly) { return coloredAsmNames[assembly]; } @@ -109,7 +109,7 @@ static void print_threads(xmrig::Config *config) } # ifdef XMRIG_FEATURE_ASM - if (config->assembly() == xmrig::ASM_AUTO) { + if (config->assembly() == xmrig::Assembly::AUTO) { const xmrig::Assembly assembly = xmrig::Cpu::info()->assembly(); xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13sauto:%s"), "ASSEMBLY", asmName(assembly)); diff --git a/src/common/cpu/BasicCpuInfo.h b/src/common/cpu/BasicCpuInfo.h index 95857ed2..f6daee54 100644 --- a/src/common/cpu/BasicCpuInfo.h +++ b/src/common/cpu/BasicCpuInfo.h @@ -40,7 +40,7 @@ public: protected: size_t optimalThreadsCount(size_t memSize, int maxCpuUsage) const override; - inline Assembly assembly() const override { return m_assembly; } + inline Assembly::Id assembly() const override { return m_assembly; } inline bool hasAES() const override { return m_aes; } inline bool hasAVX2() const override { return m_avx2; } inline bool isSupported() const override { return true; } diff --git a/src/common/interfaces/ICpuInfo.h b/src/common/interfaces/ICpuInfo.h index dd4034b3..907f3f63 100644 --- a/src/common/interfaces/ICpuInfo.h +++ b/src/common/interfaces/ICpuInfo.h @@ -30,7 +30,7 @@ #include -#include "common/xmrig.h" +#include "crypto/common/Assembly.h" namespace xmrig { @@ -39,7 +39,7 @@ namespace xmrig { class ICpuInfo { public: - virtual ~ICpuInfo() {} + virtual ~ICpuInfo() = default; virtual bool hasAES() const = 0; virtual bool hasAVX2() const = 0; @@ -53,7 +53,7 @@ public: virtual int32_t sockets() const = 0; virtual int32_t threads() const = 0; virtual size_t optimalThreadsCount(size_t memSize, int maxCpuUsage) const = 0; - virtual xmrig::Assembly assembly() const = 0; + virtual Assembly::Id assembly() const = 0; }; diff --git a/src/common/xmrig.h b/src/common/xmrig.h index 5dd41845..169c4c1f 100644 --- a/src/common/xmrig.h +++ b/src/common/xmrig.h @@ -72,16 +72,6 @@ enum OclVendor { }; -enum Assembly { - ASM_NONE, - ASM_AUTO, - ASM_INTEL, - ASM_RYZEN, - ASM_BULLDOZER, - ASM_MAX -}; - - } /* namespace xmrig */ diff --git a/src/core/config/Config.cpp b/src/core/config/Config.cpp index 69ac065f..93bd47ff 100644 --- a/src/core/config/Config.cpp +++ b/src/core/config/Config.cpp @@ -32,7 +32,7 @@ #include "base/kernel/interfaces/IJsonReader.h" #include "common/cpu/Cpu.h" #include "core/config/Config.h" -#include "crypto/cn/Asm.h" +#include "crypto/common/Assembly.h" #include "rapidjson/document.h" #include "rapidjson/filewritestream.h" #include "rapidjson/prettywriter.h" @@ -45,7 +45,6 @@ static char affinity_tmp[20] = { 0 }; xmrig::Config::Config() : m_aesMode(AES_AUTO), m_algoVariant(AV_AUTO), - m_assembly(ASM_AUTO), m_hugePages(true), m_safe(false), m_shouldSave(false), @@ -99,7 +98,7 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const doc.AddMember("http", m_http.toJSON(doc), allocator); # ifdef XMRIG_FEATURE_ASM - doc.AddMember("asm", Asm::toJSON(m_assembly), allocator); + doc.AddMember("asm", m_assembly.toJSON(), allocator); # endif doc.AddMember("autosave", isAutoSave(), allocator); @@ -285,6 +284,6 @@ xmrig::AlgoVariant xmrig::Config::getAlgoVariantLite() const #ifdef XMRIG_FEATURE_ASM void xmrig::Config::setAssembly(const rapidjson::Value &assembly) { - m_assembly = Asm::parse(assembly); + m_assembly = assembly; } #endif diff --git a/src/core/cpu/AdvancedCpuInfo.cpp b/src/core/cpu/AdvancedCpuInfo.cpp index df6a385e..922e8311 100644 --- a/src/core/cpu/AdvancedCpuInfo.cpp +++ b/src/core/cpu/AdvancedCpuInfo.cpp @@ -31,7 +31,6 @@ xmrig::AdvancedCpuInfo::AdvancedCpuInfo() : - m_assembly(ASM_NONE), m_aes(false), m_avx2(false), m_L2_exclusive(false), @@ -78,10 +77,10 @@ xmrig::AdvancedCpuInfo::AdvancedCpuInfo() : m_aes = true; if (data.vendor == VENDOR_AMD) { - m_assembly = (data.ext_family >= 23) ? ASM_RYZEN : ASM_BULLDOZER; + m_assembly = (data.ext_family >= 23) ? Assembly::RYZEN : Assembly::BULLDOZER; } else if (data.vendor == VENDOR_INTEL) { - m_assembly = ASM_INTEL; + m_assembly = Assembly::INTEL; } } diff --git a/src/core/cpu/AdvancedCpuInfo.h b/src/core/cpu/AdvancedCpuInfo.h index 0765da33..90152640 100644 --- a/src/core/cpu/AdvancedCpuInfo.h +++ b/src/core/cpu/AdvancedCpuInfo.h @@ -40,7 +40,7 @@ public: protected: size_t optimalThreadsCount(size_t memSize, int maxCpuUsage) const override; - inline Assembly assembly() const override { return m_assembly; } + inline Assembly::Id assembly() const override { return m_assembly; } inline bool hasAES() const override { return m_aes; } inline bool hasAVX2() const override { return m_avx2; } inline bool isSupported() const override { return true; } diff --git a/src/crypto/cn/Asm.h b/src/crypto/cn/Asm.h deleted file mode 100644 index 3b755fd6..00000000 --- a/src/crypto/cn/Asm.h +++ /dev/null @@ -1,50 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017-2018 XMR-Stak , - * Copyright 2016-2018 XMRig , - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef XMRIG_ASM_H -#define XMRIG_ASM_H - - -#include "common/xmrig.h" -#include "rapidjson/fwd.h" - - -namespace xmrig { - - -class Asm -{ -public: - static Assembly parse(const char *assembly, Assembly defaultValue = ASM_AUTO); - static Assembly parse(const rapidjson::Value &value, Assembly defaultValue = ASM_AUTO); - static const char *toString(Assembly assembly); - static rapidjson::Value toJSON(Assembly assembly); - - inline static Assembly parse(bool enable) { return enable ? ASM_AUTO : ASM_NONE; } -}; - - -} /* namespace xmrig */ - - -#endif /* XMRIG_ASM_H */ diff --git a/src/crypto/cn/CnHash.cpp b/src/crypto/cn/CnHash.cpp index 61d2ea69..d17a8e2d 100644 --- a/src/crypto/cn/CnHash.cpp +++ b/src/crypto/cn/CnHash.cpp @@ -39,26 +39,26 @@ #define ADD_FN(algo) \ - m_map[algo][AV_SINGLE][ASM_NONE] = cryptonight_single_hash; \ - m_map[algo][AV_SINGLE_SOFT][ASM_NONE] = cryptonight_single_hash; \ - m_map[algo][AV_DOUBLE][ASM_NONE] = cryptonight_double_hash; \ - m_map[algo][AV_DOUBLE_SOFT][ASM_NONE] = cryptonight_double_hash; \ - m_map[algo][AV_TRIPLE][ASM_NONE] = cryptonight_triple_hash; \ - m_map[algo][AV_TRIPLE_SOFT][ASM_NONE] = cryptonight_triple_hash; \ - m_map[algo][AV_QUAD][ASM_NONE] = cryptonight_quad_hash; \ - m_map[algo][AV_QUAD_SOFT][ASM_NONE] = cryptonight_quad_hash; \ - m_map[algo][AV_PENTA][ASM_NONE] = cryptonight_penta_hash; \ - m_map[algo][AV_PENTA_SOFT][ASM_NONE] = cryptonight_penta_hash; + m_map[algo][AV_SINGLE][Assembly::NONE] = cryptonight_single_hash; \ + m_map[algo][AV_SINGLE_SOFT][Assembly::NONE] = cryptonight_single_hash; \ + m_map[algo][AV_DOUBLE][Assembly::NONE] = cryptonight_double_hash; \ + m_map[algo][AV_DOUBLE_SOFT][Assembly::NONE] = cryptonight_double_hash; \ + m_map[algo][AV_TRIPLE][Assembly::NONE] = cryptonight_triple_hash; \ + m_map[algo][AV_TRIPLE_SOFT][Assembly::NONE] = cryptonight_triple_hash; \ + m_map[algo][AV_QUAD][Assembly::NONE] = cryptonight_quad_hash; \ + m_map[algo][AV_QUAD_SOFT][Assembly::NONE] = cryptonight_quad_hash; \ + m_map[algo][AV_PENTA][Assembly::NONE] = cryptonight_penta_hash; \ + m_map[algo][AV_PENTA_SOFT][Assembly::NONE] = cryptonight_penta_hash; #ifdef XMRIG_FEATURE_ASM # define ADD_FN_ASM(algo) \ - m_map[algo][AV_SINGLE][ASM_INTEL] = cryptonight_single_hash_asm; \ - m_map[algo][AV_SINGLE][ASM_RYZEN] = cryptonight_single_hash_asm; \ - m_map[algo][AV_SINGLE][ASM_BULLDOZER] = cryptonight_single_hash_asm; \ - m_map[algo][AV_DOUBLE][ASM_INTEL] = cryptonight_double_hash_asm; \ - m_map[algo][AV_DOUBLE][ASM_RYZEN] = cryptonight_double_hash_asm; \ - m_map[algo][AV_DOUBLE][ASM_BULLDOZER] = cryptonight_double_hash_asm; + m_map[algo][AV_SINGLE][Assembly::INTEL] = cryptonight_single_hash_asm; \ + m_map[algo][AV_SINGLE][Assembly::RYZEN] = cryptonight_single_hash_asm; \ + m_map[algo][AV_SINGLE][Assembly::BULLDOZER] = cryptonight_single_hash_asm; \ + m_map[algo][AV_DOUBLE][Assembly::INTEL] = cryptonight_double_hash_asm; \ + m_map[algo][AV_DOUBLE][Assembly::RYZEN] = cryptonight_double_hash_asm; \ + m_map[algo][AV_DOUBLE][Assembly::BULLDOZER] = cryptonight_double_hash_asm; extern "C" void cnv2_mainloop_ivybridge_asm(cryptonight_ctx **ctx); @@ -226,8 +226,8 @@ xmrig::CnHash::CnHash() ADD_FN_ASM(Algorithm::CN_DOUBLE); # ifdef XMRIG_ALGO_CN_GPU - m_map[Algorithm::CN_GPU][AV_SINGLE][ASM_NONE] = cryptonight_single_hash_gpu; - m_map[Algorithm::CN_GPU][AV_SINGLE_SOFT][ASM_NONE] = cryptonight_single_hash_gpu; + m_map[Algorithm::CN_GPU][AV_SINGLE][Assembly::NONE] = cryptonight_single_hash_gpu; + m_map[Algorithm::CN_GPU][AV_SINGLE_SOFT][Assembly::NONE] = cryptonight_single_hash_gpu; # endif # ifdef XMRIG_ALGO_CN_LITE @@ -252,18 +252,18 @@ xmrig::CnHash::CnHash() } -xmrig::cn_hash_fun xmrig::CnHash::fn(const Algorithm &algorithm, AlgoVariant av, Assembly assembly) const +xmrig::cn_hash_fun xmrig::CnHash::fn(const Algorithm &algorithm, AlgoVariant av, Assembly::Id assembly) const { if (!algorithm.isValid()) { return nullptr; } # ifdef XMRIG_FEATURE_ASM - cn_hash_fun fun = m_map[algorithm][av][assembly == ASM_AUTO ? Cpu::info()->assembly() : assembly]; + cn_hash_fun fun = m_map[algorithm][av][assembly == Assembly::AUTO ? Cpu::info()->assembly() : assembly]; if (fun) { return fun; } # endif - return m_map[algorithm][av][ASM_NONE]; + return m_map[algorithm][av][Assembly::NONE]; } diff --git a/src/crypto/cn/CnHash.h b/src/crypto/cn/CnHash.h index 5fbf5c8a..b57bff4c 100644 --- a/src/crypto/cn/CnHash.h +++ b/src/crypto/cn/CnHash.h @@ -33,6 +33,7 @@ #include "common/xmrig.h" #include "crypto/cn/CnAlgo.h" +#include "crypto/common/Assembly.h" struct cryptonight_ctx; @@ -50,10 +51,10 @@ class CnHash public: CnHash(); - cn_hash_fun fn(const Algorithm &algorithm, AlgoVariant av, Assembly assembly) const; + cn_hash_fun fn(const Algorithm &algorithm, AlgoVariant av, Assembly::Id assembly) const; private: - cn_hash_fun m_map[Algorithm::MAX][AV_MAX][ASM_MAX] = {}; + cn_hash_fun m_map[Algorithm::MAX][AV_MAX][Assembly::MAX] = {}; }; diff --git a/src/crypto/cn/CryptoNight_x86.h b/src/crypto/cn/CryptoNight_x86.h index fc21c7b0..b24dea57 100644 --- a/src/crypto/cn/CryptoNight_x86.h +++ b/src/crypto/cn/CryptoNight_x86.h @@ -577,10 +577,10 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si const int code_size = v4_random_math_init(code, height); if (ALGO == Algorithm::CN_WOW) { - wow_soft_aes_compile_code(code, code_size, reinterpret_cast(ctx[0]->generated_code), ASM_NONE); + wow_soft_aes_compile_code(code, code_size, reinterpret_cast(ctx[0]->generated_code), Assembly::NONE); } else if (ALGO == Algorithm::CN_R) { - v4_soft_aes_compile_code(code, code_size, reinterpret_cast(ctx[0]->generated_code), ASM_NONE); + v4_soft_aes_compile_code(code, code_size, reinterpret_cast(ctx[0]->generated_code), Assembly::NONE); } ctx[0]->generated_code_data = { ALGO, height }; @@ -849,7 +849,7 @@ void cn_r_compile_code_double(const V4_Instruction* co namespace xmrig { -template +template inline void cryptonight_single_hash_asm(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx, uint64_t height) { constexpr CnAlgo props; @@ -866,10 +866,10 @@ inline void cryptonight_single_hash_asm(const uint8_t *__restrict__ input, size_ cn_explode_scratchpad(reinterpret_cast(ctx[0]->state), reinterpret_cast<__m128i*>(ctx[0]->memory)); if (ALGO == Algorithm::CN_2) { - if (ASM == ASM_INTEL) { + if (ASM == Assembly::INTEL) { cnv2_mainloop_ivybridge_asm(ctx); } - else if (ASM == ASM_RYZEN) { + else if (ASM == Assembly::RYZEN) { cnv2_mainloop_ryzen_asm(ctx); } else { @@ -877,10 +877,10 @@ inline void cryptonight_single_hash_asm(const uint8_t *__restrict__ input, size_ } } else if (ALGO == Algorithm::CN_HALF) { - if (ASM == ASM_INTEL) { + if (ASM == Assembly::INTEL) { cn_half_mainloop_ivybridge_asm(ctx); } - else if (ASM == ASM_RYZEN) { + else if (ASM == Assembly::RYZEN) { cn_half_mainloop_ryzen_asm(ctx); } else { @@ -889,10 +889,10 @@ inline void cryptonight_single_hash_asm(const uint8_t *__restrict__ input, size_ } # ifdef XMRIG_ALGO_CN_PICO else if (ALGO == Algorithm::CN_PICO_0) { - if (ASM == ASM_INTEL) { + if (ASM == Assembly::INTEL) { cn_trtl_mainloop_ivybridge_asm(ctx); } - else if (ASM == ASM_RYZEN) { + else if (ASM == Assembly::RYZEN) { cn_trtl_mainloop_ryzen_asm(ctx); } else { @@ -904,10 +904,10 @@ inline void cryptonight_single_hash_asm(const uint8_t *__restrict__ input, size_ cnv2_rwz_mainloop_asm(ctx); } else if (ALGO == Algorithm::CN_ZLS) { - if (ASM == ASM_INTEL) { + if (ASM == Assembly::INTEL) { cn_zls_mainloop_ivybridge_asm(ctx); } - else if (ASM == ASM_RYZEN) { + else if (ASM == Assembly::RYZEN) { cn_zls_mainloop_ryzen_asm(ctx); } else { @@ -915,10 +915,10 @@ inline void cryptonight_single_hash_asm(const uint8_t *__restrict__ input, size_ } } else if (ALGO == Algorithm::CN_DOUBLE) { - if (ASM == ASM_INTEL) { + if (ASM == Assembly::INTEL) { cn_double_mainloop_ivybridge_asm(ctx); } - else if (ASM == ASM_RYZEN) { + else if (ASM == Assembly::RYZEN) { cn_double_mainloop_ryzen_asm(ctx); } else { @@ -935,7 +935,7 @@ inline void cryptonight_single_hash_asm(const uint8_t *__restrict__ input, size_ } -template +template inline void cryptonight_double_hash_asm(const uint8_t *__restrict__ input, size_t size, uint8_t *__restrict__ output, cryptonight_ctx **__restrict__ ctx, uint64_t height) { constexpr CnAlgo props; diff --git a/src/crypto/cn/r/CryptonightR_gen.cpp b/src/crypto/cn/r/CryptonightR_gen.cpp index 8491a33b..3037327a 100644 --- a/src/crypto/cn/r/CryptonightR_gen.cpp +++ b/src/crypto/cn/r/CryptonightR_gen.cpp @@ -29,6 +29,7 @@ typedef void(*void_func)(); #include "crypto/cn/asm/CryptonightR_template.h" +#include "crypto/common/Assembly.h" #include "crypto/common/VirtualMemory.h" #include "Mem.h" @@ -42,7 +43,7 @@ static inline void add_code(uint8_t* &p, void (*p1)(), void (*p2)()) } } -static inline void add_random_math(uint8_t* &p, const V4_Instruction* code, int code_size, const void_func* instructions, const void_func* instructions_mov, bool is_64_bit, xmrig::Assembly ASM) +static inline void add_random_math(uint8_t* &p, const V4_Instruction* code, int code_size, const void_func* instructions, const void_func* instructions_mov, bool is_64_bit, xmrig::Assembly::Id ASM) { uint32_t prev_rot_src = (uint32_t)(-1); @@ -76,7 +77,7 @@ static inline void add_random_math(uint8_t* &p, const V4_Instruction* code, int void_func begin = instructions[c]; - if ((ASM = xmrig::ASM_BULLDOZER) && (inst.opcode == MUL) && !is_64_bit) { + if ((ASM = xmrig::Assembly::BULLDOZER) && (inst.opcode == MUL) && !is_64_bit) { // AMD Bulldozer has latency 4 for 32-bit IMUL and 6 for 64-bit IMUL // Always use 32-bit IMUL for AMD Bulldozer in 32-bit mode - skip prefix 0x48 and change 0x49 to 0x41 uint8_t* prefix = reinterpret_cast(begin); diff --git a/src/crypto/common/Algorithm.cpp b/src/crypto/common/Algorithm.cpp index e70b0659..66b3ddda 100644 --- a/src/crypto/common/Algorithm.cpp +++ b/src/crypto/common/Algorithm.cpp @@ -35,7 +35,6 @@ #ifdef _MSC_VER -# define strncasecmp _strnicmp # define strcasecmp _stricmp #endif diff --git a/src/crypto/common/Algorithm.h b/src/crypto/common/Algorithm.h index ccaf7de5..92c6f405 100644 --- a/src/crypto/common/Algorithm.h +++ b/src/crypto/common/Algorithm.h @@ -69,7 +69,7 @@ public: CN_PICO_0, // "cn-pico" CryptoNight Turtle (TRTL) # endif # ifdef XMRIG_ALGO_RANDOMX - RX_WOW, // "rx/wow" RandomWOW + RX_WOW, // "rx/wow" RandomWOW (Wownero) # endif MAX }; diff --git a/src/crypto/cn/Asm.cpp b/src/crypto/common/Assembly.cpp similarity index 72% rename from src/crypto/cn/Asm.cpp rename to src/crypto/common/Assembly.cpp index 331c133d..44bf0a94 100644 --- a/src/crypto/cn/Asm.cpp +++ b/src/crypto/common/Assembly.cpp @@ -6,7 +6,8 @@ * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , * Copyright 2018 SChernykh - * Copyright 2016-2018 XMRig , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,15 +29,17 @@ #ifdef _MSC_VER -# define strncasecmp _strnicmp # define strcasecmp _stricmp #endif -#include "crypto/cn/Asm.h" +#include "crypto/common/Assembly.h" #include "rapidjson/document.h" +namespace xmrig { + + static const char *asmNames[] = { "none", "auto", @@ -46,11 +49,13 @@ static const char *asmNames[] = { }; -xmrig::Assembly xmrig::Asm::parse(const char *assembly, Assembly defaultValue) +} /* namespace xmrig */ + + +xmrig::Assembly::Id xmrig::Assembly::parse(const char *assembly, Id defaultValue) { constexpr size_t const size = sizeof(asmNames) / sizeof((asmNames)[0]); - assert(assembly != nullptr); - assert(ASM_MAX == size); + static_assert(size == MAX, "asmNames size mismatch"); if (assembly == nullptr) { return defaultValue; @@ -58,7 +63,7 @@ xmrig::Assembly xmrig::Asm::parse(const char *assembly, Assembly defaultValue) for (size_t i = 0; i < size; i++) { if (strcasecmp(assembly, asmNames[i]) == 0) { - return static_cast(i); + return static_cast(i); } } @@ -66,10 +71,10 @@ xmrig::Assembly xmrig::Asm::parse(const char *assembly, Assembly defaultValue) } -xmrig::Assembly xmrig::Asm::parse(const rapidjson::Value &value, Assembly defaultValue) +xmrig::Assembly::Id xmrig::Assembly::parse(const rapidjson::Value &value, Id defaultValue) { if (value.IsBool()) { - return parse(value.GetBool()); + return value.GetBool() ? AUTO : NONE; } if (value.IsString()) { @@ -80,23 +85,23 @@ xmrig::Assembly xmrig::Asm::parse(const rapidjson::Value &value, Assembly defaul } -const char *xmrig::Asm::toString(Assembly assembly) +const char *xmrig::Assembly::toString() const { - return asmNames[assembly]; + return asmNames[m_id]; } -rapidjson::Value xmrig::Asm::toJSON(Assembly assembly) +rapidjson::Value xmrig::Assembly::toJSON() const { using namespace rapidjson; - if (assembly == ASM_NONE) { + if (m_id == NONE) { return Value(false); } - if (assembly == ASM_AUTO) { + if (m_id == AUTO) { return Value(true); } - return Value(StringRef(toString(assembly))); + return Value(StringRef(toString())); } diff --git a/src/crypto/common/Assembly.h b/src/crypto/common/Assembly.h new file mode 100644 index 00000000..e4964d07 --- /dev/null +++ b/src/crypto/common/Assembly.h @@ -0,0 +1,79 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_ASSEMBLY_H +#define XMRIG_ASSEMBLY_H + + +#include "common/xmrig.h" +#include "rapidjson/fwd.h" + + +namespace xmrig { + + +class Assembly +{ +public: + enum Id : int { + NONE, + AUTO, + INTEL, + RYZEN, + BULLDOZER, + MAX + }; + + + inline Assembly() {} + inline Assembly(Id id) : m_id(id) {} + inline Assembly(const char *assembly) : m_id(parse(assembly)) {} + inline Assembly(const rapidjson::Value &value) : m_id(parse(value)) {} + + static Id parse(const char *assembly, Id defaultValue = AUTO); + static Id parse(const rapidjson::Value &value, Id defaultValue = AUTO); + + const char *toString() const; + rapidjson::Value toJSON() const; + +// inline static Assembly parse(bool enable) { return enable ? ASM_AUTO : ASM_NONE; } + + inline bool isEqual(const Assembly &other) const { return m_id == other.m_id; } + + + inline bool operator!=(const Assembly &other) const { return !isEqual(other); } + inline bool operator!=(const Assembly::Id &id) const { return m_id != id; } + inline bool operator==(const Assembly &other) const { return isEqual(other); } + inline bool operator==(const Assembly::Id &id) const { return m_id == id; } + inline operator Assembly::Id() const { return m_id; } + +private: + Id m_id = AUTO; +}; + + +} /* namespace xmrig */ + + +#endif /* XMRIG_ASSEMBLY_H */ diff --git a/src/workers/CpuThread.cpp b/src/workers/CpuThread.cpp index e26b8a0a..9f20a35a 100644 --- a/src/workers/CpuThread.cpp +++ b/src/workers/CpuThread.cpp @@ -27,8 +27,8 @@ #include "base/io/log/Log.h" #include "common/cpu/Cpu.h" -#include "crypto/cn/Asm.h" #include "crypto/cn/CnHash.h" +#include "crypto/common/Assembly.h" #include "crypto/common/VirtualMemory.h" #include "Mem.h" #include "rapidjson/document.h" @@ -36,8 +36,6 @@ - - static const xmrig::CnHash cnHash; @@ -136,7 +134,7 @@ xmrig::CpuThread::Data xmrig::CpuThread::parse(const rapidjson::Value &object) } # ifdef XMRIG_FEATURE_ASM - data.assembly = Asm::parse(object["asm"]); + data.assembly = object["asm"]; # endif return data; @@ -181,7 +179,7 @@ void xmrig::CpuThread::print() const index(), static_cast(multiway()), static_cast(m_av)); # ifdef XMRIG_FEATURE_ASM - LOG_DEBUG(" assembly: %s, affine_to_cpu: %" PRId64, Asm::toString(m_assembly), affinity()); + LOG_DEBUG(" assembly: %s, affine_to_cpu: %" PRId64, m_assembly.toString(), affinity()); # else LOG_DEBUG(" affine_to_cpu: %" PRId64, affinity()); # endif @@ -220,7 +218,7 @@ rapidjson::Value xmrig::CpuThread::toConfig(rapidjson::Document &doc) const obj.AddMember("affine_to_cpu", affinity() == -1L ? Value(kFalseType) : Value(affinity()), allocator); # ifdef XMRIG_FEATURE_ASM - obj.AddMember("asm", Asm::toJSON(m_assembly), allocator); + obj.AddMember("asm", m_assembly.toJSON(), allocator); # endif return obj; diff --git a/src/workers/CpuThread.h b/src/workers/CpuThread.h index 08aa89cb..a43a0c09 100644 --- a/src/workers/CpuThread.h +++ b/src/workers/CpuThread.h @@ -42,7 +42,7 @@ class CpuThread : public IThread public: struct Data { - inline Data() : assembly(ASM_AUTO), valid(false), affinity(-1L), multiway(SingleWay) {} + inline Data() : valid(false), affinity(-1L), multiway(SingleWay) {} inline void setMultiway(int value) { From dd875c7c3797dbb44ffb85641fe3838d93e57236 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 28 Jun 2019 22:28:40 +0700 Subject: [PATCH 08/48] Added class CpuConfig. --- CMakeLists.txt | 3 + src/App.cpp | 2 +- src/Summary.cpp | 10 +-- src/backend/cpu/CpuConfig.cpp | 110 ++++++++++++++++++++++++++++++++ src/backend/cpu/CpuConfig.h | 72 +++++++++++++++++++++ src/backend/cpu/cpu.cmake | 7 +++ src/base/kernel/Base.cpp | 2 +- src/core/config/Config.cpp | 115 ++++++++-------------------------- src/core/config/Config.h | 40 ++---------- src/crypto/common/Assembly.h | 5 +- 10 files changed, 233 insertions(+), 133 deletions(-) create mode 100644 src/backend/cpu/CpuConfig.cpp create mode 100644 src/backend/cpu/CpuConfig.h create mode 100644 src/backend/cpu/cpu.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index a402174a..832c95d7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,11 +18,13 @@ option(WITH_EMBEDDED_CONFIG "Enable internal embedded JSON config" OFF) include (CheckIncludeFile) include (cmake/cpu.cmake) include (src/base/base.cmake) +include (src/backend/cpu/cpu.cmake) set(HEADERS "${HEADERS_BASE}" "${HEADERS_BASE_HTTP}" + "${HEADERS_CPU}" src/api/interfaces/IApiListener.h src/App.h src/common/cpu/Cpu.h @@ -83,6 +85,7 @@ endif() set(SOURCES "${SOURCES_BASE}" "${SOURCES_BASE_HTTP}" + "${SOURCES_CPU}" src/App.cpp src/common/Platform.cpp src/core/config/Config.cpp diff --git a/src/App.cpp b/src/App.cpp index 66662eb1..082bbeef 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -77,7 +77,7 @@ int xmrig::App::exec() background(); - Mem::init(m_controller->config()->isHugePages()); + Mem::init(m_controller->config()->cpu().isHugePages()); Summary::print(m_controller); diff --git a/src/Summary.cpp b/src/Summary.cpp index 13973c0f..a51f8f59 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -86,9 +86,9 @@ static void print_threads(xmrig::Config *config) { if (config->threadsMode() != xmrig::Config::Advanced) { char buf[32] = { 0 }; - if (config->affinity() != -1L) { - snprintf(buf, sizeof buf, ", affinity=0x%" PRIX64, config->affinity()); - } +// if (config->affinity() != -1L) { +// snprintf(buf, sizeof buf, ", affinity=0x%" PRIX64, config->affinity()); +// } xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%d") WHITE_BOLD(", av=%d, %sdonate=%d%%") WHITE_BOLD("%s"), "THREADS", @@ -109,13 +109,13 @@ static void print_threads(xmrig::Config *config) } # ifdef XMRIG_FEATURE_ASM - if (config->assembly() == xmrig::Assembly::AUTO) { + if (config->cpu().assembly() == xmrig::Assembly::AUTO) { const xmrig::Assembly assembly = xmrig::Cpu::info()->assembly(); xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13sauto:%s"), "ASSEMBLY", asmName(assembly)); } else { - xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s%s"), "ASSEMBLY", asmName(config->assembly())); + xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s%s"), "ASSEMBLY", asmName(config->cpu().assembly())); } # endif } diff --git a/src/backend/cpu/CpuConfig.cpp b/src/backend/cpu/CpuConfig.cpp new file mode 100644 index 00000000..b3d780f4 --- /dev/null +++ b/src/backend/cpu/CpuConfig.cpp @@ -0,0 +1,110 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "backend/cpu/CpuConfig.h" +#include "base/io/json/Json.h" +#include "common/cpu/Cpu.h" +#include "rapidjson/document.h" + + +namespace xmrig { + + +static const char *kEnabled = "enabled"; +static const char *kHugePages = "huge-pages"; +static const char *kHwAes = "hw-aes"; +static const char *kPriority = "priority"; + + +#ifdef XMRIG_FEATURE_ASM +static const char *kAsm = "asm"; +#endif + +} + + +xmrig::CpuConfig::CpuConfig() +{ +} + + +bool xmrig::CpuConfig::isHwAES() const +{ + return (m_aes == AES_AUTO ? (Cpu::info()->hasAES() ? AES_HW : AES_SOFT) : m_aes) == AES_HW; +} + + +rapidjson::Value xmrig::CpuConfig::toJSON(rapidjson::Document &doc) const +{ + using namespace rapidjson; + + auto &allocator = doc.GetAllocator(); + + Value obj(kObjectType); + + obj.AddMember(StringRef(kEnabled), m_enabled, allocator); + obj.AddMember(StringRef(kHugePages), m_hugePages, allocator); + obj.AddMember(StringRef(kHwAes), m_aes == AES_AUTO ? Value(kNullType) : Value(m_aes == AES_HW), allocator); + obj.AddMember(StringRef(kPriority), priority() != -1 ? Value(priority()) : Value(kNullType), allocator); + +# ifdef XMRIG_FEATURE_ASM + obj.AddMember(StringRef(kAsm), m_assembly.toJSON(), allocator); +# endif + + return obj; +} + + +void xmrig::CpuConfig::read(const rapidjson::Value &value) +{ + if (value.IsObject()) { + m_enabled = Json::getBool(value, kEnabled, m_enabled); + m_hugePages = Json::getBool(value, kHugePages, m_hugePages); + + setAesMode(Json::getValue(value, kHwAes)); + setPriority(Json::getInt(value, kPriority, -1)); + +# ifdef XMRIG_FEATURE_ASM + m_assembly = Json::getValue(value, kAsm); +# endif + } +} + + +void xmrig::CpuConfig::setAesMode(const rapidjson::Value &aesMode) +{ + if (aesMode.IsBool()) { + m_aes = aesMode.GetBool() ? AES_HW : AES_SOFT; + } + else { + m_aes = AES_AUTO; + } +} + + +void xmrig::CpuConfig::setPriority(int priority) +{ + m_priority = (priority >= -1 && priority <= 5) ? priority : -1; +} diff --git a/src/backend/cpu/CpuConfig.h b/src/backend/cpu/CpuConfig.h new file mode 100644 index 00000000..04dd9175 --- /dev/null +++ b/src/backend/cpu/CpuConfig.h @@ -0,0 +1,72 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_CPUCONFIG_H +#define XMRIG_CPUCONFIG_H + + +#include "crypto/common/Assembly.h" + + +namespace xmrig { + + +class CpuConfig +{ +public: + enum AesMode { + AES_AUTO, + AES_HW, + AES_SOFT + }; + + CpuConfig(); + + bool isHwAES() const; + rapidjson::Value toJSON(rapidjson::Document &doc) const; + void read(const rapidjson::Value &value); + + inline bool isEnabled() const { return m_enabled; } + inline bool isHugePages() const { return m_hugePages; } + inline bool isShouldSave() const { return m_shouldSave; } + inline const Assembly &assembly() const { return m_assembly; } + inline int priority() const { return m_priority; } + +private: + void setAesMode(const rapidjson::Value &aesMode); + void setPriority(int priority); + + AesMode m_aes = AES_AUTO; + Assembly m_assembly; + bool m_enabled = true; + bool m_hugePages = true; + bool m_shouldSave = false; + int m_priority = -1; +}; + + +} /* namespace xmrig */ + + +#endif /* XMRIG_CPUCONFIG_H */ diff --git a/src/backend/cpu/cpu.cmake b/src/backend/cpu/cpu.cmake new file mode 100644 index 00000000..88159893 --- /dev/null +++ b/src/backend/cpu/cpu.cmake @@ -0,0 +1,7 @@ +set(HEADERS_CPU + src/backend/cpu/CpuConfig.h + ) + +set(SOURCES_CPU + src/backend/cpu/CpuConfig.cpp + ) diff --git a/src/base/kernel/Base.cpp b/src/base/kernel/Base.cpp index 1083efe9..031daed7 100644 --- a/src/base/kernel/Base.cpp +++ b/src/base/kernel/Base.cpp @@ -172,7 +172,7 @@ int xmrig::Base::init() Platform::init(config()->userAgent()); # ifndef XMRIG_PROXY_PROJECT - Platform::setProcessPriority(config()->priority()); + Platform::setProcessPriority(config()->cpu().priority()); # endif if (!config()->isBackground()) { diff --git a/src/core/config/Config.cpp b/src/core/config/Config.cpp index 93bd47ff..5b445c0f 100644 --- a/src/core/config/Config.cpp +++ b/src/core/config/Config.cpp @@ -39,46 +39,24 @@ #include "workers/CpuThread.h" -static char affinity_tmp[20] = { 0 }; - - xmrig::Config::Config() : - m_aesMode(AES_AUTO), m_algoVariant(AV_AUTO), - m_hugePages(true), - m_safe(false), - m_shouldSave(false), - m_maxCpuUsage(100), - m_priority(-1) + m_shouldSave(false) { } -bool xmrig::Config::isHwAES() const -{ - return (m_aesMode == AES_AUTO ? (Cpu::info()->hasAES() ? AES_HW : AES_SOFT) : m_aesMode) == AES_HW; -} - - bool xmrig::Config::read(const IJsonReader &reader, const char *fileName) { if (!BaseConfig::read(reader, fileName)) { return false; } - m_hugePages = reader.getBool("huge-pages", true); - m_safe = reader.getBool("safe"); + m_cpu.read(reader.getValue("cpu")); - setAesMode(reader.getValue("hw-aes")); setAlgoVariant(reader.getInt("av")); - setMaxCpuUsage(reader.getInt("max-cpu-usage", 100)); - setPriority(reader.getInt("cpu-priority", -1)); setThreads(reader.getValue("threads")); -# ifdef XMRIG_FEATURE_ASM - setAssembly(reader.getValue("asm")); -# endif - return finalize(); } @@ -96,36 +74,29 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const api.AddMember("worker-id", m_apiWorkerId.toJSON(), allocator); doc.AddMember("api", api, allocator); doc.AddMember("http", m_http.toJSON(doc), allocator); - -# ifdef XMRIG_FEATURE_ASM - doc.AddMember("asm", m_assembly.toJSON(), allocator); -# endif - doc.AddMember("autosave", isAutoSave(), allocator); doc.AddMember("av", algoVariant(), allocator); doc.AddMember("background", isBackground(), allocator); doc.AddMember("colors", Log::colors, allocator); - if (affinity() != -1L) { - snprintf(affinity_tmp, sizeof(affinity_tmp) - 1, "0x%" PRIX64, affinity()); - doc.AddMember("cpu-affinity", StringRef(affinity_tmp), allocator); - } - else { - doc.AddMember("cpu-affinity", kNullType, allocator); - } +// if (affinity() != -1L) { +// snprintf(affinity_tmp, sizeof(affinity_tmp) - 1, "0x%" PRIX64, affinity()); +// doc.AddMember("cpu-affinity", StringRef(affinity_tmp), allocator); +// } +// else { +// doc.AddMember("cpu-affinity", kNullType, allocator); +// } + + + doc.AddMember("cpu", m_cpu.toJSON(doc), allocator); - doc.AddMember("cpu-priority", priority() != -1 ? Value(priority()) : Value(kNullType), allocator); doc.AddMember("donate-level", m_pools.donateLevel(), allocator); doc.AddMember("donate-over-proxy", m_pools.proxyDonate(), allocator); - doc.AddMember("huge-pages", isHugePages(), allocator); - doc.AddMember("hw-aes", m_aesMode == AES_AUTO ? Value(kNullType) : Value(m_aesMode == AES_HW), allocator); doc.AddMember("log-file", m_logFile.toJSON(), allocator); - doc.AddMember("max-cpu-usage", m_maxCpuUsage, allocator); doc.AddMember("pools", m_pools.toJSON(doc), allocator); doc.AddMember("print-time", printTime(), allocator); doc.AddMember("retries", m_pools.retries(), allocator); doc.AddMember("retry-pause", m_pools.retryPause(), allocator); - doc.AddMember("safe", m_safe, allocator); if (threadsMode() != Simple) { Value threads(kArrayType); @@ -154,7 +125,7 @@ bool xmrig::Config::finalize() m_threads.mode = Advanced; for (size_t i = 0; i < m_threads.cpu.size(); ++i) { - m_threads.list.push_back(CpuThread::createFromData(i, algorithm, m_threads.cpu[i], m_priority, !isHwAES())); + m_threads.list.push_back(CpuThread::createFromData(i, algorithm, m_threads.cpu[i], m_cpu.priority(), !m_cpu.isHwAES())); } return true; @@ -166,17 +137,17 @@ bool xmrig::Config::finalize() const size_t size = CpuThread::multiway(av) * CnAlgo<>::memory(algorithm) / 1024; // FIXME MEMORY if (!m_threads.count) { - m_threads.count = Cpu::info()->optimalThreadsCount(size, m_maxCpuUsage); - } - else if (m_safe) { - const size_t count = Cpu::info()->optimalThreadsCount(size, m_maxCpuUsage); - if (m_threads.count > count) { - m_threads.count = count; - } + m_threads.count = Cpu::info()->optimalThreadsCount(size, 100); } +// else if (m_safe) { +// const size_t count = Cpu::info()->optimalThreadsCount(size, m_maxCpuUsage); +// if (m_threads.count > count) { +// m_threads.count = count; +// } +// } for (size_t i = 0; i < m_threads.count; ++i) { - m_threads.list.push_back(CpuThread::createFromAV(i, algorithm, av, m_threads.mask, m_priority, m_assembly)); + m_threads.list.push_back(CpuThread::createFromAV(i, algorithm, av, m_threads.mask, m_cpu.priority(), m_cpu.assembly())); } m_shouldSave = m_threads.mode == Automatic; @@ -185,14 +156,6 @@ bool xmrig::Config::finalize() } -void xmrig::Config::setAesMode(const rapidjson::Value &aesMode) -{ - if (aesMode.IsBool()) { - m_aesMode = aesMode.GetBool() ? AES_HW : AES_SOFT; - } -} - - void xmrig::Config::setAlgoVariant(int av) { if (av >= AV_AUTO && av < AV_MAX) { @@ -201,22 +164,6 @@ void xmrig::Config::setAlgoVariant(int av) } -void xmrig::Config::setMaxCpuUsage(int max) -{ - if (max > 0 && max <= 100) { - m_maxCpuUsage = max; - } -} - - -void xmrig::Config::setPriority(int priority) -{ - if (priority >= 0 && priority <= 5) { - m_priority = priority; - } -} - - void xmrig::Config::setThreads(const rapidjson::Value &threads) { if (threads.IsArray()) { @@ -257,9 +204,9 @@ xmrig::AlgoVariant xmrig::Config::getAlgoVariant() const return Cpu::info()->hasAES() ? AV_SINGLE : AV_SINGLE_SOFT; } - if (m_safe && !Cpu::info()->hasAES() && m_algoVariant <= AV_DOUBLE) { - return static_cast(m_algoVariant + 2); - } +// if (m_safe && !Cpu::info()->hasAES() && m_algoVariant <= AV_DOUBLE) { +// return static_cast(m_algoVariant + 2); +// } return m_algoVariant; } @@ -272,18 +219,10 @@ xmrig::AlgoVariant xmrig::Config::getAlgoVariantLite() const return Cpu::info()->hasAES() ? AV_DOUBLE : AV_DOUBLE_SOFT; } - if (m_safe && !Cpu::info()->hasAES() && m_algoVariant <= AV_DOUBLE) { - return static_cast(m_algoVariant + 2); - } +// if (m_safe && !Cpu::info()->hasAES() && m_algoVariant <= AV_DOUBLE) { +// return static_cast(m_algoVariant + 2); +// } return m_algoVariant; } #endif - - -#ifdef XMRIG_FEATURE_ASM -void xmrig::Config::setAssembly(const rapidjson::Value &assembly) -{ - m_assembly = assembly; -} -#endif diff --git a/src/core/config/Config.h b/src/core/config/Config.h index 0ff13fe7..76720889 100644 --- a/src/core/config/Config.h +++ b/src/core/config/Config.h @@ -5,7 +5,8 @@ * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , - * Copyright 2016-2018 XMRig , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -29,6 +30,7 @@ #include +#include "backend/cpu/CpuConfig.h" #include "base/kernel/config/BaseConfig.h" #include "common/xmrig.h" #include "rapidjson/fwd.h" @@ -38,23 +40,9 @@ namespace xmrig { -class ConfigLoader; class IThread; -class IConfigListener; -class Process; -/** - * @brief The Config class - * - * Options with dynamic reload: - * colors - * debug - * verbose - * custom-diff (only for new connections) - * api/worker-id - * pools/ - */ class Config : public BaseConfig { public: @@ -67,26 +55,19 @@ public: Config(); - bool isHwAES() const; bool read(const IJsonReader &reader, const char *fileName) override; void getJSON(rapidjson::Document &doc) const override; inline AlgoVariant algoVariant() const { return m_algoVariant; } - inline Assembly assembly() const { return m_assembly; } - inline bool isHugePages() const { return m_hugePages; } inline bool isShouldSave() const { return (m_shouldSave || m_upgrade) && isAutoSave(); } + inline const CpuConfig &cpu() const { return m_cpu; } inline const std::vector &threads() const { return m_threads.list; } - inline int priority() const { return m_priority; } inline int threadsCount() const { return static_cast(m_threads.list.size()); } - inline int64_t affinity() const { return m_threads.mask; } inline ThreadsMode threadsMode() const { return m_threads.mode; } private: bool finalize(); - void setAesMode(const rapidjson::Value &aesMode); void setAlgoVariant(int av); - void setMaxCpuUsage(int max); - void setPriority(int priority); void setThreads(const rapidjson::Value &threads); AlgoVariant getAlgoVariant() const; @@ -94,11 +75,6 @@ private: AlgoVariant getAlgoVariantLite() const; # endif -# ifdef XMRIG_FEATURE_ASM - void setAssembly(const rapidjson::Value &assembly); -# endif - - struct Threads { inline Threads() : mask(-1L), count(0), mode(Automatic) {} @@ -111,18 +87,14 @@ private: }; - AesMode m_aesMode; AlgoVariant m_algoVariant; - Assembly m_assembly; - bool m_hugePages; - bool m_safe; bool m_shouldSave; - int m_maxCpuUsage; - int m_priority; + CpuConfig m_cpu; Threads m_threads; }; } /* namespace xmrig */ + #endif /* XMRIG_CONFIG_H */ diff --git a/src/crypto/common/Assembly.h b/src/crypto/common/Assembly.h index e4964d07..0b3f29b3 100644 --- a/src/crypto/common/Assembly.h +++ b/src/crypto/common/Assembly.h @@ -57,10 +57,7 @@ public: const char *toString() const; rapidjson::Value toJSON() const; -// inline static Assembly parse(bool enable) { return enable ? ASM_AUTO : ASM_NONE; } - - inline bool isEqual(const Assembly &other) const { return m_id == other.m_id; } - + inline bool isEqual(const Assembly &other) const { return m_id == other.m_id; } inline bool operator!=(const Assembly &other) const { return !isEqual(other); } inline bool operator!=(const Assembly::Id &id) const { return m_id != id; } From 62edb2fc0ace1b078e821e13229f18ec94ec3c42 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 29 Jun 2019 09:51:23 +0700 Subject: [PATCH 09/48] Move CPU information classes to new location. --- CMakeLists.txt | 19 ------- src/App.cpp | 4 +- src/Summary.cpp | 4 +- src/api/v1/ApiRouter.cpp | 2 +- src/{core => backend}/cpu/Cpu.cpp | 17 ++++-- src/{common => backend}/cpu/Cpu.h | 5 +- src/backend/cpu/CpuConfig.cpp | 2 +- src/backend/cpu/cpu.cmake | 22 +++++++ .../cpu}/interfaces/ICpuInfo.h | 7 ++- .../cpu/platform}/AdvancedCpuInfo.cpp | 2 +- .../cpu/platform}/AdvancedCpuInfo.h | 8 +-- .../cpu/platform}/BasicCpuInfo.cpp | 9 +-- .../cpu/platform}/BasicCpuInfo.h | 8 +-- .../cpu/platform}/BasicCpuInfo_arm.cpp | 0 src/common/cpu/Cpu.cpp | 57 ------------------- src/core/Controller.cpp | 2 +- src/core/config/Config.cpp | 2 +- src/crypto/cn/CnHash.cpp | 2 +- src/crypto/cn/CryptoNight_x86.h | 2 +- src/workers/CpuThread.cpp | 1 - src/workers/Worker.cpp | 2 +- 21 files changed, 62 insertions(+), 115 deletions(-) rename src/{core => backend}/cpu/Cpu.cpp (73%) rename src/{common => backend}/cpu/Cpu.h (88%) rename src/{common => backend/cpu}/interfaces/ICpuInfo.h (91%) rename src/{core/cpu => backend/cpu/platform}/AdvancedCpuInfo.cpp (98%) rename src/{core/cpu => backend/cpu/platform}/AdvancedCpuInfo.h (91%) rename src/{common/cpu => backend/cpu/platform}/BasicCpuInfo.cpp (94%) rename src/{common/cpu => backend/cpu/platform}/BasicCpuInfo.h (89%) rename src/{common/cpu => backend/cpu/platform}/BasicCpuInfo_arm.cpp (100%) delete mode 100644 src/common/cpu/Cpu.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 832c95d7..7320b63d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,8 +27,6 @@ set(HEADERS "${HEADERS_CPU}" src/api/interfaces/IApiListener.h src/App.h - src/common/cpu/Cpu.h - src/common/interfaces/ICpuInfo.h src/common/Platform.h src/common/xmrig.h src/core/config/Config_default.h @@ -178,23 +176,6 @@ endif() include(cmake/flags.cmake) -if (WITH_LIBCPUID) - add_subdirectory(src/3rdparty/libcpuid) - - include_directories(src/3rdparty/libcpuid) - set(CPUID_LIB cpuid) - set(SOURCES_CPUID src/core/cpu/AdvancedCpuInfo.h src/core/cpu/AdvancedCpuInfo.cpp src/core/cpu/Cpu.cpp) -else() - add_definitions(/DXMRIG_NO_LIBCPUID) - set(SOURCES_CPUID src/common/cpu/BasicCpuInfo.h src/common/cpu/Cpu.cpp) - - if (XMRIG_ARM) - set(SOURCES_CPUID ${SOURCES_CPUID} src/common/cpu/BasicCpuInfo_arm.cpp) - else() - set(SOURCES_CPUID ${SOURCES_CPUID} src/common/cpu/BasicCpuInfo.cpp) - endif() -endif() - include(cmake/OpenSSL.cmake) include(cmake/asm.cmake) include(cmake/cn-gpu.cmake) diff --git a/src/App.cpp b/src/App.cpp index 082bbeef..6e42ac30 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -6,7 +6,7 @@ * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , * Copyright 2018 Lee Clagett - * Copyright 2018 SChernykh + * Copyright 2018-2019 SChernykh * Copyright 2016-2019 XMRig , * * This program is free software: you can redistribute it and/or modify @@ -30,10 +30,10 @@ #include "api/Api.h" #include "App.h" +#include "backend/cpu/Cpu.h" #include "base/io/Console.h" #include "base/io/log/Log.h" #include "base/kernel/Signals.h" -#include "common/cpu/Cpu.h" #include "common/Platform.h" #include "core/config/Config.h" #include "core/Controller.h" diff --git a/src/Summary.cpp b/src/Summary.cpp index a51f8f59..59e540d4 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -28,9 +28,9 @@ #include +#include "backend/cpu/Cpu.h" #include "base/io/log/Log.h" #include "base/net/stratum/Pool.h" -#include "common/cpu/Cpu.h" #include "core/config/Config.h" #include "core/Controller.h" #include "crypto/common/Assembly.h" @@ -76,7 +76,7 @@ static void print_cpu(xmrig::Config *) Cpu::info()->hasAES() ? GREEN_BOLD_S : RED_BOLD_S "-", Cpu::info()->hasAVX2() ? GREEN_BOLD_S : RED_BOLD_S "-" ); -# ifndef XMRIG_NO_LIBCPUID +# ifdef XMRIG_FEATURE_LIBCPUID Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s%.1f MB/%.1f MB"), "CPU L2/L3", Cpu::info()->L2() / 1024.0, Cpu::info()->L3() / 1024.0); # endif } diff --git a/src/api/v1/ApiRouter.cpp b/src/api/v1/ApiRouter.cpp index d066b0b1..0f754e17 100644 --- a/src/api/v1/ApiRouter.cpp +++ b/src/api/v1/ApiRouter.cpp @@ -29,8 +29,8 @@ #include "api/interfaces/IApiRequest.h" #include "api/v1/ApiRouter.h" +#include "backend/cpu/Cpu.h" #include "base/kernel/Base.h" -#include "common/cpu/Cpu.h" #include "common/Platform.h" #include "core/config/Config.h" #include "interfaces/IThread.h" diff --git a/src/core/cpu/Cpu.cpp b/src/backend/cpu/Cpu.cpp similarity index 73% rename from src/core/cpu/Cpu.cpp rename to src/backend/cpu/Cpu.cpp index 773255d2..fdcad5a8 100644 --- a/src/core/cpu/Cpu.cpp +++ b/src/backend/cpu/Cpu.cpp @@ -4,8 +4,9 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,11 +26,13 @@ #include -#include "common/cpu/Cpu.h" +#include "backend/cpu/Cpu.h" -#ifndef XMRIG_NO_LIBCPUID -# include "core/cpu/AdvancedCpuInfo.h" +#ifdef XMRIG_FEATURE_LIBCPUID +# include "backend/cpu/platform/AdvancedCpuInfo.h" +#else +# include "backend/cpu/platform/BasicCpuInfo.h" #endif @@ -48,7 +51,11 @@ void xmrig::Cpu::init() { assert(cpuInfo == nullptr); +# ifdef XMRIG_FEATURE_LIBCPUID cpuInfo = new AdvancedCpuInfo(); +# else + cpuInfo = new BasicCpuInfo(); +# endif } diff --git a/src/common/cpu/Cpu.h b/src/backend/cpu/Cpu.h similarity index 88% rename from src/common/cpu/Cpu.h rename to src/backend/cpu/Cpu.h index 1d5a9fb1..9c8afced 100644 --- a/src/common/cpu/Cpu.h +++ b/src/backend/cpu/Cpu.h @@ -5,7 +5,8 @@ * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , - * Copyright 2016-2018 XMRig , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,7 +26,7 @@ #define XMRIG_CPU_H -#include "common/interfaces/ICpuInfo.h" +#include "backend/cpu/interfaces/ICpuInfo.h" namespace xmrig { diff --git a/src/backend/cpu/CpuConfig.cpp b/src/backend/cpu/CpuConfig.cpp index b3d780f4..5284d607 100644 --- a/src/backend/cpu/CpuConfig.cpp +++ b/src/backend/cpu/CpuConfig.cpp @@ -23,9 +23,9 @@ */ +#include "backend/cpu/Cpu.h" #include "backend/cpu/CpuConfig.h" #include "base/io/json/Json.h" -#include "common/cpu/Cpu.h" #include "rapidjson/document.h" diff --git a/src/backend/cpu/cpu.cmake b/src/backend/cpu/cpu.cmake index 88159893..03ca7075 100644 --- a/src/backend/cpu/cpu.cmake +++ b/src/backend/cpu/cpu.cmake @@ -1,7 +1,29 @@ set(HEADERS_CPU + src/backend/cpu/Cpu.h src/backend/cpu/CpuConfig.h + src/backend/cpu/interfaces/ICpuInfo.h ) set(SOURCES_CPU + src/backend/cpu/Cpu.cpp src/backend/cpu/CpuConfig.cpp ) + + +if (WITH_LIBCPUID) + add_subdirectory(src/3rdparty/libcpuid) + include_directories(src/3rdparty/libcpuid) + add_definitions(/DXMRIG_FEATURE_LIBCPUID) + + set(CPUID_LIB cpuid) + set(SOURCES_CPUID src/backend/cpu/platform/AdvancedCpuInfo.h src/backend/cpu/platform/AdvancedCpuInfo.cpp src/backend/cpu/Cpu.cpp) +else() + remove_definitions(/DXMRIG_FEATURE_LIBCPUID) + set(SOURCES_CPUID src/backend/cpu/platform/BasicCpuInfo.h src/backend/cpu/Cpu.cpp) + + if (XMRIG_ARM) + set(SOURCES_CPUID ${SOURCES_CPUID} src/backend/cpu/platform/BasicCpuInfo_arm.cpp) + else() + set(SOURCES_CPUID ${SOURCES_CPUID} src/backend/cpu/platform/BasicCpuInfo.cpp) + endif() +endif() diff --git a/src/common/interfaces/ICpuInfo.h b/src/backend/cpu/interfaces/ICpuInfo.h similarity index 91% rename from src/common/interfaces/ICpuInfo.h rename to src/backend/cpu/interfaces/ICpuInfo.h index 907f3f63..9618f489 100644 --- a/src/common/interfaces/ICpuInfo.h +++ b/src/backend/cpu/interfaces/ICpuInfo.h @@ -41,10 +41,15 @@ class ICpuInfo public: virtual ~ICpuInfo() = default; +# if defined(__x86_64__) || defined(_M_AMD64) || defined (__arm64__) || defined (__aarch64__) + inline constexpr bool isX64() const { return true; } +# else + inline constexpr bool isX64() const { return false; } +# endif + virtual bool hasAES() const = 0; virtual bool hasAVX2() const = 0; virtual bool isSupported() const = 0; - virtual bool isX64() const = 0; virtual const char *brand() const = 0; virtual int32_t cores() const = 0; virtual int32_t L2() const = 0; diff --git a/src/core/cpu/AdvancedCpuInfo.cpp b/src/backend/cpu/platform/AdvancedCpuInfo.cpp similarity index 98% rename from src/core/cpu/AdvancedCpuInfo.cpp rename to src/backend/cpu/platform/AdvancedCpuInfo.cpp index 922e8311..fc7f734d 100644 --- a/src/core/cpu/AdvancedCpuInfo.cpp +++ b/src/backend/cpu/platform/AdvancedCpuInfo.cpp @@ -27,7 +27,7 @@ #include -#include "core/cpu/AdvancedCpuInfo.h" +#include "backend/cpu/platform/AdvancedCpuInfo.h" xmrig::AdvancedCpuInfo::AdvancedCpuInfo() : diff --git a/src/core/cpu/AdvancedCpuInfo.h b/src/backend/cpu/platform/AdvancedCpuInfo.h similarity index 91% rename from src/core/cpu/AdvancedCpuInfo.h rename to src/backend/cpu/platform/AdvancedCpuInfo.h index 90152640..83c3d8e5 100644 --- a/src/core/cpu/AdvancedCpuInfo.h +++ b/src/backend/cpu/platform/AdvancedCpuInfo.h @@ -26,7 +26,7 @@ #define XMRIG_ADVANCEDCPUINFO_H -#include "common/interfaces/ICpuInfo.h" +#include "backend/cpu/interfaces/ICpuInfo.h" namespace xmrig { @@ -52,12 +52,6 @@ protected: inline int32_t sockets() const override { return m_sockets; } inline int32_t threads() const override { return m_threads; } -# if defined(__x86_64__) || defined(_M_AMD64) - inline bool isX64() const override { return true; } -# else - inline bool isX64() const override { return false; } -# endif - private: Assembly m_assembly; bool m_aes; diff --git a/src/common/cpu/BasicCpuInfo.cpp b/src/backend/cpu/platform/BasicCpuInfo.cpp similarity index 94% rename from src/common/cpu/BasicCpuInfo.cpp rename to src/backend/cpu/platform/BasicCpuInfo.cpp index c5b8ed0a..04ff589b 100644 --- a/src/common/cpu/BasicCpuInfo.cpp +++ b/src/backend/cpu/platform/BasicCpuInfo.cpp @@ -45,7 +45,8 @@ #endif -#include "common/cpu/BasicCpuInfo.h" +#include "backend/cpu/platform/BasicCpuInfo.h" +#include "crypto/common/Assembly.h" #define VENDOR_ID (0) @@ -121,7 +122,7 @@ static inline bool has_ossave() xmrig::BasicCpuInfo::BasicCpuInfo() : - m_assembly(ASM_NONE), + m_assembly(Assembly::NONE), m_aes(has_aes_ni()), m_avx2(has_avx2() && has_ossave()), m_brand(), @@ -141,10 +142,10 @@ xmrig::BasicCpuInfo::BasicCpuInfo() : memcpy(vendor + 8, &data[2], 4); if (memcmp(vendor, "GenuineIntel", 12) == 0) { - m_assembly = ASM_INTEL; + m_assembly = Assembly::INTEL; } else if (memcmp(vendor, "AuthenticAMD", 12) == 0) { - m_assembly = ASM_RYZEN; + m_assembly = Assembly::RYZEN; } } # endif diff --git a/src/common/cpu/BasicCpuInfo.h b/src/backend/cpu/platform/BasicCpuInfo.h similarity index 89% rename from src/common/cpu/BasicCpuInfo.h rename to src/backend/cpu/platform/BasicCpuInfo.h index f6daee54..4d4a5163 100644 --- a/src/common/cpu/BasicCpuInfo.h +++ b/src/backend/cpu/platform/BasicCpuInfo.h @@ -26,7 +26,7 @@ #define XMRIG_BASICCPUINFO_H -#include "common/interfaces/ICpuInfo.h" +#include "backend/cpu/interfaces/ICpuInfo.h" namespace xmrig { @@ -52,12 +52,6 @@ protected: inline int32_t sockets() const override { return 1; } inline int32_t threads() const override { return m_threads; } -# if defined(__x86_64__) || defined(_M_AMD64) || defined (__arm64__) || defined (__aarch64__) - inline bool isX64() const override { return true; } -# else - inline bool isX64() const override { return false; } -# endif - private: Assembly m_assembly; bool m_aes; diff --git a/src/common/cpu/BasicCpuInfo_arm.cpp b/src/backend/cpu/platform/BasicCpuInfo_arm.cpp similarity index 100% rename from src/common/cpu/BasicCpuInfo_arm.cpp rename to src/backend/cpu/platform/BasicCpuInfo_arm.cpp diff --git a/src/common/cpu/Cpu.cpp b/src/common/cpu/Cpu.cpp deleted file mode 100644 index b1bb28ac..00000000 --- a/src/common/cpu/Cpu.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2016-2017 XMRig - * - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -#include - - -#include "common/cpu/BasicCpuInfo.h" -#include "common/cpu/Cpu.h" - - -static xmrig::ICpuInfo *cpuInfo = nullptr; - - -xmrig::ICpuInfo *xmrig::Cpu::info() -{ - assert(cpuInfo != nullptr); - - return cpuInfo; -} - - -void xmrig::Cpu::init() -{ - assert(cpuInfo == nullptr); - - cpuInfo = new BasicCpuInfo(); -} - - -void xmrig::Cpu::release() -{ - assert(cpuInfo != nullptr); - - delete cpuInfo; - cpuInfo = nullptr; -} diff --git a/src/core/Controller.cpp b/src/core/Controller.cpp index 493b3e11..8e2e03a1 100644 --- a/src/core/Controller.cpp +++ b/src/core/Controller.cpp @@ -26,7 +26,7 @@ #include -#include "common/cpu/Cpu.h" +#include "backend/cpu/Cpu.h" #include "common/Platform.h" #include "core/Controller.h" #include "net/Network.h" diff --git a/src/core/config/Config.cpp b/src/core/config/Config.cpp index 5b445c0f..33f4cc44 100644 --- a/src/core/config/Config.cpp +++ b/src/core/config/Config.cpp @@ -28,9 +28,9 @@ #include +#include "backend/cpu/Cpu.h" #include "base/io/log/Log.h" #include "base/kernel/interfaces/IJsonReader.h" -#include "common/cpu/Cpu.h" #include "core/config/Config.h" #include "crypto/common/Assembly.h" #include "rapidjson/document.h" diff --git a/src/crypto/cn/CnHash.cpp b/src/crypto/cn/CnHash.cpp index d17a8e2d..6582db10 100644 --- a/src/crypto/cn/CnHash.cpp +++ b/src/crypto/cn/CnHash.cpp @@ -26,7 +26,7 @@ #include -#include "common/cpu/Cpu.h" +#include "backend/cpu/Cpu.h" #include "crypto/cn/CnHash.h" #include "crypto/common/VirtualMemory.h" diff --git a/src/crypto/cn/CryptoNight_x86.h b/src/crypto/cn/CryptoNight_x86.h index b24dea57..ae51cd18 100644 --- a/src/crypto/cn/CryptoNight_x86.h +++ b/src/crypto/cn/CryptoNight_x86.h @@ -35,7 +35,7 @@ #endif -#include "common/cpu/Cpu.h" +#include "backend/cpu/Cpu.h" #include "crypto/cn/CnAlgo.h" #include "crypto/cn/CryptoNight_monero.h" #include "crypto/cn/CryptoNight.h" diff --git a/src/workers/CpuThread.cpp b/src/workers/CpuThread.cpp index 9f20a35a..7011da12 100644 --- a/src/workers/CpuThread.cpp +++ b/src/workers/CpuThread.cpp @@ -26,7 +26,6 @@ #include "base/io/log/Log.h" -#include "common/cpu/Cpu.h" #include "crypto/cn/CnHash.h" #include "crypto/common/Assembly.h" #include "crypto/common/VirtualMemory.h" diff --git a/src/workers/Worker.cpp b/src/workers/Worker.cpp index 234e7bfd..c6ea6d9a 100644 --- a/src/workers/Worker.cpp +++ b/src/workers/Worker.cpp @@ -24,7 +24,7 @@ #include -#include "common/cpu/Cpu.h" +#include "backend/cpu/Cpu.h" #include "common/Platform.h" #include "workers/CpuThread.h" #include "workers/ThreadHandle.h" From e10671fa5121c1af75a51ecf333db179f652a545 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 29 Jun 2019 10:25:06 +0700 Subject: [PATCH 10/48] Fixed ARM build. --- src/backend/cpu/interfaces/ICpuInfo.h | 4 ++-- src/backend/cpu/platform/BasicCpuInfo_arm.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backend/cpu/interfaces/ICpuInfo.h b/src/backend/cpu/interfaces/ICpuInfo.h index 9618f489..abff7a6c 100644 --- a/src/backend/cpu/interfaces/ICpuInfo.h +++ b/src/backend/cpu/interfaces/ICpuInfo.h @@ -42,9 +42,9 @@ public: virtual ~ICpuInfo() = default; # if defined(__x86_64__) || defined(_M_AMD64) || defined (__arm64__) || defined (__aarch64__) - inline constexpr bool isX64() const { return true; } + inline constexpr static bool isX64() { return true; } # else - inline constexpr bool isX64() const { return false; } + inline constexpr static bool isX64() { return false; } # endif virtual bool hasAES() const = 0; diff --git a/src/backend/cpu/platform/BasicCpuInfo_arm.cpp b/src/backend/cpu/platform/BasicCpuInfo_arm.cpp index dea8de73..49e300e4 100644 --- a/src/backend/cpu/platform/BasicCpuInfo_arm.cpp +++ b/src/backend/cpu/platform/BasicCpuInfo_arm.cpp @@ -32,7 +32,7 @@ #endif -#include "common/cpu/BasicCpuInfo.h" +#include "backend/cpu/platform/BasicCpuInfo.h" xmrig::BasicCpuInfo::BasicCpuInfo() : From 83fdbbf29cba31b1b238567f7040fe6db2c133c9 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 29 Jun 2019 10:57:05 +0700 Subject: [PATCH 11/48] Added "features" and "algorithms" fields to API summary response. --- src/api/Api.cpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/api/Api.cpp b/src/api/Api.cpp index caebcba7..a1aeb4c2 100644 --- a/src/api/Api.cpp +++ b/src/api/Api.cpp @@ -41,6 +41,7 @@ #include "base/tools/Chrono.h" #include "core/config/Config.h" #include "core/Controller.h" +#include "crypto/common/Algorithm.h" #include "crypto/common/keccak.h" #include "version.h" @@ -126,6 +127,32 @@ void xmrig::Api::exec(IApiRequest &request) request.reply().AddMember("id", StringRef(m_id), allocator); request.reply().AddMember("worker_id", StringRef(m_workerId), allocator); request.reply().AddMember("uptime", (Chrono::steadyMSecs() - m_timestamp) / 1000, allocator); + + Value features(kArrayType); +# ifdef XMRIG_FEATURE_API + features.PushBack("api", allocator); +# endif +# ifdef XMRIG_FEATURE_ASM + features.PushBack("asm", allocator); +# endif +# ifdef XMRIG_FEATURE_HTTP + features.PushBack("http", allocator); +# endif +# ifdef XMRIG_FEATURE_LIBCPUID + features.PushBack("cpuid", allocator); +# endif +# ifdef XMRIG_FEATURE_TLS + features.PushBack("tls", allocator); +# endif + request.reply().AddMember("features", features, allocator); + + Value algorithms(kArrayType); + + for (int i = 0; i < Algorithm::MAX; ++i) { + algorithms.PushBack(StringRef(Algorithm(static_cast(i)).shortName()), allocator); + } + + request.reply().AddMember("algorithms", algorithms, allocator); } for (IApiListener *listener : m_listeners) { From b92807e8d83eddd6677cc811b6b97436b72c52ec Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 2 Jul 2019 22:56:28 +0700 Subject: [PATCH 12/48] Added support for multi-algorithm CPU threads settings. --- CMakeLists.txt | 10 +- src/backend/Threads.cpp | 145 ++++++++++++++++++ src/backend/Threads.h | 67 ++++++++ src/backend/backend.cmake | 12 ++ src/backend/cpu/CpuConfig.cpp | 52 ++++++- src/backend/cpu/CpuConfig.h | 14 +- src/backend/cpu/CpuThread.cpp | 71 +++++++++ src/backend/cpu/CpuThread.h | 63 ++++++++ src/backend/cpu/cpu.cmake | 8 +- src/backend/cpu/interfaces/ICpuInfo.h | 21 ++- src/backend/cpu/platform/AdvancedCpuInfo.cpp | 76 ++++++--- src/backend/cpu/platform/AdvancedCpuInfo.h | 29 ++-- src/backend/cpu/platform/BasicCpuInfo.cpp | 27 +++- src/backend/cpu/platform/BasicCpuInfo.h | 21 +-- src/core/config/Config.cpp | 10 +- src/core/config/Config.h | 6 +- src/crypto/common/Algorithm.cpp | 15 ++ src/crypto/common/Algorithm.h | 3 + src/crypto/common/Assembly.h | 4 +- .../{CpuThread.cpp => CpuThreadLegacy.cpp} | 26 ++-- .../{CpuThread.h => CpuThreadLegacy.h} | 14 +- src/workers/MultiWorker.cpp | 2 +- src/workers/Worker.cpp | 4 +- src/workers/Worker.h | 4 +- 24 files changed, 595 insertions(+), 109 deletions(-) create mode 100644 src/backend/Threads.cpp create mode 100644 src/backend/Threads.h create mode 100644 src/backend/backend.cmake create mode 100644 src/backend/cpu/CpuThread.cpp create mode 100644 src/backend/cpu/CpuThread.h rename src/workers/{CpuThread.cpp => CpuThreadLegacy.cpp} (78%) rename src/workers/{CpuThread.h => CpuThreadLegacy.h} (83%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7320b63d..ef4f8cee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,13 +18,13 @@ option(WITH_EMBEDDED_CONFIG "Enable internal embedded JSON config" OFF) include (CheckIncludeFile) include (cmake/cpu.cmake) include (src/base/base.cmake) -include (src/backend/cpu/cpu.cmake) +include (src/backend/backend.cmake) set(HEADERS "${HEADERS_BASE}" "${HEADERS_BASE_HTTP}" - "${HEADERS_CPU}" + "${HEADERS_BACKEND}" src/api/interfaces/IApiListener.h src/App.h src/common/Platform.h @@ -45,7 +45,7 @@ set(HEADERS src/net/strategies/DonateStrategy.h src/Summary.h src/version.h - src/workers/CpuThread.h + src/workers/CpuThreadLegacy.h src/workers/Hashrate.h src/workers/MultiWorker.h src/workers/ThreadHandle.h @@ -83,7 +83,7 @@ endif() set(SOURCES "${SOURCES_BASE}" "${SOURCES_BASE_HTTP}" - "${SOURCES_CPU}" + "${SOURCES_BACKEND}" src/App.cpp src/common/Platform.cpp src/core/config/Config.cpp @@ -94,7 +94,7 @@ set(SOURCES src/net/NetworkState.cpp src/net/strategies/DonateStrategy.cpp src/Summary.cpp - src/workers/CpuThread.cpp + src/workers/CpuThreadLegacy.cpp src/workers/Hashrate.cpp src/workers/MultiWorker.cpp src/workers/ThreadHandle.cpp diff --git a/src/backend/Threads.cpp b/src/backend/Threads.cpp new file mode 100644 index 00000000..11e1ec15 --- /dev/null +++ b/src/backend/Threads.cpp @@ -0,0 +1,145 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "backend/cpu/CpuThread.h" +#include "backend/Threads.h" +#include "rapidjson/document.h" + + +template +const std::vector &xmrig::Threads::get(const String &profileName) const +{ + static std::vector empty; + if (profileName.isNull() || !has(profileName)) { + return empty; + } + + return m_profiles.at(profileName); +} + + +template +xmrig::String xmrig::Threads::profileName(const Algorithm &algorithm, bool strict) const +{ + if (isDisabled(algorithm)) { + return String(); + } + + const String name = algorithm.shortName(); + if (has(name)) { + return name; + } + + if (m_aliases.count(algorithm) > 0) { + return m_aliases.at(algorithm); + } + + if (!strict && name.contains("/")) { + const String base = name.split('/').at(0); + if (has(base)) { + return base; + } + } + + return String(); +} + + +template +void xmrig::Threads::read(const rapidjson::Value &value) +{ + using namespace rapidjson; + + for (auto &member : value.GetObject()) { + if (member.value.IsArray()) { + std::vector threads; + + for (auto &v : member.value.GetArray()) { + T thread(v); + if (thread.isValid()) { + threads.push_back(std::move(thread)); + } + } + + if (!threads.empty()) { + move(member.name.GetString(), std::move(threads)); + } + + continue; + } + + const Algorithm algo(member.name.GetString()); + if (!algo.isValid()) { + continue; + } + + if (member.value.IsBool() && member.value.IsFalse()) { + disable(algo); + continue; + } + + if (member.value.IsString()) { + if (has(member.value.GetString())) { + m_aliases.insert({ algo, member.value.GetString() }); + } + else { + m_disabled.insert(algo); + } + } + } +} + + +template +void xmrig::Threads::toJSON(rapidjson::Value &out, rapidjson::Document &doc) const +{ + using namespace rapidjson; + auto &allocator = doc.GetAllocator(); + + for (const auto &kv : m_profiles) { + Value arr(kArrayType); + + for (const T &thread : kv.second) { + arr.PushBack(thread.toJSON(doc), allocator); + } + + out.AddMember(kv.first.toJSON(), arr, allocator); + } + + for (const Algorithm &algo : m_disabled) { + out.AddMember(StringRef(algo.shortName()), false, allocator); + } + + for (const auto &kv : m_aliases) { + out.AddMember(StringRef(kv.first.shortName()), kv.second.toJSON(), allocator); + } +} + + +namespace xmrig { + +template class Threads; + +} // namespace xmrig diff --git a/src/backend/Threads.h b/src/backend/Threads.h new file mode 100644 index 00000000..70bc02a4 --- /dev/null +++ b/src/backend/Threads.h @@ -0,0 +1,67 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_THREADS_H +#define XMRIG_THREADS_H + + +#include +#include + + +#include "base/tools/String.h" +#include "crypto/common/Algorithm.h" +#include "rapidjson/fwd.h" + + +namespace xmrig { + + +template +class Threads +{ +public: + inline bool has(const char *profile) const { return m_profiles.count(profile) > 0; } + inline bool isDisabled(const Algorithm &algo) const { return m_disabled.count(algo) > 0; } + inline bool isExist(const Algorithm &algo) const { return isDisabled(algo) || m_aliases.count(algo) > 0 || has(algo.shortName()); } + inline const std::vector &get(const Algorithm &algo, bool strict = false) const { return get(profileName(algo, strict)); } + inline void disable(const Algorithm &algo) { m_disabled.insert(algo); } + inline void move(const char *profile, std::vector &&threads) { m_profiles.insert({ profile, threads }); } + + const std::vector &get(const String &profileName) const; + String profileName(const Algorithm &algorithm, bool strict = false) const; + void read(const rapidjson::Value &value); + void toJSON(rapidjson::Value &out, rapidjson::Document &doc) const; + +private: + std::map m_aliases; + std::map > m_profiles; + std::set m_disabled; +}; + + +} /* namespace xmrig */ + + +#endif /* XMRIG_THREADS_H */ diff --git a/src/backend/backend.cmake b/src/backend/backend.cmake new file mode 100644 index 00000000..750cc9cb --- /dev/null +++ b/src/backend/backend.cmake @@ -0,0 +1,12 @@ +include (src/backend/cpu/cpu.cmake) + + +set(HEADERS_BACKEND + "${HEADERS_CPU}" + src/backend/Threads.h + ) + +set(SOURCES_BACKEND + "${SOURCES_CPU}" + src/backend/Threads.cpp + ) diff --git a/src/backend/cpu/CpuConfig.cpp b/src/backend/cpu/CpuConfig.cpp index 5284d607..34dcff44 100644 --- a/src/backend/cpu/CpuConfig.cpp +++ b/src/backend/cpu/CpuConfig.cpp @@ -31,17 +31,34 @@ namespace xmrig { - +static const char *kCn = "cn"; static const char *kEnabled = "enabled"; static const char *kHugePages = "huge-pages"; static const char *kHwAes = "hw-aes"; static const char *kPriority = "priority"; - #ifdef XMRIG_FEATURE_ASM static const char *kAsm = "asm"; #endif +#ifdef XMRIG_ALGO_CN_GPU +static const char *kCnGPU = "cn/gpu"; +#endif + +#ifdef XMRIG_ALGO_CN_LITE +static const char *kCnLite = "cn-lite"; +#endif + +#ifdef XMRIG_ALGO_CN_HEAVY +static const char *kCnHeavy = "cn-heavy"; +#endif + +#ifdef XMRIG_ALGO_CN_PICO +static const char *kCnPico = "cn-pico"; +#endif + +extern template class Threads; + } @@ -59,7 +76,6 @@ bool xmrig::CpuConfig::isHwAES() const rapidjson::Value xmrig::CpuConfig::toJSON(rapidjson::Document &doc) const { using namespace rapidjson; - auto &allocator = doc.GetAllocator(); Value obj(kObjectType); @@ -73,6 +89,8 @@ rapidjson::Value xmrig::CpuConfig::toJSON(rapidjson::Document &doc) const obj.AddMember(StringRef(kAsm), m_assembly.toJSON(), allocator); # endif + m_threads.toJSON(obj, doc); + return obj; } @@ -89,6 +107,34 @@ void xmrig::CpuConfig::read(const rapidjson::Value &value) # ifdef XMRIG_FEATURE_ASM m_assembly = Json::getValue(value, kAsm); # endif + + m_threads.read(value); + } + else if (value.IsBool() && value.IsFalse()) { + m_enabled = false; + } + else { + m_shouldSave = true; + + m_threads.disable(Algorithm::CN_0); + m_threads.move(kCn, Cpu::info()->threads(Algorithm::CN_0)); + +# ifdef XMRIG_ALGO_CN_GPU + m_threads.move(kCnGPU, Cpu::info()->threads(Algorithm::CN_GPU)); +# endif + +# ifdef XMRIG_ALGO_CN_LITE + m_threads.disable(Algorithm::CN_LITE_0); + m_threads.move(kCnLite, Cpu::info()->threads(Algorithm::CN_LITE_1)); +# endif + +# ifdef XMRIG_ALGO_CN_HEAVY + m_threads.move(kCnHeavy, Cpu::info()->threads(Algorithm::CN_HEAVY_0)); +# endif + +# ifdef XMRIG_ALGO_CN_PICO + m_threads.move(kCnPico, Cpu::info()->threads(Algorithm::CN_PICO_0)); +# endif } } diff --git a/src/backend/cpu/CpuConfig.h b/src/backend/cpu/CpuConfig.h index 04dd9175..66da3a5f 100644 --- a/src/backend/cpu/CpuConfig.h +++ b/src/backend/cpu/CpuConfig.h @@ -26,6 +26,8 @@ #define XMRIG_CPUCONFIG_H +#include "backend/cpu/CpuThread.h" +#include "backend/Threads.h" #include "crypto/common/Assembly.h" @@ -47,11 +49,12 @@ public: rapidjson::Value toJSON(rapidjson::Document &doc) const; void read(const rapidjson::Value &value); - inline bool isEnabled() const { return m_enabled; } - inline bool isHugePages() const { return m_hugePages; } - inline bool isShouldSave() const { return m_shouldSave; } - inline const Assembly &assembly() const { return m_assembly; } - inline int priority() const { return m_priority; } + inline bool isEnabled() const { return m_enabled; } + inline bool isHugePages() const { return m_hugePages; } + inline bool isShouldSave() const { return m_shouldSave; } + inline const Assembly &assembly() const { return m_assembly; } + inline const Threads &threads() const { return m_threads; } + inline int priority() const { return m_priority; } private: void setAesMode(const rapidjson::Value &aesMode); @@ -63,6 +66,7 @@ private: bool m_hugePages = true; bool m_shouldSave = false; int m_priority = -1; + Threads m_threads; }; diff --git a/src/backend/cpu/CpuThread.cpp b/src/backend/cpu/CpuThread.cpp new file mode 100644 index 00000000..e7132cfa --- /dev/null +++ b/src/backend/cpu/CpuThread.cpp @@ -0,0 +1,71 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "backend/cpu/CpuThread.h" +#include "base/io/json/Json.h" +#include "rapidjson/document.h" + + +namespace xmrig { + + +static const char *kAffinity = "affinity"; +static const char *kIntensity = "intensity"; + + +} + + + +xmrig::CpuThread::CpuThread(const rapidjson::Value &value) +{ + if (value.IsObject()) { + m_intensity = Json::getInt(value, kIntensity, -1); + m_affinity = Json::getInt(value, kAffinity, -1); + } + else if (value.IsInt()) { + m_intensity = 1; + m_affinity = value.GetInt(); + } +} + + +rapidjson::Value xmrig::CpuThread::toJSON(rapidjson::Document &doc) const +{ + using namespace rapidjson; + + if (intensity() > 1) { + auto &allocator = doc.GetAllocator(); + + Value obj(kObjectType); + + obj.AddMember(StringRef(kIntensity), m_intensity, allocator); + obj.AddMember(StringRef(kAffinity), m_affinity, allocator); + + return obj; + } + + return Value(m_affinity); +} diff --git a/src/backend/cpu/CpuThread.h b/src/backend/cpu/CpuThread.h new file mode 100644 index 00000000..444b2709 --- /dev/null +++ b/src/backend/cpu/CpuThread.h @@ -0,0 +1,63 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_CPUTHREADCONFIG_H +#define XMRIG_CPUTHREADCONFIG_H + + +#include + + +#include "rapidjson/fwd.h" + + +namespace xmrig { + + +class CpuThread +{ +public: + inline constexpr CpuThread(int intensity = 1, int affinity = -1) : m_affinity(affinity), m_intensity(intensity) {} + + CpuThread(const rapidjson::Value &value); + + inline bool isValid() const { return m_intensity >= 1 && m_intensity <= 5; } + inline int affinity() const { return m_affinity; } + inline int intensity() const { return m_intensity; } + + rapidjson::Value toJSON(rapidjson::Document &doc) const; + +private: + int m_affinity = -1; + int m_intensity = -1; +}; + + +typedef std::vector CpuThreads; + + +} /* namespace xmrig */ + + +#endif /* XMRIG_CPUTHREADCONFIG_H */ diff --git a/src/backend/cpu/cpu.cmake b/src/backend/cpu/cpu.cmake index 03ca7075..df9b7cea 100644 --- a/src/backend/cpu/cpu.cmake +++ b/src/backend/cpu/cpu.cmake @@ -1,12 +1,14 @@ set(HEADERS_CPU - src/backend/cpu/Cpu.h - src/backend/cpu/CpuConfig.h - src/backend/cpu/interfaces/ICpuInfo.h + src/backend/cpu/Cpu.h + src/backend/cpu/CpuConfig.h + src/backend/cpu/CpuThread.h + src/backend/cpu/interfaces/ICpuInfo.h ) set(SOURCES_CPU src/backend/cpu/Cpu.cpp src/backend/cpu/CpuConfig.cpp + src/backend/cpu/CpuThread.cpp ) diff --git a/src/backend/cpu/interfaces/ICpuInfo.h b/src/backend/cpu/interfaces/ICpuInfo.h index abff7a6c..74f6baee 100644 --- a/src/backend/cpu/interfaces/ICpuInfo.h +++ b/src/backend/cpu/interfaces/ICpuInfo.h @@ -26,11 +26,9 @@ #define XMRIG_CPUINFO_H -#include -#include - - +#include "backend/cpu/CpuThread.h" #include "crypto/common/Assembly.h" +#include "crypto/common/Algorithm.h" namespace xmrig { @@ -47,18 +45,19 @@ public: inline constexpr static bool isX64() { return false; } # endif + virtual Assembly::Id assembly() const = 0; virtual bool hasAES() const = 0; virtual bool hasAVX2() const = 0; virtual bool isSupported() const = 0; virtual const char *brand() const = 0; - virtual int32_t cores() const = 0; - virtual int32_t L2() const = 0; - virtual int32_t L3() const = 0; - virtual int32_t nodes() const = 0; - virtual int32_t sockets() const = 0; - virtual int32_t threads() const = 0; + virtual CpuThreads threads(const Algorithm &algorithm) const = 0; + virtual size_t cores() const = 0; + virtual size_t L2() const = 0; + virtual size_t L3() const = 0; + virtual size_t nodes() const = 0; virtual size_t optimalThreadsCount(size_t memSize, int maxCpuUsage) const = 0; - virtual Assembly::Id assembly() const = 0; + virtual size_t sockets() const = 0; + virtual size_t threads() const = 0; }; diff --git a/src/backend/cpu/platform/AdvancedCpuInfo.cpp b/src/backend/cpu/platform/AdvancedCpuInfo.cpp index fc7f734d..4c3b30ab 100644 --- a/src/backend/cpu/platform/AdvancedCpuInfo.cpp +++ b/src/backend/cpu/platform/AdvancedCpuInfo.cpp @@ -26,51 +26,43 @@ #include #include +#include + #include "backend/cpu/platform/AdvancedCpuInfo.h" xmrig::AdvancedCpuInfo::AdvancedCpuInfo() : - m_aes(false), - m_avx2(false), - m_L2_exclusive(false), - m_brand(), - m_cores(0), - m_L2(0), - m_L3(0), - m_sockets(1), - m_threads(0) + m_brand() { - struct cpu_raw_data_t raw = { 0 }; - struct cpu_id_t data = { 0 }; + struct cpu_raw_data_t raw = {}; + struct cpu_id_t data = {}; cpuid_get_raw_data(&raw); cpu_identify(&raw, &data); strncpy(m_brand, data.brand_str, sizeof(m_brand)); - m_threads = data.total_logical_cpus; - m_sockets = threads() / data.num_logical_cpus; - if (m_sockets == 0) { - m_sockets = 1; - } + m_threads = static_cast(data.total_logical_cpus); + m_sockets = std::max(threads() / static_cast(data.num_logical_cpus), 1); + m_cores = static_cast(data.num_cores) * m_sockets; + m_L3 = data.l3_cache > 0 ? static_cast(data.l3_cache) * m_sockets : 0; - m_cores = data.num_cores * m_sockets; - m_L3 = data.l3_cache > 0 ? data.l3_cache * m_sockets : 0; + const size_t l2 = static_cast(data.l2_cache); // Workaround for AMD CPUs https://github.com/anrieff/libcpuid/issues/97 if (data.vendor == VENDOR_AMD && data.ext_family >= 0x15 && data.ext_family < 0x17) { - m_L2 = data.l2_cache * (cores() / 2) * m_sockets; + m_L2 = l2 * (cores() / 2) * m_sockets; m_L2_exclusive = true; } // Workaround for Intel Pentium Dual-Core, Core Duo, Core 2 Duo, Core 2 Quad and their Xeon homologue // These processors have L2 cache shared by 2 cores. else if (data.vendor == VENDOR_INTEL && data.ext_family == 0x06 && (data.ext_model == 0x0E || data.ext_model == 0x0F || data.ext_model == 0x17)) { - int l2_count_per_socket = cores() > 1 ? cores() / 2 : 1; - m_L2 = data.l2_cache > 0 ? data.l2_cache * l2_count_per_socket * m_sockets : 0; + size_t l2_count_per_socket = cores() > 1 ? cores() / 2 : 1; + m_L2 = data.l2_cache > 0 ? l2 * l2_count_per_socket * m_sockets : 0; } else{ - m_L2 = data.l2_cache > 0 ? data.l2_cache * cores() * m_sockets : 0; + m_L2 = data.l2_cache > 0 ? l2 * cores() * m_sockets : 0; } if (data.flags[CPU_FEATURE_AES]) { @@ -125,3 +117,43 @@ size_t xmrig::AdvancedCpuInfo::optimalThreadsCount(size_t memSize, int maxCpuUsa return count < 1 ? 1 : count; } + + +xmrig::CpuThreads xmrig::AdvancedCpuInfo::threads(const Algorithm &algorithm) const +{ + if (threads() == 1) { + return CpuThreads(1); + } + +# ifdef XMRIG_ALGO_CN_GPU + if (algorithm == Algorithm::CN_GPU) { + return CpuThreads(threads()); + } +# endif + + size_t cache = 0; + size_t count = 0; + + if (m_L3) { + cache = m_L2_exclusive ? (m_L2 + m_L3) : m_L3; + } + else { + cache = m_L2; + } + + if (cache) { + cache *= 1024; + const size_t memory = algorithm.memory(); + + count = cache / memory; + + if (cache % memory >= memory / 2) { + count++; + } + } + else { + count = threads() / 2; + } + + return CpuThreads(std::max(std::min(count, threads()), 1)); +} diff --git a/src/backend/cpu/platform/AdvancedCpuInfo.h b/src/backend/cpu/platform/AdvancedCpuInfo.h index 83c3d8e5..9852f6bd 100644 --- a/src/backend/cpu/platform/AdvancedCpuInfo.h +++ b/src/backend/cpu/platform/AdvancedCpuInfo.h @@ -39,30 +39,31 @@ public: protected: size_t optimalThreadsCount(size_t memSize, int maxCpuUsage) const override; + CpuThreads threads(const Algorithm &algorithm) const override; inline Assembly::Id assembly() const override { return m_assembly; } inline bool hasAES() const override { return m_aes; } inline bool hasAVX2() const override { return m_avx2; } inline bool isSupported() const override { return true; } inline const char *brand() const override { return m_brand; } - inline int32_t cores() const override { return m_cores; } - inline int32_t L2() const override { return m_L2; } - inline int32_t L3() const override { return m_L3; } - inline int32_t nodes() const override { return -1; } - inline int32_t sockets() const override { return m_sockets; } - inline int32_t threads() const override { return m_threads; } + inline size_t cores() const override { return m_cores; } + inline size_t L2() const override { return m_L2; } + inline size_t L3() const override { return m_L3; } + inline size_t nodes() const override { return 0; } + inline size_t sockets() const override { return m_sockets; } + inline size_t threads() const override { return m_threads; } private: Assembly m_assembly; - bool m_aes; - bool m_avx2; - bool m_L2_exclusive; + bool m_aes = false; + bool m_avx2 = false; + bool m_L2_exclusive = false; char m_brand[64]; - int32_t m_cores; - int32_t m_L2; - int32_t m_L3; - int32_t m_sockets; - int32_t m_threads; + size_t m_cores = 0; + size_t m_L2 = 0; + size_t m_L3 = 0; + size_t m_sockets = 1; + size_t m_threads = 0; }; diff --git a/src/backend/cpu/platform/BasicCpuInfo.cpp b/src/backend/cpu/platform/BasicCpuInfo.cpp index 04ff589b..26237468 100644 --- a/src/backend/cpu/platform/BasicCpuInfo.cpp +++ b/src/backend/cpu/platform/BasicCpuInfo.cpp @@ -22,6 +22,7 @@ * along with this program. If not, see . */ +#include #include #include @@ -123,9 +124,9 @@ static inline bool has_ossave() xmrig::BasicCpuInfo::BasicCpuInfo() : m_assembly(Assembly::NONE), + m_brand(), m_aes(has_aes_ni()), m_avx2(has_avx2() && has_ossave()), - m_brand(), m_threads(std::thread::hardware_concurrency()) { cpu_brand_string(m_brand); @@ -158,3 +159,27 @@ size_t xmrig::BasicCpuInfo::optimalThreadsCount(size_t memSize, int maxCpuUsage) return count < 1 ? 1 : count; } + + +xmrig::CpuThreads xmrig::BasicCpuInfo::threads(const Algorithm &algorithm) const +{ + if (threads() == 1) { + return CpuThreads(1); + } + +# ifdef XMRIG_ALGO_CN_GPU + if (algorithm == Algorithm::CN_GPU) { + return CpuThreads(threads()); + } +# endif + + if (algorithm.family() == Algorithm::CN_LITE || algorithm.family() == Algorithm::CN_PICO) { + return CpuThreads(threads()); + } + + if (algorithm.family() == Algorithm::CN_HEAVY) { + return CpuThreads(std::max(threads() / 4, 1)); + } + + return CpuThreads(std::max(threads() / 2, 1)); +} diff --git a/src/backend/cpu/platform/BasicCpuInfo.h b/src/backend/cpu/platform/BasicCpuInfo.h index 4d4a5163..12c275dd 100644 --- a/src/backend/cpu/platform/BasicCpuInfo.h +++ b/src/backend/cpu/platform/BasicCpuInfo.h @@ -39,25 +39,26 @@ public: protected: size_t optimalThreadsCount(size_t memSize, int maxCpuUsage) const override; + CpuThreads threads(const Algorithm &algorithm) const override; inline Assembly::Id assembly() const override { return m_assembly; } inline bool hasAES() const override { return m_aes; } inline bool hasAVX2() const override { return m_avx2; } inline bool isSupported() const override { return true; } inline const char *brand() const override { return m_brand; } - inline int32_t cores() const override { return -1; } - inline int32_t L2() const override { return -1; } - inline int32_t L3() const override { return -1; } - inline int32_t nodes() const override { return -1; } - inline int32_t sockets() const override { return 1; } - inline int32_t threads() const override { return m_threads; } + inline size_t cores() const override { return 0; } + inline size_t L2() const override { return 0; } + inline size_t L3() const override { return 0; } + inline size_t nodes() const override { return 0; } + inline size_t sockets() const override { return 1; } + inline size_t threads() const override { return m_threads; } private: Assembly m_assembly; - bool m_aes; - bool m_avx2; - char m_brand[64]; - int32_t m_threads; + char m_brand[64 + 6]; + const bool m_aes; + const bool m_avx2; + const size_t m_threads; }; diff --git a/src/core/config/Config.cpp b/src/core/config/Config.cpp index 33f4cc44..87abbb91 100644 --- a/src/core/config/Config.cpp +++ b/src/core/config/Config.cpp @@ -36,7 +36,7 @@ #include "rapidjson/document.h" #include "rapidjson/filewritestream.h" #include "rapidjson/prettywriter.h" -#include "workers/CpuThread.h" +#include "workers/CpuThreadLegacy.h" xmrig::Config::Config() : @@ -125,7 +125,7 @@ bool xmrig::Config::finalize() m_threads.mode = Advanced; for (size_t i = 0; i < m_threads.cpu.size(); ++i) { - m_threads.list.push_back(CpuThread::createFromData(i, algorithm, m_threads.cpu[i], m_cpu.priority(), !m_cpu.isHwAES())); + m_threads.list.push_back(CpuThreadLegacy::createFromData(i, algorithm, m_threads.cpu[i], m_cpu.priority(), !m_cpu.isHwAES())); } return true; @@ -134,7 +134,7 @@ bool xmrig::Config::finalize() const AlgoVariant av = getAlgoVariant(); m_threads.mode = m_threads.count ? Simple : Automatic; - const size_t size = CpuThread::multiway(av) * CnAlgo<>::memory(algorithm) / 1024; // FIXME MEMORY + const size_t size = CpuThreadLegacy::multiway(av) * CnAlgo<>::memory(algorithm) / 1024; // FIXME MEMORY if (!m_threads.count) { m_threads.count = Cpu::info()->optimalThreadsCount(size, 100); @@ -147,7 +147,7 @@ bool xmrig::Config::finalize() // } for (size_t i = 0; i < m_threads.count; ++i) { - m_threads.list.push_back(CpuThread::createFromAV(i, algorithm, av, m_threads.mask, m_cpu.priority(), m_cpu.assembly())); + m_threads.list.push_back(CpuThreadLegacy::createFromAV(i, algorithm, av, m_threads.mask, m_cpu.priority(), m_cpu.assembly())); } m_shouldSave = m_threads.mode == Automatic; @@ -175,7 +175,7 @@ void xmrig::Config::setThreads(const rapidjson::Value &threads) } if (value.HasMember("low_power_mode")) { - auto data = CpuThread::parse(value); + auto data = CpuThreadLegacy::parse(value); if (data.valid) { m_threads.cpu.push_back(std::move(data)); diff --git a/src/core/config/Config.h b/src/core/config/Config.h index 76720889..7b765892 100644 --- a/src/core/config/Config.h +++ b/src/core/config/Config.h @@ -34,7 +34,7 @@ #include "base/kernel/config/BaseConfig.h" #include "common/xmrig.h" #include "rapidjson/fwd.h" -#include "workers/CpuThread.h" +#include "workers/CpuThreadLegacy.h" namespace xmrig { @@ -59,7 +59,7 @@ public: void getJSON(rapidjson::Document &doc) const override; inline AlgoVariant algoVariant() const { return m_algoVariant; } - inline bool isShouldSave() const { return (m_shouldSave || m_upgrade) && isAutoSave(); } + inline bool isShouldSave() const { return (m_shouldSave || m_upgrade || m_cpu.isShouldSave()) && isAutoSave(); } inline const CpuConfig &cpu() const { return m_cpu; } inline const std::vector &threads() const { return m_threads.list; } inline int threadsCount() const { return static_cast(m_threads.list.size()); } @@ -81,7 +81,7 @@ private: int64_t mask; size_t count; - std::vector cpu; + std::vector cpu; std::vector list; ThreadsMode mode; }; diff --git a/src/crypto/common/Algorithm.cpp b/src/crypto/common/Algorithm.cpp index 66b3ddda..81ee6655 100644 --- a/src/crypto/common/Algorithm.cpp +++ b/src/crypto/common/Algorithm.cpp @@ -30,6 +30,7 @@ #include +#include "crypto/cn/CnAlgo.h" #include "crypto/common/Algorithm.h" #include "rapidjson/document.h" @@ -123,6 +124,20 @@ rapidjson::Value xmrig::Algorithm::toJSON() const } +size_t xmrig::Algorithm::memory() const +{ + if (family() < RANDOM_X) { + return CnAlgo<>::memory(m_id); + } + + if (m_id == RX_WOW) { + return 0x100000; + } + + return 0; +} + + xmrig::Algorithm::Family xmrig::Algorithm::family(Id id) { switch (id) { diff --git a/src/crypto/common/Algorithm.h b/src/crypto/common/Algorithm.h index 92c6f405..08d1c4cd 100644 --- a/src/crypto/common/Algorithm.h +++ b/src/crypto/common/Algorithm.h @@ -94,11 +94,14 @@ public: inline Family family() const { return family(m_id); } inline Id id() const { return m_id; } + inline bool operator!=(Algorithm::Id id) const { return m_id != id; } inline bool operator!=(const Algorithm &other) const { return !isEqual(other); } + inline bool operator==(Algorithm::Id id) const { return m_id == id; } inline bool operator==(const Algorithm &other) const { return isEqual(other); } inline operator Algorithm::Id() const { return m_id; } rapidjson::Value toJSON() const; + size_t memory() const; static Family family(Id id); static Id parse(const char *name); diff --git a/src/crypto/common/Assembly.h b/src/crypto/common/Assembly.h index 0b3f29b3..afd8a536 100644 --- a/src/crypto/common/Assembly.h +++ b/src/crypto/common/Assembly.h @@ -59,10 +59,10 @@ public: inline bool isEqual(const Assembly &other) const { return m_id == other.m_id; } + inline bool operator!=(Assembly::Id id) const { return m_id != id; } inline bool operator!=(const Assembly &other) const { return !isEqual(other); } - inline bool operator!=(const Assembly::Id &id) const { return m_id != id; } + inline bool operator==(Assembly::Id id) const { return m_id == id; } inline bool operator==(const Assembly &other) const { return isEqual(other); } - inline bool operator==(const Assembly::Id &id) const { return m_id == id; } inline operator Assembly::Id() const { return m_id; } private: diff --git a/src/workers/CpuThread.cpp b/src/workers/CpuThreadLegacy.cpp similarity index 78% rename from src/workers/CpuThread.cpp rename to src/workers/CpuThreadLegacy.cpp index 7011da12..df9b9904 100644 --- a/src/workers/CpuThread.cpp +++ b/src/workers/CpuThreadLegacy.cpp @@ -31,14 +31,14 @@ #include "crypto/common/VirtualMemory.h" #include "Mem.h" #include "rapidjson/document.h" -#include "workers/CpuThread.h" +#include "workers/CpuThreadLegacy.h" static const xmrig::CnHash cnHash; -xmrig::CpuThread::CpuThread(size_t index, Algorithm algorithm, AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch, Assembly assembly) : +xmrig::CpuThreadLegacy::CpuThreadLegacy(size_t index, Algorithm algorithm, AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch, Assembly assembly) : m_algorithm(algorithm), m_av(av), m_assembly(assembly), @@ -52,20 +52,20 @@ xmrig::CpuThread::CpuThread(size_t index, Algorithm algorithm, AlgoVariant av, M } -xmrig::cn_hash_fun xmrig::CpuThread::fn(const Algorithm &algorithm) const +xmrig::cn_hash_fun xmrig::CpuThreadLegacy::fn(const Algorithm &algorithm) const { return cnHash.fn(algorithm, m_av, m_assembly); } -bool xmrig::CpuThread::isSoftAES(AlgoVariant av) +bool xmrig::CpuThreadLegacy::isSoftAES(AlgoVariant av) { return av == AV_SINGLE_SOFT || av == AV_DOUBLE_SOFT || av > AV_PENTA; } -xmrig::CpuThread *xmrig::CpuThread::createFromAV(size_t index, const Algorithm &algorithm, AlgoVariant av, int64_t affinity, int priority, Assembly assembly) +xmrig::CpuThreadLegacy *xmrig::CpuThreadLegacy::createFromAV(size_t index, const Algorithm &algorithm, AlgoVariant av, int64_t affinity, int priority, Assembly assembly) { assert(av > AV_AUTO && av < AV_MAX); @@ -88,11 +88,11 @@ xmrig::CpuThread *xmrig::CpuThread::createFromAV(size_t index, const Algorithm & } } - return new CpuThread(index, algorithm, av, multiway(av), cpuId, priority, isSoftAES(av), false, assembly); + return new CpuThreadLegacy(index, algorithm, av, multiway(av), cpuId, priority, isSoftAES(av), false, assembly); } -xmrig::CpuThread *xmrig::CpuThread::createFromData(size_t index, const Algorithm &algorithm, const CpuThread::Data &data, int priority, bool softAES) +xmrig::CpuThreadLegacy *xmrig::CpuThreadLegacy::createFromData(size_t index, const Algorithm &algorithm, const CpuThreadLegacy::Data &data, int priority, bool softAES) { int av = AV_AUTO; const Multiway multiway = data.multiway; @@ -106,11 +106,11 @@ xmrig::CpuThread *xmrig::CpuThread::createFromData(size_t index, const Algorithm assert(av > AV_AUTO && av < AV_MAX); - return new CpuThread(index, algorithm, static_cast(av), multiway, data.affinity, priority, softAES, false, data.assembly); + return new CpuThreadLegacy(index, algorithm, static_cast(av), multiway, data.affinity, priority, softAES, false, data.assembly); } -xmrig::CpuThread::Data xmrig::CpuThread::parse(const rapidjson::Value &object) +xmrig::CpuThreadLegacy::Data xmrig::CpuThreadLegacy::parse(const rapidjson::Value &object) { Data data; @@ -140,7 +140,7 @@ xmrig::CpuThread::Data xmrig::CpuThread::parse(const rapidjson::Value &object) } -xmrig::IThread::Multiway xmrig::CpuThread::multiway(AlgoVariant av) +xmrig::IThread::Multiway xmrig::CpuThreadLegacy::multiway(AlgoVariant av) { switch (av) { case AV_SINGLE: @@ -172,7 +172,7 @@ xmrig::IThread::Multiway xmrig::CpuThread::multiway(AlgoVariant av) #ifdef APP_DEBUG -void xmrig::CpuThread::print() const +void xmrig::CpuThreadLegacy::print() const { LOG_DEBUG(GREEN_BOLD("CPU thread: ") " index " WHITE_BOLD("%zu") ", multiway " WHITE_BOLD("%d") ", av " WHITE_BOLD("%d") ",", index(), static_cast(multiway()), static_cast(m_av)); @@ -187,7 +187,7 @@ void xmrig::CpuThread::print() const #ifdef XMRIG_FEATURE_API -rapidjson::Value xmrig::CpuThread::toAPI(rapidjson::Document &doc) const +rapidjson::Value xmrig::CpuThreadLegacy::toAPI(rapidjson::Document &doc) const { using namespace rapidjson; @@ -206,7 +206,7 @@ rapidjson::Value xmrig::CpuThread::toAPI(rapidjson::Document &doc) const #endif -rapidjson::Value xmrig::CpuThread::toConfig(rapidjson::Document &doc) const +rapidjson::Value xmrig::CpuThreadLegacy::toConfig(rapidjson::Document &doc) const { using namespace rapidjson; diff --git a/src/workers/CpuThread.h b/src/workers/CpuThreadLegacy.h similarity index 83% rename from src/workers/CpuThread.h rename to src/workers/CpuThreadLegacy.h index a43a0c09..ed69d8ac 100644 --- a/src/workers/CpuThread.h +++ b/src/workers/CpuThreadLegacy.h @@ -22,8 +22,8 @@ * along with this program. If not, see . */ -#ifndef XMRIG_CPUTHREAD_H -#define XMRIG_CPUTHREAD_H +#ifndef XMRIG_CPUTHREADLEGACY_H +#define XMRIG_CPUTHREADLEGACY_H #include "common/xmrig.h" @@ -37,7 +37,7 @@ struct cryptonight_ctx; namespace xmrig { -class CpuThread : public IThread +class CpuThreadLegacy : public IThread { public: struct Data @@ -59,13 +59,13 @@ public: }; - CpuThread(size_t index, Algorithm algorithm, AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch, Assembly assembly); + CpuThreadLegacy(size_t index, Algorithm algorithm, AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch, Assembly assembly); cn_hash_fun fn(const Algorithm &algorithm) const; static bool isSoftAES(AlgoVariant av); - static CpuThread *createFromAV(size_t index, const Algorithm &algorithm, AlgoVariant av, int64_t affinity, int priority, Assembly assembly); - static CpuThread *createFromData(size_t index, const Algorithm &algorithm, const CpuThread::Data &data, int priority, bool softAES); + static CpuThreadLegacy *createFromAV(size_t index, const Algorithm &algorithm, AlgoVariant av, int64_t affinity, int priority, Assembly assembly); + static CpuThreadLegacy *createFromData(size_t index, const Algorithm &algorithm, const CpuThreadLegacy::Data &data, int priority, bool softAES); static Data parse(const rapidjson::Value &object); static Multiway multiway(AlgoVariant av); @@ -106,4 +106,4 @@ private: } /* namespace xmrig */ -#endif /* XMRIG_CPUTHREAD_H */ +#endif /* XMRIG_CPUTHREADLEGACY_H */ diff --git a/src/workers/MultiWorker.cpp b/src/workers/MultiWorker.cpp index 52e98e0a..0ac026bc 100644 --- a/src/workers/MultiWorker.cpp +++ b/src/workers/MultiWorker.cpp @@ -28,7 +28,7 @@ #include "crypto/cn/CryptoNight_test.h" -#include "workers/CpuThread.h" +#include "workers/CpuThreadLegacy.h" #include "workers/MultiWorker.h" #include "workers/Workers.h" diff --git a/src/workers/Worker.cpp b/src/workers/Worker.cpp index c6ea6d9a..4f69d905 100644 --- a/src/workers/Worker.cpp +++ b/src/workers/Worker.cpp @@ -26,7 +26,7 @@ #include "backend/cpu/Cpu.h" #include "common/Platform.h" -#include "workers/CpuThread.h" +#include "workers/CpuThreadLegacy.h" #include "workers/ThreadHandle.h" #include "workers/Worker.h" @@ -39,7 +39,7 @@ Worker::Worker(ThreadHandle *handle) : m_timestamp(0), m_count(0), m_sequence(0), - m_thread(static_cast(handle->config())) + m_thread(static_cast(handle->config())) { if (xmrig::Cpu::info()->threads() > 1 && m_thread->affinity() != -1L) { Platform::setThreadAffinity(m_thread->affinity()); diff --git a/src/workers/Worker.h b/src/workers/Worker.h index 4710bcc5..3d40257d 100644 --- a/src/workers/Worker.h +++ b/src/workers/Worker.h @@ -37,7 +37,7 @@ class ThreadHandle; namespace xmrig { - class CpuThread; + class CpuThreadLegacy; } @@ -62,7 +62,7 @@ protected: std::atomic m_timestamp; uint64_t m_count; uint64_t m_sequence; - xmrig::CpuThread *m_thread; + xmrig::CpuThreadLegacy *m_thread; }; From 9bf4c2c98f2d24bb673014d3166bbbf3bbd3bfa2 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 6 Jul 2019 11:31:12 +0700 Subject: [PATCH 13/48] Generate "rx" and "rx/wow" sections of CPU threads. --- src/backend/cpu/CpuConfig.cpp | 10 ++++++++++ src/backend/cpu/platform/AdvancedCpuInfo.cpp | 4 ++-- src/crypto/common/Algorithm.cpp | 14 ++++++++++---- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/backend/cpu/CpuConfig.cpp b/src/backend/cpu/CpuConfig.cpp index 34dcff44..b4a9c363 100644 --- a/src/backend/cpu/CpuConfig.cpp +++ b/src/backend/cpu/CpuConfig.cpp @@ -57,6 +57,11 @@ static const char *kCnHeavy = "cn-heavy"; static const char *kCnPico = "cn-pico"; #endif +#ifdef XMRIG_ALGO_RANDOMX +static const char *kRx = "rx"; +static const char *kRxWOW = "rx/wow"; +#endif + extern template class Threads; } @@ -135,6 +140,11 @@ void xmrig::CpuConfig::read(const rapidjson::Value &value) # ifdef XMRIG_ALGO_CN_PICO m_threads.move(kCnPico, Cpu::info()->threads(Algorithm::CN_PICO_0)); # endif + +# ifdef XMRIG_ALGO_RANDOMX + m_threads.move(kRx, Cpu::info()->threads(Algorithm::RX_0)); + m_threads.move(kRxWOW, Cpu::info()->threads(Algorithm::RX_WOW)); +# endif } } diff --git a/src/backend/cpu/platform/AdvancedCpuInfo.cpp b/src/backend/cpu/platform/AdvancedCpuInfo.cpp index 4c3b30ab..b5b2fe91 100644 --- a/src/backend/cpu/platform/AdvancedCpuInfo.cpp +++ b/src/backend/cpu/platform/AdvancedCpuInfo.cpp @@ -22,12 +22,11 @@ * along with this program. If not, see . */ +#include #include #include #include -#include - #include "backend/cpu/platform/AdvancedCpuInfo.h" @@ -144,6 +143,7 @@ xmrig::CpuThreads xmrig::AdvancedCpuInfo::threads(const Algorithm &algorithm) co if (cache) { cache *= 1024; const size_t memory = algorithm.memory(); + assert(memory > 0); count = cache / memory; diff --git a/src/crypto/common/Algorithm.cpp b/src/crypto/common/Algorithm.cpp index 4af3fd41..7680ef02 100644 --- a/src/crypto/common/Algorithm.cpp +++ b/src/crypto/common/Algorithm.cpp @@ -130,7 +130,10 @@ rapidjson::Value xmrig::Algorithm::toJSON() const size_t xmrig::Algorithm::memory() const { - if (family() < RANDOM_X) { + const Family f = family(); + assert(f != UNKNOWN); + + if (f < RANDOM_X) { return CnAlgo<>::memory(m_id); } @@ -138,7 +141,7 @@ size_t xmrig::Algorithm::memory() const return 0x100000; } - return 0; + return 0x200000; } @@ -181,12 +184,15 @@ xmrig::Algorithm::Family xmrig::Algorithm::family(Id id) # endif # ifdef XMRIG_ALGO_RANDOMX + case RX_0: case RX_WOW: + case RX_LOKI: return RANDOM_X; # endif - default: - break; + case INVALID: + case MAX: + return UNKNOWN; } return UNKNOWN; From ea1149a971bdf57482649c5ff180b6b6e7a4b87b Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 6 Jul 2019 15:22:19 +0700 Subject: [PATCH 14/48] Added class JobResults. --- CMakeLists.txt | 4 +- src/crypto/common/Algorithm.cpp | 2 + src/net/JobResults.cpp | 139 ++++++++++++++++++ src/net/JobResults.h | 49 ++++++ src/net/Network.cpp | 5 +- src/{ => net}/interfaces/IJobResultListener.h | 0 src/workers/MultiWorker.cpp | 3 +- src/workers/Workers.cpp | 37 ----- src/workers/Workers.h | 7 - 9 files changed, 199 insertions(+), 47 deletions(-) create mode 100644 src/net/JobResults.cpp create mode 100644 src/net/JobResults.h rename src/{ => net}/interfaces/IJobResultListener.h (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index d252af5d..33d3ad70 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,11 +35,12 @@ set(HEADERS src/core/config/ConfigTransform.h src/core/config/usage.h src/core/Controller.h - src/interfaces/IJobResultListener.h src/interfaces/IThread.h src/interfaces/IWorker.h src/Mem.h + src/net/interfaces/IJobResultListener.h src/net/JobResult.h + src/net/JobResults.h src/net/Network.h src/net/NetworkState.h src/net/strategies/DonateStrategy.h @@ -90,6 +91,7 @@ set(SOURCES src/core/config/ConfigTransform.cpp src/core/Controller.cpp src/Mem.cpp + src/net/JobResults.cpp src/net/Network.cpp src/net/NetworkState.cpp src/net/strategies/DonateStrategy.cpp diff --git a/src/crypto/common/Algorithm.cpp b/src/crypto/common/Algorithm.cpp index 7680ef02..ab63204f 100644 --- a/src/crypto/common/Algorithm.cpp +++ b/src/crypto/common/Algorithm.cpp @@ -137,9 +137,11 @@ size_t xmrig::Algorithm::memory() const return CnAlgo<>::memory(m_id); } +# ifdef XMRIG_ALGO_RANDOMX if (m_id == RX_WOW) { return 0x100000; } +# endif return 0x200000; } diff --git a/src/net/JobResults.cpp b/src/net/JobResults.cpp new file mode 100644 index 00000000..8c65b5e4 --- /dev/null +++ b/src/net/JobResults.cpp @@ -0,0 +1,139 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include +#include +#include + + +#include "base/tools/Handle.h" +#include "net/interfaces/IJobResultListener.h" +#include "net/JobResult.h" +#include "net/JobResults.h" + + +namespace xmrig { + + +class JobResultsPrivate +{ +public: + inline JobResultsPrivate() + { + uv_mutex_init(&m_mutex); + + m_async = new uv_async_t; + m_async->data = this; + + uv_async_init(uv_default_loop(), m_async, JobResultsPrivate::onResult); + } + + + inline ~JobResultsPrivate() + { + Handle::close(m_async); + } + + + void setListener(IJobResultListener *listener) + { + m_listener = listener; + } + + + void submit(const JobResult &result) + { + uv_mutex_lock(&m_mutex); + m_queue.push_back(result); + uv_mutex_unlock(&m_mutex); + + uv_async_send(m_async); + } + + +private: + static void onResult(uv_async_t *handle) + { + static_cast(handle->data)->submit(); + } + + + inline void submit() + { + std::list results; + + uv_mutex_lock(&m_mutex); + while (!m_queue.empty()) { + results.push_back(std::move(m_queue.front())); + m_queue.pop_front(); + } + uv_mutex_unlock(&m_mutex); + + for (auto result : results) { + m_listener->onJobResult(result); + } + + results.clear(); + } + + + IJobResultListener *m_listener = nullptr; + std::list m_queue; + uv_async_t *m_async; + uv_mutex_t m_mutex; +}; + + +static JobResultsPrivate *handler = new JobResultsPrivate(); + + +} // namespace xmrig + + + +void xmrig::JobResults::setListener(IJobResultListener *listener) +{ + assert(handler != nullptr && listener != nullptr); + + handler->setListener(listener); +} + + +void xmrig::JobResults::stop() +{ + delete handler; + + handler = nullptr; +} + + +void xmrig::JobResults::submit(const JobResult &result) +{ + assert(handler != nullptr); + + if (handler) { + handler->submit(result); + } +} diff --git a/src/net/JobResults.h b/src/net/JobResults.h new file mode 100644 index 00000000..e7082acb --- /dev/null +++ b/src/net/JobResults.h @@ -0,0 +1,49 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018 Lee Clagett + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_JOBRESULTS_H +#define XMRIG_JOBRESULTS_H + + +namespace xmrig { + + +class IJobResultListener; +class JobResult; + + +class JobResults +{ +public: + static void setListener(IJobResultListener *listener); + static void stop(); + static void submit(const JobResult &result); +}; + + +} // namespace xmrig + + +#endif /* XMRIG_JOBRESULTS_H */ diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 16669f52..c08facb9 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -40,6 +40,7 @@ #include "base/tools/Timer.h" #include "core/config/Config.h" #include "core/Controller.h" +#include "net/JobResults.h" #include "net/Network.h" #include "net/strategies/DonateStrategy.h" #include "rapidjson/document.h" @@ -57,7 +58,7 @@ xmrig::Network::Network(Controller *controller) : m_donate(nullptr), m_timer(nullptr) { - Workers::setListener(this); + JobResults::setListener(this); controller->addListener(this); # ifdef XMRIG_FEATURE_API @@ -77,6 +78,8 @@ xmrig::Network::Network(Controller *controller) : xmrig::Network::~Network() { + JobResults::stop(); + delete m_timer; if (m_donate) { diff --git a/src/interfaces/IJobResultListener.h b/src/net/interfaces/IJobResultListener.h similarity index 100% rename from src/interfaces/IJobResultListener.h rename to src/net/interfaces/IJobResultListener.h diff --git a/src/workers/MultiWorker.cpp b/src/workers/MultiWorker.cpp index dc1292a3..2565e7c4 100644 --- a/src/workers/MultiWorker.cpp +++ b/src/workers/MultiWorker.cpp @@ -28,6 +28,7 @@ #include "crypto/cn/CryptoNight_test.h" +#include "net/JobResults.h" #include "workers/CpuThreadLegacy.h" #include "workers/MultiWorker.h" #include "workers/Workers.h" @@ -170,7 +171,7 @@ void xmrig::MultiWorker::start() for (size_t i = 0; i < N; ++i) { if (*reinterpret_cast(m_hash + (i * 32) + 24) < m_state.job.target()) { - Workers::submit(JobResult(m_state.job.poolId(), m_state.job.id(), m_state.job.clientId(), *nonce(i), m_hash + (i * 32), m_state.job.diff(), m_state.job.algorithm())); + JobResults::submit(JobResult(m_state.job.poolId(), m_state.job.id(), m_state.job.clientId(), *nonce(i), m_hash + (i * 32), m_state.job.diff(), m_state.job.algorithm())); } *nonce(i) += 1; diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 28590d36..88d73a0b 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -32,7 +32,6 @@ #include "base/tools/Handle.h" #include "core/config/Config.h" #include "core/Controller.h" -#include "interfaces/IJobResultListener.h" #include "interfaces/IThread.h" #include "Mem.h" #include "rapidjson/document.h" @@ -45,15 +44,12 @@ bool Workers::m_active = false; bool Workers::m_enabled = true; Hashrate *Workers::m_hashrate = nullptr; -xmrig::IJobResultListener *Workers::m_listener = nullptr; xmrig::Job Workers::m_job; Workers::LaunchStatus Workers::m_status; std::atomic Workers::m_paused; std::atomic Workers::m_sequence; -std::list Workers::m_queue; std::vector Workers::m_workers; uint64_t Workers::m_ticks = 0; -uv_async_t *Workers::m_async = nullptr; uv_mutex_t Workers::m_mutex; uv_rwlock_t Workers::m_rwlock; uv_timer_t *Workers::m_timer = nullptr; @@ -199,9 +195,6 @@ void Workers::start(xmrig::Controller *controller) m_sequence = 1; m_paused = 1; - m_async = new uv_async_t; - uv_async_init(uv_default_loop(), m_async, Workers::onResult); - m_timer = new uv_timer_t; uv_timer_init(uv_default_loop(), m_timer); uv_timer_start(m_timer, Workers::onTick, 500, 500); @@ -221,7 +214,6 @@ void Workers::start(xmrig::Controller *controller) void Workers::stop() { xmrig::Handle::close(m_timer); - xmrig::Handle::close(m_async); m_hashrate->stop(); m_paused = 0; @@ -233,16 +225,6 @@ void Workers::stop() } -void Workers::submit(const xmrig::JobResult &result) -{ - uv_mutex_lock(&m_mutex); - m_queue.push_back(result); - uv_mutex_unlock(&m_mutex); - - uv_async_send(m_async); -} - - #ifdef XMRIG_FEATURE_API void Workers::threadsSummary(rapidjson::Document &doc) { @@ -306,25 +288,6 @@ void Workers::onReady(void *arg) } -void Workers::onResult(uv_async_t *) -{ - std::list results; - - uv_mutex_lock(&m_mutex); - while (!m_queue.empty()) { - results.push_back(std::move(m_queue.front())); - m_queue.pop_front(); - } - uv_mutex_unlock(&m_mutex); - - for (auto result : results) { - m_listener->onJobResult(result); - } - - results.clear(); -} - - void Workers::onTick(uv_timer_t *) { for (ThreadHandle *handle : m_workers) { diff --git a/src/workers/Workers.h b/src/workers/Workers.h index 96191309..39e872b5 100644 --- a/src/workers/Workers.h +++ b/src/workers/Workers.h @@ -47,7 +47,6 @@ class ThreadHandle; namespace xmrig { class Controller; - class IJobResultListener; } @@ -62,7 +61,6 @@ public: static void setJob(const xmrig::Job &job, bool donate); static void start(xmrig::Controller *controller); static void stop(); - static void submit(const xmrig::JobResult &result); static inline bool isEnabled() { return m_enabled; } static inline bool isOutdated(uint64_t sequence) { return m_sequence.load(std::memory_order_relaxed) != sequence; } @@ -70,7 +68,6 @@ public: static inline Hashrate *hashrate() { return m_hashrate; } static inline uint64_t sequence() { return m_sequence.load(std::memory_order_relaxed); } static inline void pause() { m_active = false; m_paused = 1; m_sequence++; } - static inline void setListener(xmrig::IJobResultListener *listener) { m_listener = listener; } # ifdef XMRIG_FEATURE_API static void threadsSummary(rapidjson::Document &doc); @@ -83,7 +80,6 @@ public: private: static void onReady(void *arg); - static void onResult(uv_async_t *handle); static void onTick(uv_timer_t *handle); static void start(IWorker *worker); @@ -109,15 +105,12 @@ private: static bool m_active; static bool m_enabled; static Hashrate *m_hashrate; - static xmrig::IJobResultListener *m_listener; static xmrig::Job m_job; static LaunchStatus m_status; static std::atomic m_paused; static std::atomic m_sequence; - static std::list m_queue; static std::vector m_workers; static uint64_t m_ticks; - static uv_async_t *m_async; static uv_mutex_t m_mutex; static uv_rwlock_t m_rwlock; static uv_timer_t *m_timer; From f42adafee0b73d4112a7e7362399fe850b629a40 Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 10 Jul 2019 01:53:05 +0700 Subject: [PATCH 15/48] Added classes Rx, RxAlgo, RxCache, RxDataset. --- CMakeLists.txt | 30 ++++-- src/base/io/log/Log.h | 6 ++ src/core/config/Config.cpp | 2 +- src/crypto/common/Algorithm.cpp | 7 +- src/crypto/common/VirtualMemory.h | 2 + src/crypto/common/VirtualMemory_win.cpp | 9 -- src/crypto/rx/Rx.cpp | 134 ++++++++++++++++++++++++ src/crypto/rx/Rx.h | 53 ++++++++++ src/crypto/rx/RxAlgo.cpp | 69 ++++++++++++ src/crypto/rx/RxAlgo.h | 56 ++++++++++ src/crypto/rx/RxCache.cpp | 81 ++++++++++++++ src/crypto/rx/RxCache.h | 70 +++++++++++++ src/crypto/rx/RxDataset.cpp | 124 ++++++++++++++++++++++ src/crypto/rx/RxDataset.h | 72 +++++++++++++ src/net/JobResults.cpp | 2 + src/workers/MultiWorker.cpp | 9 +- src/workers/Workers.cpp | 108 +------------------ src/workers/Workers.h | 14 --- 18 files changed, 704 insertions(+), 144 deletions(-) create mode 100644 src/crypto/rx/Rx.cpp create mode 100644 src/crypto/rx/Rx.h create mode 100644 src/crypto/rx/RxAlgo.cpp create mode 100644 src/crypto/rx/RxAlgo.h create mode 100644 src/crypto/rx/RxCache.cpp create mode 100644 src/crypto/rx/RxCache.h create mode 100644 src/crypto/rx/RxDataset.cpp create mode 100644 src/crypto/rx/RxDataset.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 33d3ad70..c315e1cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -171,24 +171,32 @@ if (WITH_RANDOMX) set(SOURCES_CRYPTO "${SOURCES_CRYPTO}" src/crypto/randomx/aes_hash.cpp + src/crypto/randomx/allocator.cpp + src/crypto/randomx/argon2_core.c src/crypto/randomx/argon2_ref.c + src/crypto/randomx/blake2_generator.cpp + src/crypto/randomx/blake2/blake2b.c src/crypto/randomx/bytecode_machine.cpp src/crypto/randomx/dataset.cpp - src/crypto/randomx/soft_aes.cpp - src/crypto/randomx/virtual_memory.cpp - src/crypto/randomx/vm_interpreted.cpp - src/crypto/randomx/allocator.cpp + src/crypto/randomx/instructions_portable.cpp src/crypto/randomx/randomx.cpp + src/crypto/randomx/reciprocal.c + src/crypto/randomx/soft_aes.cpp src/crypto/randomx/superscalar.cpp + src/crypto/randomx/virtual_machine.cpp + src/crypto/randomx/virtual_memory.cpp + src/crypto/randomx/vm_compiled_light.cpp src/crypto/randomx/vm_compiled.cpp src/crypto/randomx/vm_interpreted_light.cpp - src/crypto/randomx/argon2_core.c - src/crypto/randomx/blake2_generator.cpp - src/crypto/randomx/instructions_portable.cpp - src/crypto/randomx/reciprocal.c - src/crypto/randomx/virtual_machine.cpp - src/crypto/randomx/vm_compiled_light.cpp - src/crypto/randomx/blake2/blake2b.c + src/crypto/randomx/vm_interpreted.cpp + src/crypto/rx/Rx.cpp + src/crypto/rx/Rx.h + src/crypto/rx/RxAlgo.cpp + src/crypto/rx/RxAlgo.h + src/crypto/rx/RxCache.cpp + src/crypto/rx/RxCache.h + src/crypto/rx/RxDataset.cpp + src/crypto/rx/RxDataset.h ) if (NOT ARCH_ID) set(ARCH_ID ${CMAKE_HOST_SYSTEM_PROCESSOR}) diff --git a/src/base/io/log/Log.h b/src/base/io/log/Log.h index a14ffded..962d1dba 100644 --- a/src/base/io/log/Log.h +++ b/src/base/io/log/Log.h @@ -81,6 +81,9 @@ private: #define WHITE_S CSI "0;37m" // another name for LT.GRAY #define WHITE_BOLD_S CSI "1;37m" // actually white +#define BLUE_BG_S CSI "44m" +#define BLUE_BG_BOLD_S CSI "44;1m" + //color wrappings #define BLACK(x) BLACK_S x CLEAR #define BLACK_BOLD(x) BLACK_BOLD_S x CLEAR @@ -99,6 +102,9 @@ private: #define WHITE(x) WHITE_S x CLEAR #define WHITE_BOLD(x) WHITE_BOLD_S x CLEAR +#define BLUE_BG(x) BLUE_BG_S x CLEAR +#define BLUE_BG_BOLD(x) BLUE_BG_BOLD_S x CLEAR + #define LOG_EMERG(x, ...) xmrig::Log::print(xmrig::Log::EMERG, x, ##__VA_ARGS__) #define LOG_ALERT(x, ...) xmrig::Log::print(xmrig::Log::ALERT, x, ##__VA_ARGS__) diff --git a/src/core/config/Config.cpp b/src/core/config/Config.cpp index 87abbb91..784e171c 100644 --- a/src/core/config/Config.cpp +++ b/src/core/config/Config.cpp @@ -119,7 +119,7 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const bool xmrig::Config::finalize() { - Algorithm algorithm(Algorithm::CN_0); // FIXME algo + Algorithm algorithm(Algorithm::RX_WOW); // FIXME algo if (!m_threads.cpu.empty()) { m_threads.mode = Advanced; diff --git a/src/crypto/common/Algorithm.cpp b/src/crypto/common/Algorithm.cpp index ab63204f..2c259d32 100644 --- a/src/crypto/common/Algorithm.cpp +++ b/src/crypto/common/Algorithm.cpp @@ -32,6 +32,7 @@ #include "crypto/cn/CnAlgo.h" #include "crypto/common/Algorithm.h" +#include "crypto/rx/RxAlgo.h" #include "rapidjson/document.h" @@ -138,12 +139,12 @@ size_t xmrig::Algorithm::memory() const } # ifdef XMRIG_ALGO_RANDOMX - if (m_id == RX_WOW) { - return 0x100000; + if (f == RANDOM_X) { + return RxAlgo::l3(m_id); } # endif - return 0x200000; + return 0; } diff --git a/src/crypto/common/VirtualMemory.h b/src/crypto/common/VirtualMemory.h index e8acb017..a83c35ed 100644 --- a/src/crypto/common/VirtualMemory.h +++ b/src/crypto/common/VirtualMemory.h @@ -44,6 +44,8 @@ public: static void freeLargePagesMemory(void *p, size_t size); static void protectExecutableMemory(void *p, size_t size); static void unprotectExecutableMemory(void *p, size_t size); + + static inline constexpr size_t align(size_t pos, size_t align = 2097152) { return ((pos - 1) / align + 1) * align; } }; diff --git a/src/crypto/common/VirtualMemory_win.cpp b/src/crypto/common/VirtualMemory_win.cpp index dd6be14f..7f1d6f43 100644 --- a/src/crypto/common/VirtualMemory_win.cpp +++ b/src/crypto/common/VirtualMemory_win.cpp @@ -32,15 +32,6 @@ #include "crypto/common/VirtualMemory.h" -namespace xmrig { - -constexpr size_t align(size_t pos, size_t align) { - return ((pos - 1) / align + 1) * align; -} - -} - - void *xmrig::VirtualMemory::allocateExecutableMemory(size_t size) { return VirtualAlloc(nullptr, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); diff --git a/src/crypto/rx/Rx.cpp b/src/crypto/rx/Rx.cpp new file mode 100644 index 00000000..735169e2 --- /dev/null +++ b/src/crypto/rx/Rx.cpp @@ -0,0 +1,134 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2019 XMR-Stak , + * Copyright 2018 Lee Clagett + * Copyright 2018-2019 tevador + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include +#include + + +#include "backend/cpu/Cpu.h" +#include "base/io/log/Log.h" +#include "base/tools/Buffer.h" +#include "base/tools/Chrono.h" +#include "crypto/rx/Rx.h" +#include "crypto/rx/RxCache.h" +#include "crypto/rx/RxDataset.h" + + +namespace xmrig { + + +class RxPrivate +{ +public: + inline RxPrivate() + { + uv_mutex_init(&mutex); + } + + + inline ~RxPrivate() + { + delete dataset; + uv_mutex_destroy(&mutex); + } + + + inline void lock() { uv_mutex_lock(&mutex); } + inline void unlock() { uv_mutex_unlock(&mutex); } + + + RxDataset *dataset = nullptr; + uint32_t initThreads = std::thread::hardware_concurrency(); + uv_mutex_t mutex; +}; + + +static RxPrivate *d_ptr = new RxPrivate(); +static const char *tag = BLUE_BG(" rx "); + + +} // namespace xmrig + + +xmrig::RxDataset *xmrig::Rx::dataset(const uint8_t *seed, const Algorithm &algorithm, bool hugePages) +{ + d_ptr->lock(); + + if (!d_ptr->dataset) { + const uint64_t ts = Chrono::steadyMSecs(); + + LOG_INFO("%s" MAGENTA_BOLD(" allocate") CYAN_BOLD(" %zu MiB") BLACK_BOLD(" (%zu+%zu) for RandomX dataset & cache"), + tag, + (RxDataset::size() + RxCache::size()) / 1024 / 1024, + RxDataset::size() / 1024 / 1024, + RxCache::size() / 1024 / 1024 + ); + + d_ptr->dataset = new RxDataset(hugePages); + + const auto hugePages = d_ptr->dataset->hugePages(); + const double percent = hugePages.first == 0 ? 0.0 : static_cast(hugePages.first) / hugePages.second * 100.0; + + LOG_INFO("%s" GREEN(" allocate done") " huge pages %s%u/%u %1.0f%%" CLEAR " %sJIT" BLACK_BOLD(" (%" PRIu64 " ms)"), + tag, + (hugePages.first == hugePages.second ? GREEN_BOLD_S : (hugePages.first == 0 ? RED_BOLD_S : YELLOW_BOLD_S)), + hugePages.first, + hugePages.second, + percent, + d_ptr->dataset->cache()->isJIT() ? GREEN_BOLD_S "+" : RED_BOLD_S "-", + Chrono::steadyMSecs() - ts + ); + } + + if (!d_ptr->dataset->isReady(seed, algorithm)) { + const uint64_t ts = Chrono::steadyMSecs(); + + LOG_INFO("%s" MAGENTA_BOLD(" init dataset") " algo " WHITE_BOLD("%s") " threads " WHITE_BOLD("%u") BLACK_BOLD(" seed %s..."), + tag, + algorithm.shortName(), + d_ptr->initThreads, + Buffer::toHex(seed, 8).data() + ); + + d_ptr->dataset->init(seed, algorithm, d_ptr->initThreads); + + LOG_INFO("%s" GREEN(" init done") BLACK_BOLD(" (%" PRIu64 " ms)"), tag, Chrono::steadyMSecs() - ts); + } + + RxDataset *dataset = d_ptr->dataset; + d_ptr->unlock(); + + return dataset; +} + + +void xmrig::Rx::stop() +{ + delete d_ptr; + + d_ptr = nullptr; +} diff --git a/src/crypto/rx/Rx.h b/src/crypto/rx/Rx.h new file mode 100644 index 00000000..c9d068c6 --- /dev/null +++ b/src/crypto/rx/Rx.h @@ -0,0 +1,53 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2019 XMR-Stak , + * Copyright 2018 Lee Clagett + * Copyright 2018-2019 tevador + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_RX_H +#define XMRIG_RX_H + + +#include + + +namespace xmrig +{ + + +class Algorithm; +class RxDataset; + + +class Rx +{ +public: + static RxDataset *dataset(const uint8_t *seed, const Algorithm &algorithm, bool hugePages = true); + static void stop(); +}; + + +} /* namespace xmrig */ + + +#endif /* XMRIG_RX_H */ diff --git a/src/crypto/rx/RxAlgo.cpp b/src/crypto/rx/RxAlgo.cpp new file mode 100644 index 00000000..b0e92e6e --- /dev/null +++ b/src/crypto/rx/RxAlgo.cpp @@ -0,0 +1,69 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2019 XMR-Stak , + * Copyright 2018 Lee Clagett + * Copyright 2018-2019 tevador + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "crypto/randomx/randomx.h" +#include "crypto/rx/RxAlgo.h" + + +xmrig::Algorithm::Id xmrig::RxAlgo::apply(Algorithm::Id algorithm) +{ + switch (algorithm) { + case Algorithm::RX_WOW: + randomx_apply_config(RandomX_WowneroConfig); + break; + + case Algorithm::RX_LOKI: + randomx_apply_config(RandomX_LokiConfig); + break; + + default: + randomx_apply_config(RandomX_MoneroConfig); + break; + } + + return algorithm; +} + + +size_t xmrig::RxAlgo::l3(Algorithm::Id algorithm) +{ + switch (algorithm) { + case Algorithm::RX_0: + return RandomX_MoneroConfig.ScratchpadL3_Size; + + case Algorithm::RX_WOW: + return RandomX_WowneroConfig.ScratchpadL3_Size; + + case Algorithm::RX_LOKI: + return RandomX_LokiConfig.ScratchpadL3_Size; + + default: + break; + } + + return 0; +} diff --git a/src/crypto/rx/RxAlgo.h b/src/crypto/rx/RxAlgo.h new file mode 100644 index 00000000..dd3f0aa7 --- /dev/null +++ b/src/crypto/rx/RxAlgo.h @@ -0,0 +1,56 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2019 XMR-Stak , + * Copyright 2018 Lee Clagett + * Copyright 2018-2019 tevador + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_RX_ALGO_H +#define XMRIG_RX_ALGO_H + + +#include +#include + + +#include "crypto/common/Algorithm.h" + + +struct RandomX_ConfigurationBase; + + +namespace xmrig +{ + + +class RxAlgo +{ +public: + static Algorithm::Id apply(Algorithm::Id algorithm); + static size_t l3(Algorithm::Id algorithm); +}; + + +} /* namespace xmrig */ + + +#endif /* XMRIG_RX_ALGO_H */ diff --git a/src/crypto/rx/RxCache.cpp b/src/crypto/rx/RxCache.cpp new file mode 100644 index 00000000..a5e9efb3 --- /dev/null +++ b/src/crypto/rx/RxCache.cpp @@ -0,0 +1,81 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2019 XMR-Stak , + * Copyright 2018 Lee Clagett + * Copyright 2018-2019 tevador + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "crypto/randomx/randomx.h" +#include "crypto/rx/RxCache.h" + + +static_assert(RANDOMX_FLAG_JIT == 8, "RANDOMX_FLAG_JIT flag mismatch"); +static_assert(RANDOMX_FLAG_LARGE_PAGES == 1, "RANDOMX_FLAG_LARGE_PAGES flag mismatch"); + + + +xmrig::RxCache::RxCache(bool hugePages) : + m_seed() +{ + if (hugePages) { + m_flags = RANDOMX_FLAG_JIT | RANDOMX_FLAG_LARGE_PAGES; + m_cache = randomx_alloc_cache(static_cast(m_flags)); + } + + if (!m_cache) { + m_flags = RANDOMX_FLAG_JIT; + m_cache = randomx_alloc_cache(static_cast(m_flags)); + } + + if (!m_cache) { + m_flags = RANDOMX_FLAG_DEFAULT; + m_cache = randomx_alloc_cache(static_cast(m_flags)); + } +} + + +xmrig::RxCache::~RxCache() +{ + if (m_cache) { + randomx_release_cache(m_cache); + } +} + + +bool xmrig::RxCache::init(const void *seed) +{ + if (isReady(seed)) { + return false; + } + + memcpy(m_seed, seed, sizeof(m_seed)); + randomx_init_cache(m_cache, m_seed, sizeof(m_seed)); + + return true; +} + + +bool xmrig::RxCache::isReady(const void *seed) const +{ + return memcmp(m_seed, seed, sizeof(m_seed)) == 0; +} diff --git a/src/crypto/rx/RxCache.h b/src/crypto/rx/RxCache.h new file mode 100644 index 00000000..893ebf06 --- /dev/null +++ b/src/crypto/rx/RxCache.h @@ -0,0 +1,70 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2019 XMR-Stak , + * Copyright 2018 Lee Clagett + * Copyright 2018-2019 tevador + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_RX_CACHE_H +#define XMRIG_RX_CACHE_H + + +#include + + +#include "crypto/randomx/configuration.h" + + +struct randomx_cache; + + +namespace xmrig +{ + + +class RxCache +{ +public: + RxCache(bool hugePages = true); + ~RxCache(); + + inline bool isHugePages() const { return m_flags & 1; } + inline bool isJIT() const { return m_flags & 8; } + inline const uint8_t *seed() const { return m_seed; } + inline randomx_cache *get() const { return m_cache; } + + bool init(const void *seed); + bool isReady(const void *seed) const; + + static inline constexpr size_t size() { return RANDOMX_CACHE_MAX_SIZE; } + +private: + int m_flags = 0; + randomx_cache *m_cache = nullptr; + uint8_t m_seed[32]; +}; + + +} /* namespace xmrig */ + + +#endif /* XMRIG_RX_CACHE_H */ diff --git a/src/crypto/rx/RxDataset.cpp b/src/crypto/rx/RxDataset.cpp new file mode 100644 index 00000000..5c3b9f37 --- /dev/null +++ b/src/crypto/rx/RxDataset.cpp @@ -0,0 +1,124 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2019 XMR-Stak , + * Copyright 2018 Lee Clagett + * Copyright 2018-2019 tevador + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include + + +#include "crypto/common/VirtualMemory.h" +#include "crypto/randomx/randomx.h" +#include "crypto/rx/RxAlgo.h" +#include "crypto/rx/RxCache.h" +#include "crypto/rx/RxDataset.h" + + +static_assert(RANDOMX_FLAG_LARGE_PAGES == 1, "RANDOMX_FLAG_LARGE_PAGES flag mismatch"); + + +xmrig::RxDataset::RxDataset(bool hugePages) +{ + if (hugePages) { + m_flags = RANDOMX_FLAG_LARGE_PAGES; + m_dataset = randomx_alloc_dataset(static_cast(m_flags)); + } + + if (!m_dataset) { + m_flags = RANDOMX_FLAG_DEFAULT; + m_dataset = randomx_alloc_dataset(static_cast(m_flags)); + } + + m_cache = new RxCache(hugePages); +} + + +xmrig::RxDataset::~RxDataset() +{ + if (m_dataset) { + randomx_release_dataset(m_dataset); + } + + delete m_cache; +} + + +bool xmrig::RxDataset::init(const void *seed, const Algorithm &algorithm, uint32_t numThreads) +{ + if (isReady(seed, algorithm)) { + return false; + } + + if (m_algorithm != algorithm) { + m_algorithm = RxAlgo::apply(algorithm); + } + + cache()->init(seed); + + const uint32_t datasetItemCount = randomx_dataset_item_count(); + + if (numThreads > 1) { + std::vector threads; + threads.reserve(numThreads); + + for (uint32_t i = 0; i < numThreads; ++i) { + const uint32_t a = (datasetItemCount * i) / numThreads; + const uint32_t b = (datasetItemCount * (i + 1)) / numThreads; + threads.emplace_back(randomx_init_dataset, m_dataset, m_cache->get(), a, b - a); + } + + for (uint32_t i = 0; i < numThreads; ++i) { + threads[i].join(); + } + } + else { + randomx_init_dataset(m_dataset, m_cache->get(), 0, datasetItemCount); + } + + return true; +} + + +bool xmrig::RxDataset::isReady(const void *seed, const Algorithm &algorithm) const +{ + return algorithm == m_algorithm && cache()->isReady(seed); +} + + +std::pair xmrig::RxDataset::hugePages() const +{ + constexpr size_t twoMiB = 2u * 1024u * 1024u; + constexpr const size_t total = (VirtualMemory::align(size(), twoMiB) + VirtualMemory::align(RxCache::size(), twoMiB)) / twoMiB; + + size_t count = 0; + if (isHugePages()) { + count += VirtualMemory::align(size(), twoMiB) / twoMiB; + } + + if (m_cache->isHugePages()) { + count += VirtualMemory::align(RxCache::size(), twoMiB) / twoMiB; + } + + return std::pair(count, total); +} diff --git a/src/crypto/rx/RxDataset.h b/src/crypto/rx/RxDataset.h new file mode 100644 index 00000000..7944d52c --- /dev/null +++ b/src/crypto/rx/RxDataset.h @@ -0,0 +1,72 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2019 XMR-Stak , + * Copyright 2018 Lee Clagett + * Copyright 2018-2019 tevador + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_RX_DATASET_H +#define XMRIG_RX_DATASET_H + + +#include "crypto/common/Algorithm.h" +#include "crypto/randomx/configuration.h" + + +struct randomx_dataset; + + +namespace xmrig +{ + + +class RxCache; + + +class RxDataset +{ +public: + RxDataset(bool hugePages = true); + ~RxDataset(); + + inline bool isHugePages() const { return m_flags & 1; } + inline randomx_dataset *get() const { return m_dataset; } + inline RxCache *cache() const { return m_cache; } + + bool init(const void *seed, const Algorithm &algorithm, uint32_t numThreads); + bool isReady(const void *seed, const Algorithm &algorithm) const; + std::pair hugePages() const; + + static inline constexpr size_t size() { return RANDOMX_DATASET_MAX_SIZE; } + +private: + Algorithm m_algorithm; + int m_flags = 0; + randomx_dataset *m_dataset = nullptr; + RxCache *m_cache = nullptr; +}; + + +} /* namespace xmrig */ + + +#endif /* XMRIG_RX_DATASET_H */ diff --git a/src/net/JobResults.cpp b/src/net/JobResults.cpp index 8c65b5e4..bf0b5e86 100644 --- a/src/net/JobResults.cpp +++ b/src/net/JobResults.cpp @@ -54,6 +54,8 @@ public: inline ~JobResultsPrivate() { Handle::close(m_async); + + uv_mutex_destroy(&m_mutex); } diff --git a/src/workers/MultiWorker.cpp b/src/workers/MultiWorker.cpp index 2565e7c4..059a7171 100644 --- a/src/workers/MultiWorker.cpp +++ b/src/workers/MultiWorker.cpp @@ -28,6 +28,8 @@ #include "crypto/cn/CryptoNight_test.h" +#include "crypto/rx/Rx.h" +#include "crypto/rx/RxDataset.h" #include "net/JobResults.h" #include "workers/CpuThreadLegacy.h" #include "workers/MultiWorker.h" @@ -67,9 +69,11 @@ void xmrig::MultiWorker::allocateRandomX_VM() flags |= RANDOMX_FLAG_HARD_AES; } - m_rx_vm = randomx_create_vm(static_cast(flags), nullptr, Workers::getDataset()); + RxDataset *dataset = Rx::dataset(m_state.job.seedHash(), m_state.job.algorithm()); + + m_rx_vm = randomx_create_vm(static_cast(flags), nullptr, dataset->get()); if (!m_rx_vm) { - m_rx_vm = randomx_create_vm(static_cast(flags - RANDOMX_FLAG_LARGE_PAGES), nullptr, Workers::getDataset()); + m_rx_vm = randomx_create_vm(static_cast(flags - RANDOMX_FLAG_LARGE_PAGES), nullptr, dataset->get()); } } } @@ -160,7 +164,6 @@ void xmrig::MultiWorker::start() # ifdef XMRIG_ALGO_RANDOMX if (m_state.job.algorithm().family() == Algorithm::RANDOM_X) { allocateRandomX_VM(); - Workers::updateDataset(m_state.job.seedHash(), m_totalWays, m_state.job.algorithm()); randomx_calculate_hash(m_rx_vm, m_state.blob, m_state.job.size(), m_hash); } else diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 88d73a0b..58cccd9e 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -29,9 +29,13 @@ #include "api/Api.h" #include "base/io/log/Log.h" +#include "base/tools/Chrono.h" #include "base/tools/Handle.h" #include "core/config/Config.h" #include "core/Controller.h" +#include "crypto/rx/RxAlgo.h" +#include "crypto/rx/RxCache.h" +#include "crypto/rx/RxDataset.h" #include "interfaces/IThread.h" #include "Mem.h" #include "rapidjson/document.h" @@ -55,15 +59,6 @@ uv_rwlock_t Workers::m_rwlock; uv_timer_t *Workers::m_timer = nullptr; xmrig::Controller *Workers::m_controller = nullptr; -#ifdef XMRIG_ALGO_RANDOMX -uv_rwlock_t Workers::m_rx_dataset_lock; -randomx_cache *Workers::m_rx_cache = nullptr; -randomx_dataset *Workers::m_rx_dataset = nullptr; -uint8_t Workers::m_rx_seed_hash[32] = {}; -xmrig::Algorithm Workers::m_rx_algo; -std::atomic Workers::m_rx_dataset_init_thread_counter = {}; -#endif - xmrig::Job Workers::job() { @@ -176,7 +171,7 @@ void Workers::start(xmrig::Controller *controller) m_controller = controller; const std::vector &threads = controller->config()->threads(); - m_status.algo = xmrig::Algorithm::CN_0; // FIXME algo + m_status.algo = xmrig::Algorithm::RX_WOW; // FIXME algo m_status.threads = threads.size(); for (const xmrig::IThread *thread : threads) { @@ -188,10 +183,6 @@ void Workers::start(xmrig::Controller *controller) uv_mutex_init(&m_mutex); uv_rwlock_init(&m_rwlock); -# ifdef XMRIG_ALGO_RANDOMX - uv_rwlock_init(&m_rx_dataset_lock); -# endif - m_sequence = 1; m_paused = 1; @@ -335,92 +326,3 @@ void Workers::start(IWorker *worker) worker->start(); } - - -#ifdef XMRIG_ALGO_RANDOMX -void Workers::updateDataset(const uint8_t* seed_hash, const uint32_t num_threads, const xmrig::Algorithm &algorithm) -{ - // Check if we need to update cache and dataset - if ((memcmp(m_rx_seed_hash, seed_hash, sizeof(m_rx_seed_hash)) == 0) && (m_rx_algo == algorithm)) - return; - - const uint32_t thread_id = m_rx_dataset_init_thread_counter++; - LOG_DEBUG("Thread %u started updating RandomX dataset", thread_id); - - // Wait for all threads to get here - do { - if (m_sequence.load(std::memory_order_relaxed) == 0) { - // Exit immediately if workers were stopped - return; - } - std::this_thread::yield(); - } while (m_rx_dataset_init_thread_counter.load() != num_threads); - - // One of the threads updates cache - uv_rwlock_wrlock(&m_rx_dataset_lock); - - if (m_rx_algo != algorithm) { - switch (algorithm) { - case xmrig::Algorithm::RX_WOW: - randomx_apply_config(RandomX_WowneroConfig); - break; - - case xmrig::Algorithm::RX_LOKI: - randomx_apply_config(RandomX_LokiConfig); - break; - - default: - randomx_apply_config(RandomX_MoneroConfig); - break; - } - - m_rx_algo = algorithm; - } - - if (memcmp(m_rx_seed_hash, seed_hash, sizeof(m_rx_seed_hash)) != 0) { - memcpy(m_rx_seed_hash, seed_hash, sizeof(m_rx_seed_hash)); - randomx_init_cache(m_rx_cache, m_rx_seed_hash, sizeof(m_rx_seed_hash)); - } - - uv_rwlock_wrunlock(&m_rx_dataset_lock); - - // All threads update dataset - const uint32_t a = (randomx_dataset_item_count() * thread_id) / num_threads; - const uint32_t b = (randomx_dataset_item_count() * (thread_id + 1)) / num_threads; - randomx_init_dataset(m_rx_dataset, m_rx_cache, a, b - a); - - LOG_DEBUG("Thread %u finished updating RandomX dataset", thread_id); - - // Wait for all threads to complete - --m_rx_dataset_init_thread_counter; - do { - if (m_sequence.load(std::memory_order_relaxed) == 0) { - // Exit immediately if workers were stopped - return; - } - std::this_thread::yield(); - } while (m_rx_dataset_init_thread_counter.load() != 0); -} - -randomx_dataset* Workers::getDataset() -{ - if (m_rx_dataset) - return m_rx_dataset; - - uv_rwlock_wrlock(&m_rx_dataset_lock); - if (!m_rx_dataset) { - randomx_dataset* dataset = randomx_alloc_dataset(RANDOMX_FLAG_LARGE_PAGES); - if (!dataset) { - dataset = randomx_alloc_dataset(RANDOMX_FLAG_DEFAULT); - } - m_rx_cache = randomx_alloc_cache(static_cast(RANDOMX_FLAG_JIT | RANDOMX_FLAG_LARGE_PAGES)); - if (!m_rx_cache) { - m_rx_cache = randomx_alloc_cache(RANDOMX_FLAG_JIT); - } - m_rx_dataset = dataset; - } - uv_rwlock_wrunlock(&m_rx_dataset_lock); - - return m_rx_dataset; -} -#endif diff --git a/src/workers/Workers.h b/src/workers/Workers.h index 39e872b5..8619f973 100644 --- a/src/workers/Workers.h +++ b/src/workers/Workers.h @@ -73,11 +73,6 @@ public: static void threadsSummary(rapidjson::Document &doc); # endif -# ifdef XMRIG_ALGO_RANDOMX - static void updateDataset(const uint8_t* seed_hash, uint32_t num_threads, const xmrig::Algorithm &algorithm); - static randomx_dataset* getDataset(); -# endif - private: static void onReady(void *arg); static void onTick(uv_timer_t *handle); @@ -115,15 +110,6 @@ private: static uv_rwlock_t m_rwlock; static uv_timer_t *m_timer; static xmrig::Controller *m_controller; - -# ifdef XMRIG_ALGO_RANDOMX - static uv_rwlock_t m_rx_dataset_lock; - static randomx_cache *m_rx_cache; - static randomx_dataset *m_rx_dataset; - static uint8_t m_rx_seed_hash[32]; - static xmrig::Algorithm m_rx_algo; - static std::atomic m_rx_dataset_init_thread_counter; -# endif }; From 3bebf778da034d974718b0258ea7b74c3534d649 Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 10 Jul 2019 02:28:45 +0700 Subject: [PATCH 16/48] Fixed build. --- src/api/v1/ApiRouter.cpp | 4 ++-- src/backend/cpu/platform/AdvancedCpuInfo.cpp | 1 + src/backend/cpu/platform/BasicCpuInfo.cpp | 2 +- src/backend/cpu/platform/BasicCpuInfo.h | 2 +- src/backend/cpu/platform/BasicCpuInfo_arm.cpp | 8 +++++++- 5 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/api/v1/ApiRouter.cpp b/src/api/v1/ApiRouter.cpp index 0f754e17..ff1ef404 100644 --- a/src/api/v1/ApiRouter.cpp +++ b/src/api/v1/ApiRouter.cpp @@ -22,7 +22,7 @@ * along with this program. If not, see . */ -#include +#include #include #include @@ -44,7 +44,7 @@ static inline rapidjson::Value normalize(double d) { using namespace rapidjson; - if (!isnormal(d)) { + if (!std::isnormal(d)) { return Value(kNullType); } diff --git a/src/backend/cpu/platform/AdvancedCpuInfo.cpp b/src/backend/cpu/platform/AdvancedCpuInfo.cpp index b5b2fe91..f3c4ed23 100644 --- a/src/backend/cpu/platform/AdvancedCpuInfo.cpp +++ b/src/backend/cpu/platform/AdvancedCpuInfo.cpp @@ -22,6 +22,7 @@ * along with this program. If not, see . */ +#include #include #include #include diff --git a/src/backend/cpu/platform/BasicCpuInfo.cpp b/src/backend/cpu/platform/BasicCpuInfo.cpp index 26237468..369392b6 100644 --- a/src/backend/cpu/platform/BasicCpuInfo.cpp +++ b/src/backend/cpu/platform/BasicCpuInfo.cpp @@ -124,8 +124,8 @@ static inline bool has_ossave() xmrig::BasicCpuInfo::BasicCpuInfo() : m_assembly(Assembly::NONE), - m_brand(), m_aes(has_aes_ni()), + m_brand(), m_avx2(has_avx2() && has_ossave()), m_threads(std::thread::hardware_concurrency()) { diff --git a/src/backend/cpu/platform/BasicCpuInfo.h b/src/backend/cpu/platform/BasicCpuInfo.h index 12c275dd..886d59c3 100644 --- a/src/backend/cpu/platform/BasicCpuInfo.h +++ b/src/backend/cpu/platform/BasicCpuInfo.h @@ -55,8 +55,8 @@ protected: private: Assembly m_assembly; + bool m_aes; char m_brand[64 + 6]; - const bool m_aes; const bool m_avx2; const size_t m_threads; }; diff --git a/src/backend/cpu/platform/BasicCpuInfo_arm.cpp b/src/backend/cpu/platform/BasicCpuInfo_arm.cpp index 49e300e4..6702f6f0 100644 --- a/src/backend/cpu/platform/BasicCpuInfo_arm.cpp +++ b/src/backend/cpu/platform/BasicCpuInfo_arm.cpp @@ -37,8 +37,8 @@ xmrig::BasicCpuInfo::BasicCpuInfo() : m_aes(false), - m_avx2(false), m_brand(), + m_avx2(false), m_threads(std::thread::hardware_concurrency()) { # ifdef XMRIG_ARMv8 @@ -61,3 +61,9 @@ size_t xmrig::BasicCpuInfo::optimalThreadsCount(size_t memSize, int maxCpuUsage) { return threads(); } + + +xmrig::CpuThreads xmrig::BasicCpuInfo::threads(const Algorithm &algorithm) const +{ + return CpuThreads(threads()); +} From 270d3ba6a2bed53d132a4d8960ba867d35776137 Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 10 Jul 2019 10:14:33 +0700 Subject: [PATCH 17/48] Added class RxVm. --- CMakeLists.txt | 2 ++ src/crypto/rx/Rx.cpp | 48 ++++++++++++++++---------- src/crypto/rx/RxCache.h | 2 +- src/crypto/rx/RxDataset.cpp | 4 +++ src/crypto/rx/RxVm.cpp | 68 +++++++++++++++++++++++++++++++++++++ src/crypto/rx/RxVm.h | 61 +++++++++++++++++++++++++++++++++ src/workers/MultiWorker.cpp | 21 +++--------- src/workers/MultiWorker.h | 10 +++--- 8 files changed, 176 insertions(+), 40 deletions(-) create mode 100644 src/crypto/rx/RxVm.cpp create mode 100644 src/crypto/rx/RxVm.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c315e1cf..9094d381 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -197,6 +197,8 @@ if (WITH_RANDOMX) src/crypto/rx/RxCache.h src/crypto/rx/RxDataset.cpp src/crypto/rx/RxDataset.h + src/crypto/rx/RxVm.cpp + src/crypto/rx/RxVm.h ) if (NOT ARCH_ID) set(ARCH_ID ${CMAKE_HOST_SYSTEM_PROCESSOR}) diff --git a/src/crypto/rx/Rx.cpp b/src/crypto/rx/Rx.cpp index 735169e2..630dd45a 100644 --- a/src/crypto/rx/Rx.cpp +++ b/src/crypto/rx/Rx.cpp @@ -90,29 +90,43 @@ xmrig::RxDataset *xmrig::Rx::dataset(const uint8_t *seed, const Algorithm &algor d_ptr->dataset = new RxDataset(hugePages); - const auto hugePages = d_ptr->dataset->hugePages(); - const double percent = hugePages.first == 0 ? 0.0 : static_cast(hugePages.first) / hugePages.second * 100.0; + if (d_ptr->dataset->get() != nullptr) { + const auto hugePages = d_ptr->dataset->hugePages(); + const double percent = hugePages.first == 0 ? 0.0 : static_cast(hugePages.first) / hugePages.second * 100.0; - LOG_INFO("%s" GREEN(" allocate done") " huge pages %s%u/%u %1.0f%%" CLEAR " %sJIT" BLACK_BOLD(" (%" PRIu64 " ms)"), - tag, - (hugePages.first == hugePages.second ? GREEN_BOLD_S : (hugePages.first == 0 ? RED_BOLD_S : YELLOW_BOLD_S)), - hugePages.first, - hugePages.second, - percent, - d_ptr->dataset->cache()->isJIT() ? GREEN_BOLD_S "+" : RED_BOLD_S "-", - Chrono::steadyMSecs() - ts - ); + LOG_INFO("%s" GREEN(" allocate done") " huge pages %s%u/%u %1.0f%%" CLEAR " %sJIT" BLACK_BOLD(" (%" PRIu64 " ms)"), + tag, + (hugePages.first == hugePages.second ? GREEN_BOLD_S : (hugePages.first == 0 ? RED_BOLD_S : YELLOW_BOLD_S)), + hugePages.first, + hugePages.second, + percent, + d_ptr->dataset->cache()->isJIT() ? GREEN_BOLD_S "+" : RED_BOLD_S "-", + Chrono::steadyMSecs() - ts + ); + } + else { + LOG_WARN(CLEAR "%s" YELLOW_BOLD_S " failed to allocate RandomX dataset, switching to slow mode", tag); + } } if (!d_ptr->dataset->isReady(seed, algorithm)) { const uint64_t ts = Chrono::steadyMSecs(); - LOG_INFO("%s" MAGENTA_BOLD(" init dataset") " algo " WHITE_BOLD("%s") " threads " WHITE_BOLD("%u") BLACK_BOLD(" seed %s..."), - tag, - algorithm.shortName(), - d_ptr->initThreads, - Buffer::toHex(seed, 8).data() - ); + if (d_ptr->dataset->get() != nullptr) { + LOG_INFO("%s" MAGENTA_BOLD(" init dataset") " algo " WHITE_BOLD("%s") " threads " WHITE_BOLD("%u") BLACK_BOLD(" seed %s..."), + tag, + algorithm.shortName(), + d_ptr->initThreads, + Buffer::toHex(seed, 8).data() + ); + } + else { + LOG_INFO("%s" MAGENTA_BOLD(" init cache") " algo " WHITE_BOLD("%s") BLACK_BOLD(" seed %s..."), + tag, + algorithm.shortName(), + Buffer::toHex(seed, 8).data() + ); + } d_ptr->dataset->init(seed, algorithm, d_ptr->initThreads); diff --git a/src/crypto/rx/RxCache.h b/src/crypto/rx/RxCache.h index 893ebf06..c48924a1 100644 --- a/src/crypto/rx/RxCache.h +++ b/src/crypto/rx/RxCache.h @@ -58,7 +58,7 @@ public: static inline constexpr size_t size() { return RANDOMX_CACHE_MAX_SIZE; } private: - int m_flags = 0; + int m_flags = 0; randomx_cache *m_cache = nullptr; uint8_t m_seed[32]; }; diff --git a/src/crypto/rx/RxDataset.cpp b/src/crypto/rx/RxDataset.cpp index 5c3b9f37..603cf578 100644 --- a/src/crypto/rx/RxDataset.cpp +++ b/src/crypto/rx/RxDataset.cpp @@ -76,6 +76,10 @@ bool xmrig::RxDataset::init(const void *seed, const Algorithm &algorithm, uint32 cache()->init(seed); + if (!get()) { + return true; + } + const uint32_t datasetItemCount = randomx_dataset_item_count(); if (numThreads > 1) { diff --git a/src/crypto/rx/RxVm.cpp b/src/crypto/rx/RxVm.cpp new file mode 100644 index 00000000..3ee0f859 --- /dev/null +++ b/src/crypto/rx/RxVm.cpp @@ -0,0 +1,68 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2019 XMR-Stak , + * Copyright 2018 Lee Clagett + * Copyright 2018-2019 tevador + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "crypto/randomx/randomx.h" +#include "crypto/rx/RxCache.h" +#include "crypto/rx/RxDataset.h" +#include "crypto/rx/RxVm.h" + + +xmrig::RxVm::RxVm(RxDataset *dataset, bool hugePages, bool softAes) +{ + m_flags = RANDOMX_FLAG_JIT; + if (hugePages) { + m_flags |= RANDOMX_FLAG_LARGE_PAGES; + } + + if (!softAes) { + m_flags |= RANDOMX_FLAG_HARD_AES; + } + + if (dataset->get()) { + m_flags |= RANDOMX_FLAG_FULL_MEM; + } + + m_vm = randomx_create_vm(static_cast(m_flags), dataset->cache()->get(), dataset->get()); + + if (!m_vm) { + m_flags &= ~RANDOMX_FLAG_LARGE_PAGES; + m_vm = randomx_create_vm(static_cast(m_flags), dataset->cache()->get(), dataset->get()); + } + + if (!m_vm) { + m_flags &= ~RANDOMX_FLAG_JIT; + m_vm = randomx_create_vm(static_cast(m_flags), dataset->cache()->get(), dataset->get()); + } +} + + +xmrig::RxVm::~RxVm() +{ + if (m_vm) { + randomx_destroy_vm(m_vm); + } +} diff --git a/src/crypto/rx/RxVm.h b/src/crypto/rx/RxVm.h new file mode 100644 index 00000000..90af8187 --- /dev/null +++ b/src/crypto/rx/RxVm.h @@ -0,0 +1,61 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2019 XMR-Stak , + * Copyright 2018 Lee Clagett + * Copyright 2018-2019 tevador + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_RX_VM_H +#define XMRIG_RX_VM_H + + +#include + + +struct randomx_vm; + + +namespace xmrig +{ + + +class RxDataset; + + +class RxVm +{ +public: + RxVm(RxDataset *dataset, bool hugePages, bool softAes); + ~RxVm(); + + inline randomx_vm *get() const { return m_vm; } + +private: + int m_flags = 0; + randomx_vm *m_vm = nullptr; +}; + + +} /* namespace xmrig */ + + +#endif /* XMRIG_RX_CACHE_H */ diff --git a/src/workers/MultiWorker.cpp b/src/workers/MultiWorker.cpp index 059a7171..684d92f9 100644 --- a/src/workers/MultiWorker.cpp +++ b/src/workers/MultiWorker.cpp @@ -29,7 +29,7 @@ #include "crypto/cn/CryptoNight_test.h" #include "crypto/rx/Rx.h" -#include "crypto/rx/RxDataset.h" +#include "crypto/rx/RxVm.h" #include "net/JobResults.h" #include "workers/CpuThreadLegacy.h" #include "workers/MultiWorker.h" @@ -52,9 +52,7 @@ xmrig::MultiWorker::~MultiWorker() Mem::release(m_ctx, N, m_memory); # ifdef XMRIG_ALGO_RANDOMX - if (m_rx_vm) { - randomx_destroy_vm(m_rx_vm); - } + delete m_vm; # endif } @@ -63,18 +61,9 @@ xmrig::MultiWorker::~MultiWorker() template void xmrig::MultiWorker::allocateRandomX_VM() { - if (!m_rx_vm) { - int flags = RANDOMX_FLAG_LARGE_PAGES | RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_JIT; - if (!m_thread->isSoftAES()) { - flags |= RANDOMX_FLAG_HARD_AES; - } - + if (!m_vm) { RxDataset *dataset = Rx::dataset(m_state.job.seedHash(), m_state.job.algorithm()); - - m_rx_vm = randomx_create_vm(static_cast(flags), nullptr, dataset->get()); - if (!m_rx_vm) { - m_rx_vm = randomx_create_vm(static_cast(flags - RANDOMX_FLAG_LARGE_PAGES), nullptr, dataset->get()); - } + m_vm = new RxVm(dataset, true, m_thread->isSoftAES()); } } #endif @@ -164,7 +153,7 @@ void xmrig::MultiWorker::start() # ifdef XMRIG_ALGO_RANDOMX if (m_state.job.algorithm().family() == Algorithm::RANDOM_X) { allocateRandomX_VM(); - randomx_calculate_hash(m_rx_vm, m_state.blob, m_state.job.size(), m_hash); + randomx_calculate_hash(m_vm->get(), m_state.blob, m_state.job.size(), m_hash); } else # endif diff --git a/src/workers/MultiWorker.h b/src/workers/MultiWorker.h index d695e030..0502ad84 100644 --- a/src/workers/MultiWorker.h +++ b/src/workers/MultiWorker.h @@ -27,11 +27,6 @@ #define XMRIG_MULTIWORKER_H -#ifdef XMRIG_ALGO_RANDOMX -# include -#endif - - #include "base/net/stratum/Job.h" #include "Mem.h" #include "net/JobResult.h" @@ -41,6 +36,9 @@ namespace xmrig { +class RxVm; + + template class MultiWorker : public Worker { @@ -81,7 +79,7 @@ private: uint8_t m_hash[N * 32]; # ifdef XMRIG_ALGO_RANDOMX - randomx_vm *m_rx_vm = nullptr; + RxVm *m_vm = nullptr; # endif }; From 8e2219b7c481d8cd692b1103d317254e03626bf7 Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 10 Jul 2019 10:26:10 +0700 Subject: [PATCH 18/48] Fixed RandomX VM creation in some cases. --- src/crypto/rx/RxVm.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/crypto/rx/RxVm.cpp b/src/crypto/rx/RxVm.cpp index 3ee0f859..b02f708e 100644 --- a/src/crypto/rx/RxVm.cpp +++ b/src/crypto/rx/RxVm.cpp @@ -33,7 +33,6 @@ xmrig::RxVm::RxVm(RxDataset *dataset, bool hugePages, bool softAes) { - m_flags = RANDOMX_FLAG_JIT; if (hugePages) { m_flags |= RANDOMX_FLAG_LARGE_PAGES; } @@ -46,6 +45,10 @@ xmrig::RxVm::RxVm(RxDataset *dataset, bool hugePages, bool softAes) m_flags |= RANDOMX_FLAG_FULL_MEM; } + if (dataset->cache()->isJIT()) { + m_flags |= RANDOMX_FLAG_JIT; + } + m_vm = randomx_create_vm(static_cast(m_flags), dataset->cache()->get(), dataset->get()); if (!m_vm) { @@ -54,7 +57,7 @@ xmrig::RxVm::RxVm(RxDataset *dataset, bool hugePages, bool softAes) } if (!m_vm) { - m_flags &= ~RANDOMX_FLAG_JIT; + m_flags &= ~RANDOMX_FLAG_HARD_AES; m_vm = randomx_create_vm(static_cast(m_flags), dataset->cache()->get(), dataset->get()); } } From 6f27037f0759133aea66a366093744e983b49d9b Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 11 Jul 2019 16:15:51 +0700 Subject: [PATCH 19/48] Added new nonce allocation method for dynamic/variable threads. --- CMakeLists.txt | 3 + src/core/WorkerJob.h | 143 ++++++++++++++++++++++++++++++++++++ src/crypto/common/Nonce.cpp | 83 +++++++++++++++++++++ src/crypto/common/Nonce.h | 57 ++++++++++++++ src/workers/MultiWorker.cpp | 88 ++++++---------------- src/workers/MultiWorker.h | 19 +---- src/workers/Worker.cpp | 5 +- src/workers/Worker.h | 5 +- src/workers/Workers.cpp | 21 ++++-- src/workers/Workers.h | 7 +- 10 files changed, 336 insertions(+), 95 deletions(-) create mode 100644 src/core/WorkerJob.h create mode 100644 src/crypto/common/Nonce.cpp create mode 100644 src/crypto/common/Nonce.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 9094d381..13f787f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,6 +35,7 @@ set(HEADERS src/core/config/ConfigTransform.h src/core/config/usage.h src/core/Controller.h + src/core/WorkerJob.h src/interfaces/IThread.h src/interfaces/IWorker.h src/Mem.h @@ -71,6 +72,7 @@ set(HEADERS_CRYPTO src/crypto/cn/soft_aes.h src/crypto/common/Algorithm.h src/crypto/common/keccak.h + src/crypto/common/Nonce.h src/crypto/common/portable/mm_malloc.h src/crypto/common/VirtualMemory.h ) @@ -113,6 +115,7 @@ set(SOURCES_CRYPTO src/crypto/cn/CnHash.cpp src/crypto/common/Algorithm.cpp src/crypto/common/keccak.cpp + src/crypto/common/Nonce.cpp ) if (WIN32) diff --git a/src/core/WorkerJob.h b/src/core/WorkerJob.h new file mode 100644 index 00000000..004c5533 --- /dev/null +++ b/src/core/WorkerJob.h @@ -0,0 +1,143 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_WORKERJOB_H +#define XMRIG_WORKERJOB_H + + +#include +#include + + +#include "base/net/stratum/Job.h" +#include "crypto/common/Nonce.h" + + +namespace xmrig { + + +template +class WorkerJob +{ +public: + inline const Job ¤tJob() const { return m_jobs[index()]; } + inline uint32_t *nonce(size_t i = 0) { return reinterpret_cast(blob() + (i * currentJob().size()) + 39); } + inline uint64_t sequence() const { return m_sequence; } + inline uint8_t *blob() { return m_blobs[index()]; } + inline uint8_t index() const { return m_index; } + + + inline void add(const Job &job, uint64_t sequence, uint32_t reserveCount) + { + m_sequence = sequence; + + if (currentJob() == job) { + return; + } + + if (index() == 1 && job.poolId() >= 0 && job == m_jobs[0]) { + return; + } + + save(job, reserveCount); + } + + + inline void nextRound(uint32_t reserveCount) + { + m_rounds[index()]++; + + if ((m_rounds[index()] % reserveCount) == 0) { + for (size_t i = 0; i < N; ++i) { + *nonce(i) = Nonce::next(index(), *nonce(i), reserveCount, currentJob().isNicehash()); + } + } + else { + for (size_t i = 0; i < N; ++i) { + *nonce(i) += 1; + } + } + } + + +private: + inline void save(const Job &job, uint32_t reserveCount) + { + m_index = job.poolId() == -1 ? 1 : 0; + const size_t size = job.size(); + m_jobs[index()] = job; + m_rounds[index()] = 0; + + for (size_t i = 0; i < N; ++i) { + memcpy(m_blobs[index()] + (i * size), job.blob(), size); + *nonce(i) = Nonce::next(index(), *nonce(i), reserveCount, job.isNicehash()); + } + } + + + alignas(16) uint8_t m_blobs[2][Job::kMaxBlobSize * N]; + Job m_jobs[2]; + uint32_t m_rounds[2] = { 0, 0 }; + uint64_t m_sequence = 0; + uint8_t m_index = 0; +}; + + +template<> +inline uint32_t *xmrig::WorkerJob<1>::nonce(size_t) +{ + return reinterpret_cast(blob() + 39); +} + + +template<> +inline void xmrig::WorkerJob<1>::nextRound(uint32_t reserveCount) +{ + m_rounds[index()]++; + + if ((m_rounds[index()] % reserveCount) == 0) { + *nonce() = Nonce::next(index(), *nonce(), reserveCount, currentJob().isNicehash()); + } + else { + *nonce() += 1; + } +} + + +template<> +inline void xmrig::WorkerJob<1>::save(const Job &job, uint32_t reserveCount) +{ + m_index = job.poolId() == -1 ? 1 : 0; + m_jobs[index()] = job; + m_rounds[index()] = 0; + + memcpy(blob(), job.blob(), job.size()); + *nonce() = Nonce::next(index(), *nonce(), reserveCount, currentJob().isNicehash()); +} + + +} // namespace xmrig + + +#endif /* XMRIG_WORKERJOB_H */ diff --git a/src/crypto/common/Nonce.cpp b/src/crypto/common/Nonce.cpp new file mode 100644 index 00000000..6670308a --- /dev/null +++ b/src/crypto/common/Nonce.cpp @@ -0,0 +1,83 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include + + +#include "crypto/common/Nonce.h" + + +namespace xmrig { + + +std::atomic Nonce::m_sequence; +uint32_t Nonce::m_nonces[2] = { 0, 0 }; + + +static uv_mutex_t mutex; +static Nonce nonce; + + +} // namespace xmrig + + +xmrig::Nonce::Nonce() +{ + m_sequence = 1; + + uv_mutex_init(&mutex); +} + + +uint32_t xmrig::Nonce::next(uint8_t index, uint32_t nonce, uint32_t reserveCount, bool nicehash) +{ + uint32_t next; + + uv_mutex_lock(&mutex); + + if (nicehash) { + next = (nonce & 0xFF000000) | m_nonces[index]; + } + else { + next = m_nonces[index]; + } + + m_nonces[index] += reserveCount; + + uv_mutex_unlock(&mutex); + + return next; +} + + +void xmrig::Nonce::reset(uint8_t index) +{ + uv_mutex_lock(&mutex); + + m_nonces[index] = 0; + m_sequence++; + + uv_mutex_unlock(&mutex); +} diff --git a/src/crypto/common/Nonce.h b/src/crypto/common/Nonce.h new file mode 100644 index 00000000..ea843bc9 --- /dev/null +++ b/src/crypto/common/Nonce.h @@ -0,0 +1,57 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_NONCE_H +#define XMRIG_NONCE_H + + +#include + + +namespace xmrig { + + +class Nonce +{ +public: + Nonce(); + + static inline bool isOutdated(uint64_t sequence) { return m_sequence.load(std::memory_order_relaxed) != sequence; } + static inline uint64_t sequence() { return m_sequence.load(std::memory_order_relaxed); } + static inline void stop() { m_sequence = 0; } + static inline void touch() { m_sequence++; } + + static uint32_t next(uint8_t index, uint32_t nonce, uint32_t reserveCount, bool nicehash); + static void reset(uint8_t index); + +private: + static uint32_t m_nonces[2]; + static std::atomic m_sequence; +}; + + +} // namespace xmrig + + +#endif /* XMRIG_NONCE_H */ diff --git a/src/workers/MultiWorker.cpp b/src/workers/MultiWorker.cpp index 684d92f9..daae9230 100644 --- a/src/workers/MultiWorker.cpp +++ b/src/workers/MultiWorker.cpp @@ -28,6 +28,7 @@ #include "crypto/cn/CryptoNight_test.h" +#include "crypto/common/Nonce.h" #include "crypto/rx/Rx.h" #include "crypto/rx/RxVm.h" #include "net/JobResults.h" @@ -36,6 +37,13 @@ #include "workers/Workers.h" +namespace xmrig { + +static constexpr uint32_t kReserveCount = 4096; + +} // namespace xmrig + + template xmrig::MultiWorker::MultiWorker(ThreadHandle *handle) : Worker(handle) @@ -62,7 +70,7 @@ template void xmrig::MultiWorker::allocateRandomX_VM() { if (!m_vm) { - RxDataset *dataset = Rx::dataset(m_state.job.seedHash(), m_state.job.algorithm()); + RxDataset *dataset = Rx::dataset(m_job.currentJob().seedHash(), m_job.currentJob().algorithm()); m_vm = new RxVm(dataset, true, m_thread->isSoftAES()); } } @@ -131,44 +139,45 @@ bool xmrig::MultiWorker::selfTest() template void xmrig::MultiWorker::start() { - while (Workers::sequence() > 0) { + while (Nonce::sequence() > 0) { if (Workers::isPaused()) { do { std::this_thread::sleep_for(std::chrono::milliseconds(200)); } while (Workers::isPaused()); - if (Workers::sequence() == 0) { + if (Nonce::sequence() == 0) { break; } consumeJob(); } - while (!Workers::isOutdated(m_sequence)) { + while (!Nonce::isOutdated(m_job.sequence())) { if ((m_count & 0x7) == 0) { storeStats(); } + const Job &job = m_job.currentJob(); + # ifdef XMRIG_ALGO_RANDOMX - if (m_state.job.algorithm().family() == Algorithm::RANDOM_X) { + if (job.algorithm().family() == Algorithm::RANDOM_X) { allocateRandomX_VM(); - randomx_calculate_hash(m_vm->get(), m_state.blob, m_state.job.size(), m_hash); + randomx_calculate_hash(m_vm->get(), m_job.blob(), job.size(), m_hash); } else # endif { - m_thread->fn(m_state.job.algorithm())(m_state.blob, m_state.job.size(), m_hash, m_ctx, m_state.job.height()); + m_thread->fn(job.algorithm())(m_job.blob(), job.size(), m_hash, m_ctx, job.height()); } for (size_t i = 0; i < N; ++i) { - if (*reinterpret_cast(m_hash + (i * 32) + 24) < m_state.job.target()) { - JobResults::submit(JobResult(m_state.job.poolId(), m_state.job.id(), m_state.job.clientId(), *nonce(i), m_hash + (i * 32), m_state.job.diff(), m_state.job.algorithm())); + if (*reinterpret_cast(m_hash + (i * 32) + 24) < job.target()) { + JobResults::submit(JobResult(job.poolId(), job.id(), job.clientId(), *m_job.nonce(i), m_hash + (i * 32), job.diff(), job.algorithm())); } - - *nonce(i) += 1; } + m_job.nextRound(kReserveCount); m_count += N; std::this_thread::yield(); @@ -179,18 +188,6 @@ void xmrig::MultiWorker::start() } -template -bool xmrig::MultiWorker::resume(const xmrig::Job &job) -{ - if (m_state.job.poolId() == -1 && job.poolId() >= 0 && job.id() == m_pausedState.job.id()) { - m_state = m_pausedState; - return true; - } - - return false; -} - - template bool xmrig::MultiWorker::verify(const Algorithm &algorithm, const uint8_t *referenceValue) { @@ -215,10 +212,10 @@ bool xmrig::MultiWorker::verify2(const Algorithm &algorithm, const uint8_t *r for (size_t i = 0; i < (sizeof(cn_r_test_input) / sizeof(cn_r_test_input[0])); ++i) { const size_t size = cn_r_test_input[i].size; for (size_t k = 0; k < N; ++k) { - memcpy(m_state.blob + (k * size), cn_r_test_input[i].data, size); + memcpy(m_job.blob() + (k * size), cn_r_test_input[i].data, size); } - func(m_state.blob, size, m_hash, m_ctx, cn_r_test_input[i].height); + func(m_job.blob(), size, m_hash, m_ctx, cn_r_test_input[i].height); for (size_t k = 0; k < N; ++k) { if (memcmp(m_hash + k * 32, referenceValue + i * 32, sizeof m_hash / N) != 0) { @@ -258,46 +255,7 @@ bool MultiWorker<1>::verify2(const Algorithm &algorithm, const uint8_t *referenc template void xmrig::MultiWorker::consumeJob() { - Job job = Workers::job(); - m_sequence = Workers::sequence(); - if (m_state.job == job) { - return; - } - - save(job); - - if (resume(job)) { - return; - } - - m_state.job = job; - - const size_t size = m_state.job.size(); - memcpy(m_state.blob, m_state.job.blob(), m_state.job.size()); - - if (N > 1) { - for (size_t i = 1; i < N; ++i) { - memcpy(m_state.blob + (i * size), m_state.blob, size); - } - } - - for (size_t i = 0; i < N; ++i) { - if (m_state.job.isNicehash()) { - *nonce(i) = (*nonce(i) & 0xff000000U) + (0xffffffU / m_totalWays * (m_offset + i)); - } - else { - *nonce(i) = 0xffffffffU / m_totalWays * (m_offset + i); - } - } -} - - -template -void xmrig::MultiWorker::save(const Job &job) -{ - if (job.poolId() == -1 && m_state.job.poolId() >= 0) { - m_pausedState = m_state; - } + m_job.add(Workers::job(), Nonce::sequence(), kReserveCount); } diff --git a/src/workers/MultiWorker.h b/src/workers/MultiWorker.h index 0502ad84..2bcb2333 100644 --- a/src/workers/MultiWorker.h +++ b/src/workers/MultiWorker.h @@ -28,6 +28,7 @@ #include "base/net/stratum/Job.h" +#include "core/WorkerJob.h" #include "Mem.h" #include "net/JobResult.h" #include "workers/Worker.h" @@ -55,29 +56,15 @@ private: void allocateRandomX_VM(); # endif - bool resume(const Job &job); bool verify(const Algorithm &algorithm, const uint8_t *referenceValue); bool verify2(const Algorithm &algorithm, const uint8_t *referenceValue); void consumeJob(); - void save(const Job &job); - - inline uint32_t *nonce(size_t index) - { - return reinterpret_cast(m_state.blob + (index * m_state.job.size()) + 39); - } - - struct State - { - alignas(16) uint8_t blob[Job::kMaxBlobSize * N]; - Job job; - }; - cryptonight_ctx *m_ctx[N]; - State m_pausedState; - State m_state; uint8_t m_hash[N * 32]; + WorkerJob m_job; + # ifdef XMRIG_ALGO_RANDOMX RxVm *m_vm = nullptr; # endif diff --git a/src/workers/Worker.cpp b/src/workers/Worker.cpp index 4f69d905..0c61b3cb 100644 --- a/src/workers/Worker.cpp +++ b/src/workers/Worker.cpp @@ -5,7 +5,9 @@ * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , - * Copyright 2016-2018 XMRig , + * Copyright 2018 Lee Clagett + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -38,7 +40,6 @@ Worker::Worker(ThreadHandle *handle) : m_hashCount(0), m_timestamp(0), m_count(0), - m_sequence(0), m_thread(static_cast(handle->config())) { if (xmrig::Cpu::info()->threads() > 1 && m_thread->affinity() != -1L) { diff --git a/src/workers/Worker.h b/src/workers/Worker.h index 3d40257d..13e437d3 100644 --- a/src/workers/Worker.h +++ b/src/workers/Worker.h @@ -5,7 +5,9 @@ * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , - * Copyright 2016-2018 XMRig , + * Copyright 2018 Lee Clagett + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -61,7 +63,6 @@ protected: std::atomic m_hashCount; std::atomic m_timestamp; uint64_t m_count; - uint64_t m_sequence; xmrig::CpuThreadLegacy *m_thread; }; diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 58cccd9e..1ed27c40 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -33,6 +33,7 @@ #include "base/tools/Handle.h" #include "core/config/Config.h" #include "core/Controller.h" +#include "crypto/common/Nonce.h" #include "crypto/rx/RxAlgo.h" #include "crypto/rx/RxCache.h" #include "crypto/rx/RxDataset.h" @@ -51,7 +52,6 @@ Hashrate *Workers::m_hashrate = nullptr; xmrig::Job Workers::m_job; Workers::LaunchStatus Workers::m_status; std::atomic Workers::m_paused; -std::atomic Workers::m_sequence; std::vector Workers::m_workers; uint64_t Workers::m_ticks = 0; uv_mutex_t Workers::m_mutex; @@ -90,6 +90,15 @@ size_t Workers::threads() } +void Workers::pause() +{ + m_active = false; + m_paused = 1; + + xmrig::Nonce::touch(); +} + + void Workers::printHashrate(bool detail) { assert(m_controller != nullptr); @@ -134,7 +143,7 @@ void Workers::setEnabled(bool enabled) } m_paused = enabled ? 0 : 1; - m_sequence++; + xmrig::Nonce::touch(); } @@ -146,6 +155,9 @@ void Workers::setJob(const xmrig::Job &job, bool donate) if (donate) { m_job.setPoolId(-1); } + + xmrig::Nonce::reset(donate ? 1 : 0); + uv_rwlock_wrunlock(&m_rwlock); m_active = true; @@ -153,7 +165,6 @@ void Workers::setJob(const xmrig::Job &job, bool donate) return; } - m_sequence++; m_paused = 0; } @@ -183,7 +194,6 @@ void Workers::start(xmrig::Controller *controller) uv_mutex_init(&m_mutex); uv_rwlock_init(&m_rwlock); - m_sequence = 1; m_paused = 1; m_timer = new uv_timer_t; @@ -208,7 +218,8 @@ void Workers::stop() m_hashrate->stop(); m_paused = 0; - m_sequence = 0; + + xmrig::Nonce::stop(); for (size_t i = 0; i < m_workers.size(); ++i) { m_workers[i]->join(); diff --git a/src/workers/Workers.h b/src/workers/Workers.h index 8619f973..83777d0d 100644 --- a/src/workers/Workers.h +++ b/src/workers/Workers.h @@ -53,21 +53,19 @@ namespace xmrig { class Workers { public: - static xmrig::Job job(); static size_t hugePages(); static size_t threads(); + static void pause(); static void printHashrate(bool detail); static void setEnabled(bool enabled); static void setJob(const xmrig::Job &job, bool donate); static void start(xmrig::Controller *controller); static void stop(); + static xmrig::Job job(); static inline bool isEnabled() { return m_enabled; } - static inline bool isOutdated(uint64_t sequence) { return m_sequence.load(std::memory_order_relaxed) != sequence; } static inline bool isPaused() { return m_paused.load(std::memory_order_relaxed) == 1; } static inline Hashrate *hashrate() { return m_hashrate; } - static inline uint64_t sequence() { return m_sequence.load(std::memory_order_relaxed); } - static inline void pause() { m_active = false; m_paused = 1; m_sequence++; } # ifdef XMRIG_FEATURE_API static void threadsSummary(rapidjson::Document &doc); @@ -103,7 +101,6 @@ private: static xmrig::Job m_job; static LaunchStatus m_status; static std::atomic m_paused; - static std::atomic m_sequence; static std::vector m_workers; static uint64_t m_ticks; static uv_mutex_t m_mutex; From be7ff62c48adcf2644a48c3c494132bd13a913f9 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 12 Jul 2019 02:25:07 +0700 Subject: [PATCH 20/48] Removed no longer required code. --- src/workers/ThreadHandle.cpp | 4 +--- src/workers/ThreadHandle.h | 6 +----- src/workers/Worker.cpp | 2 -- src/workers/Worker.h | 2 -- src/workers/Workers.cpp | 5 +---- 5 files changed, 3 insertions(+), 16 deletions(-) diff --git a/src/workers/ThreadHandle.cpp b/src/workers/ThreadHandle.cpp index 43ff950c..ced5f326 100644 --- a/src/workers/ThreadHandle.cpp +++ b/src/workers/ThreadHandle.cpp @@ -26,10 +26,8 @@ #include "workers/ThreadHandle.h" -ThreadHandle::ThreadHandle(xmrig::IThread *config, uint32_t offset, size_t totalWays) : +ThreadHandle::ThreadHandle(xmrig::IThread *config) : m_worker(nullptr), - m_totalWays(totalWays), - m_offset(offset), m_config(config) { } diff --git a/src/workers/ThreadHandle.h b/src/workers/ThreadHandle.h index f3e09ce5..c32aabf0 100644 --- a/src/workers/ThreadHandle.h +++ b/src/workers/ThreadHandle.h @@ -40,21 +40,17 @@ class IWorker; class ThreadHandle { public: - ThreadHandle(xmrig::IThread *config, uint32_t offset, size_t totalWays); + ThreadHandle(xmrig::IThread *config); void join(); void start(void (*callback) (void *)); inline IWorker *worker() const { return m_worker; } inline size_t threadId() const { return m_config->index(); } - inline size_t totalWays() const { return m_totalWays; } - inline uint32_t offset() const { return m_offset; } inline void setWorker(IWorker *worker) { assert(worker != nullptr); m_worker = worker; } inline xmrig::IThread *config() const { return m_config; } private: IWorker *m_worker; - size_t m_totalWays; - uint32_t m_offset; uv_thread_t m_thread; xmrig::IThread *m_config; }; diff --git a/src/workers/Worker.cpp b/src/workers/Worker.cpp index 0c61b3cb..3a9b693d 100644 --- a/src/workers/Worker.cpp +++ b/src/workers/Worker.cpp @@ -35,8 +35,6 @@ Worker::Worker(ThreadHandle *handle) : m_id(handle->threadId()), - m_totalWays(handle->totalWays()), - m_offset(handle->offset()), m_hashCount(0), m_timestamp(0), m_count(0), diff --git a/src/workers/Worker.h b/src/workers/Worker.h index 13e437d3..997771b0 100644 --- a/src/workers/Worker.h +++ b/src/workers/Worker.h @@ -57,8 +57,6 @@ protected: void storeStats(); const size_t m_id; - const size_t m_totalWays; - const uint32_t m_offset; MemInfo m_memory; std::atomic m_hashCount; std::atomic m_timestamp; diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 1ed27c40..72d9a1d1 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -200,11 +200,8 @@ void Workers::start(xmrig::Controller *controller) uv_timer_init(uv_default_loop(), m_timer); uv_timer_start(m_timer, Workers::onTick, 500, 500); - uint32_t offset = 0; - for (xmrig::IThread *thread : threads) { - ThreadHandle *handle = new ThreadHandle(thread, offset, m_status.ways); - offset += thread->multiway(); + ThreadHandle *handle = new ThreadHandle(thread); m_workers.push_back(handle); handle->start(Workers::onReady); From 4643742d13c08d2e95934cf68223976011f655fe Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 13 Jul 2019 00:49:17 +0700 Subject: [PATCH 21/48] Refactoring --- src/base/net/stratum/Client.cpp | 4 +-- src/base/net/stratum/DaemonClient.cpp | 2 +- src/base/net/stratum/Job.cpp | 13 +------ src/base/net/stratum/Job.h | 18 +++++----- src/core/WorkerJob.h | 6 ++-- src/net/JobResult.h | 50 ++++++++++----------------- src/net/Network.cpp | 2 +- src/workers/MultiWorker.cpp | 2 +- src/workers/Workers.cpp | 6 ++-- 9 files changed, 39 insertions(+), 64 deletions(-) diff --git a/src/base/net/stratum/Client.cpp b/src/base/net/stratum/Client.cpp index 63123720..c1519573 100644 --- a/src/base/net/stratum/Client.cpp +++ b/src/base/net/stratum/Client.cpp @@ -162,7 +162,7 @@ int64_t xmrig::Client::submit(const JobResult &result) Buffer::toHex(reinterpret_cast(&result.nonce), 4, nonce); nonce[8] = '\0'; - Buffer::toHex(result.result, 32, data); + Buffer::toHex(result.result(), 32, data); data[64] = '\0'; # endif @@ -313,7 +313,7 @@ bool xmrig::Client::parseJob(const rapidjson::Value ¶ms, int *code) return false; } - Job job(m_id, has(), m_pool.algorithm(), m_rpcId); + Job job(has(), m_pool.algorithm(), m_rpcId); if (!job.setId(params["job_id"].GetString())) { *code = 3; diff --git a/src/base/net/stratum/DaemonClient.cpp b/src/base/net/stratum/DaemonClient.cpp index 70cc9151..0c141c7d 100644 --- a/src/base/net/stratum/DaemonClient.cpp +++ b/src/base/net/stratum/DaemonClient.cpp @@ -212,7 +212,7 @@ bool xmrig::DaemonClient::isOutdated(uint64_t height, const char *hash) const bool xmrig::DaemonClient::parseJob(const rapidjson::Value ¶ms, int *code) { - Job job(m_id, false, m_pool.algorithm(), String()); + Job job(false, m_pool.algorithm(), String()); String blocktemplate = Json::getString(params, kBlocktemplateBlob); if (blocktemplate.isNull() || !job.setBlob(Json::getString(params, "blockhashing_blob"))) { diff --git a/src/base/net/stratum/Job.cpp b/src/base/net/stratum/Job.cpp index 7e846b3b..a383bbf7 100644 --- a/src/base/net/stratum/Job.cpp +++ b/src/base/net/stratum/Job.cpp @@ -34,27 +34,16 @@ xmrig::Job::Job() : - m_nicehash(false), - m_poolId(-2), - m_size(0), - m_diff(0), - m_height(0), - m_target(0), m_blob(), m_seedHash() { } -xmrig::Job::Job(int poolId, bool nicehash, const Algorithm &algorithm, const String &clientId) : +xmrig::Job::Job(bool nicehash, const Algorithm &algorithm, const String &clientId) : m_algorithm(algorithm), m_nicehash(nicehash), - m_poolId(poolId), - m_size(0), m_clientId(clientId), - m_diff(0), - m_height(0), - m_target(0), m_blob(), m_seedHash() { diff --git a/src/base/net/stratum/Job.h b/src/base/net/stratum/Job.h index c229f95c..06d1be79 100644 --- a/src/base/net/stratum/Job.h +++ b/src/base/net/stratum/Job.h @@ -47,7 +47,7 @@ public: static constexpr const size_t kMaxBlobSize = 128; Job(); - Job(int poolId, bool nicehash, const Algorithm &algorithm, const String &clientId); + Job(bool nicehash, const Algorithm &algorithm, const String &clientId); ~Job(); bool isEqual(const Job &other) const; @@ -65,18 +65,18 @@ public: inline const uint32_t *nonce() const { return reinterpret_cast(m_blob + 39); } inline const uint8_t *blob() const { return m_blob; } inline const uint8_t *seedHash() const { return m_seedHash; } - inline int poolId() const { return m_poolId; } inline size_t size() const { return m_size; } inline uint32_t *nonce() { return reinterpret_cast(m_blob + 39); } inline uint64_t diff() const { return m_diff; } inline uint64_t height() const { return m_height; } inline uint64_t target() const { return m_target; } inline uint8_t fixedByte() const { return *(m_blob + 42); } + inline uint8_t index() const { return m_index; } inline void reset() { m_size = 0; m_diff = 0; } inline void setAlgorithm(const char *algo) { m_algorithm = algo; } inline void setClientId(const String &id) { m_clientId = id; } inline void setHeight(uint64_t height) { m_height = height; } - inline void setPoolId(int poolId) { m_poolId = poolId; } + inline void setIndex(uint8_t index) { m_index = index; } # ifdef XMRIG_PROXY_PROJECT inline char *rawBlob() { return m_rawBlob; } @@ -93,15 +93,15 @@ public: private: Algorithm m_algorithm; - bool m_nicehash; - int m_poolId; - size_t m_size; + bool m_nicehash = false; + size_t m_size = 0; String m_clientId; String m_id; - uint64_t m_diff; - uint64_t m_height; - uint64_t m_target; + uint64_t m_diff = 0; + uint64_t m_height = 0; + uint64_t m_target = 0; uint8_t m_blob[kMaxBlobSize]; + uint8_t m_index = 0; uint8_t m_seedHash[32]; # ifdef XMRIG_PROXY_PROJECT diff --git a/src/core/WorkerJob.h b/src/core/WorkerJob.h index 004c5533..7b598ee6 100644 --- a/src/core/WorkerJob.h +++ b/src/core/WorkerJob.h @@ -56,7 +56,7 @@ public: return; } - if (index() == 1 && job.poolId() >= 0 && job == m_jobs[0]) { + if (index() == 1 && job.index() == 0 && job == m_jobs[0]) { return; } @@ -84,7 +84,7 @@ public: private: inline void save(const Job &job, uint32_t reserveCount) { - m_index = job.poolId() == -1 ? 1 : 0; + m_index = job.index(); const size_t size = job.size(); m_jobs[index()] = job; m_rounds[index()] = 0; @@ -128,7 +128,7 @@ inline void xmrig::WorkerJob<1>::nextRound(uint32_t reserveCount) template<> inline void xmrig::WorkerJob<1>::save(const Job &job, uint32_t reserveCount) { - m_index = job.poolId() == -1 ? 1 : 0; + m_index = job.index(); m_jobs[index()] = job; m_rounds[index()] = 0; diff --git a/src/net/JobResult.h b/src/net/JobResult.h index 9fe1238e..2c2fded5 100644 --- a/src/net/JobResult.h +++ b/src/net/JobResult.h @@ -41,43 +41,31 @@ namespace xmrig { class JobResult { public: - inline JobResult() : poolId(0), nonce(0), diff(0) {} - inline JobResult(int poolId, const String &jobId, const String &clientId, uint32_t nonce, const uint8_t *result, uint64_t diff, const Algorithm &algorithm) : - algorithm(algorithm), - poolId(poolId), - clientId(clientId), - jobId(jobId), + inline JobResult() {} + + inline JobResult(const Job &job, uint32_t nonce, const uint8_t *result) : + algorithm(job.algorithm()), + clientId(job.clientId()), + jobId(job.id()), nonce(nonce), - diff(diff) + diff(job.diff()), + index(job.index()) { - memcpy(this->result, result, sizeof(this->result)); + memcpy(m_result, result, sizeof(m_result)); } + inline const uint8_t *result() const { return m_result; } + inline uint64_t actualDiff() const { return Job::toDiff(reinterpret_cast(m_result)[3]); } - inline JobResult(const Job &job) : poolId(0), nonce(0), diff(0) - { - jobId = job.id(); - clientId = job.clientId(); - poolId = job.poolId(); - diff = job.diff(); - nonce = *job.nonce(); - algorithm = job.algorithm(); - } + const Algorithm algorithm; + const String clientId; + const String jobId; + const uint32_t nonce = 0; + const uint64_t diff = 0; + const uint8_t index = 0; - - inline uint64_t actualDiff() const - { - return Job::toDiff(reinterpret_cast(result)[3]); - } - - - Algorithm algorithm; - int poolId; - String clientId; - String jobId; - uint32_t nonce; - uint64_t diff; - uint8_t result[32]; +private: + uint8_t m_result[32]; }; diff --git a/src/net/Network.cpp b/src/net/Network.cpp index c08facb9..d40bebd1 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -144,7 +144,7 @@ void xmrig::Network::onJob(IStrategy *strategy, IClient *client, const Job &job) void xmrig::Network::onJobResult(const JobResult &result) { - if (result.poolId == -1 && m_donate) { + if (result.index == 1 && m_donate) { m_donate->submit(result); return; } diff --git a/src/workers/MultiWorker.cpp b/src/workers/MultiWorker.cpp index daae9230..1f06455a 100644 --- a/src/workers/MultiWorker.cpp +++ b/src/workers/MultiWorker.cpp @@ -173,7 +173,7 @@ void xmrig::MultiWorker::start() for (size_t i = 0; i < N; ++i) { if (*reinterpret_cast(m_hash + (i * 32) + 24) < job.target()) { - JobResults::submit(JobResult(job.poolId(), job.id(), job.clientId(), *m_job.nonce(i), m_hash + (i * 32), job.diff(), job.algorithm())); + JobResults::submit(JobResult(job, *m_job.nonce(i), m_hash + (i * 32))); } } diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 72d9a1d1..53a8b712 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -150,11 +150,9 @@ void Workers::setEnabled(bool enabled) void Workers::setJob(const xmrig::Job &job, bool donate) { uv_rwlock_wrlock(&m_rwlock); - m_job = job; - if (donate) { - m_job.setPoolId(-1); - } + m_job = job; + m_job.setIndex(donate ? 1 : 0); xmrig::Nonce::reset(donate ? 1 : 0); From 8b3f2d8fff01b230b47f54dfcbd12ef66beab274 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 13 Jul 2019 16:48:14 +0700 Subject: [PATCH 22/48] Move Platform. --- CMakeLists.txt | 5 ----- src/App.cpp | 1 - src/api/v1/ApiRouter.cpp | 2 +- src/base/base.cmake | 17 +++++++++++++++-- src/base/kernel/Base.cpp | 2 +- src/{common => base/kernel}/Platform.cpp | 0 src/{common => base/kernel}/Platform.h | 9 +++++++++ src/{common => base/kernel}/Platform_mac.cpp | 0 src/{common => base/kernel}/Platform_unix.cpp | 0 src/{common => base/kernel}/Platform_win.cpp | 0 src/base/net/http/HttpClient.cpp | 2 +- .../net/stratum/strategies/FailoverStrategy.cpp | 2 +- .../stratum/strategies/SinglePoolStrategy.cpp | 2 +- src/core/Controller.cpp | 1 - src/net/strategies/DonateStrategy.cpp | 2 +- src/workers/Worker.cpp | 2 +- 16 files changed, 31 insertions(+), 16 deletions(-) rename src/{common => base/kernel}/Platform.cpp (100%) rename src/{common => base/kernel}/Platform.h (90%) rename src/{common => base/kernel}/Platform_mac.cpp (100%) rename src/{common => base/kernel}/Platform_unix.cpp (100%) rename src/{common => base/kernel}/Platform_win.cpp (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 13f787f7..a6adda76 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,7 +27,6 @@ set(HEADERS "${HEADERS_BACKEND}" src/api/interfaces/IApiListener.h src/App.h - src/common/Platform.h src/common/xmrig.h src/core/config/Config_default.h src/core/config/Config_platform.h @@ -88,7 +87,6 @@ set(SOURCES "${SOURCES_BASE_HTTP}" "${SOURCES_BACKEND}" src/App.cpp - src/common/Platform.cpp src/core/config/Config.cpp src/core/config/ConfigTransform.cpp src/core/Controller.cpp @@ -123,7 +121,6 @@ if (WIN32) "${SOURCES_OS}" res/app.rc src/App_win.cpp - src/common/Platform_win.cpp src/Mem_win.cpp src/crypto/common/VirtualMemory_win.cpp ) @@ -134,7 +131,6 @@ elseif (APPLE) set(SOURCES_OS "${SOURCES_OS}" src/App_unix.cpp - src/common/Platform_mac.cpp src/Mem_unix.cpp src/crypto/common/VirtualMemory_unix.cpp ) @@ -142,7 +138,6 @@ else() set(SOURCES_OS "${SOURCES_OS}" src/App_unix.cpp - src/common/Platform_unix.cpp src/Mem_unix.cpp src/crypto/common/VirtualMemory_unix.cpp ) diff --git a/src/App.cpp b/src/App.cpp index 6e42ac30..5b2178ac 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -34,7 +34,6 @@ #include "base/io/Console.h" #include "base/io/log/Log.h" #include "base/kernel/Signals.h" -#include "common/Platform.h" #include "core/config/Config.h" #include "core/Controller.h" #include "Mem.h" diff --git a/src/api/v1/ApiRouter.cpp b/src/api/v1/ApiRouter.cpp index ff1ef404..18d97fda 100644 --- a/src/api/v1/ApiRouter.cpp +++ b/src/api/v1/ApiRouter.cpp @@ -31,7 +31,7 @@ #include "api/v1/ApiRouter.h" #include "backend/cpu/Cpu.h" #include "base/kernel/Base.h" -#include "common/Platform.h" +#include "base/kernel/Platform.h" #include "core/config/Config.h" #include "interfaces/IThread.h" #include "rapidjson/document.h" diff --git a/src/base/base.cmake b/src/base/base.cmake index dcc10495..b25d9743 100644 --- a/src/base/base.cmake +++ b/src/base/base.cmake @@ -26,6 +26,7 @@ set(HEADERS_BASE src/base/kernel/interfaces/IStrategyListener.h src/base/kernel/interfaces/ITimerListener.h src/base/kernel/interfaces/IWatcherListener.h + src/base/kernel/Platform.h src/base/kernel/Process.h src/base/kernel/Signals.h src/base/net/dns/Dns.h @@ -63,6 +64,7 @@ set(SOURCES_BASE src/base/kernel/config/BaseConfig.cpp src/base/kernel/config/BaseTransform.cpp src/base/kernel/Entry.cpp + src/base/kernel/Platform.cpp src/base/kernel/Process.cpp src/base/kernel/Signals.cpp src/base/net/dns/Dns.cpp @@ -83,9 +85,20 @@ set(SOURCES_BASE if (WIN32) - set(SOURCES_OS src/base/io/json/Json_win.cpp) + set(SOURCES_OS + src/base/io/json/Json_win.cpp + src/base/kernel/Platform_win.cpp + ) +elseif (APPLE) + set(SOURCES_OS + src/base/io/json/Json_unix.cpp + src/base/kernel/Platform_mac.cpp + ) else() - set(SOURCES_OS src/base/io/json/Json_unix.cpp) + set(SOURCES_OS + src/base/io/json/Json_unix.cpp + src/base/kernel//Platform_unix.cpp + ) endif() diff --git a/src/base/kernel/Base.cpp b/src/base/kernel/Base.cpp index 031daed7..46f32684 100644 --- a/src/base/kernel/Base.cpp +++ b/src/base/kernel/Base.cpp @@ -35,8 +35,8 @@ #include "base/io/Watcher.h" #include "base/kernel/Base.h" #include "base/kernel/interfaces/IBaseListener.h" +#include "base/kernel/Platform.h" #include "base/kernel/Process.h" -#include "common/Platform.h" #include "core/config/Config.h" #include "core/config/ConfigTransform.h" diff --git a/src/common/Platform.cpp b/src/base/kernel/Platform.cpp similarity index 100% rename from src/common/Platform.cpp rename to src/base/kernel/Platform.cpp diff --git a/src/common/Platform.h b/src/base/kernel/Platform.h similarity index 90% rename from src/common/Platform.h rename to src/base/kernel/Platform.h index 85f08a2e..f3c2c719 100644 --- a/src/common/Platform.h +++ b/src/base/kernel/Platform.h @@ -35,6 +35,15 @@ class Platform { public: + static inline bool trySetThreadAffinity(int64_t cpu_id) + { + if (cpu_id < 0) { + return false; + } + + return setThreadAffinity(static_cast(cpu_id)); + } + static bool setThreadAffinity(uint64_t cpu_id); static uint32_t setTimerResolution(uint32_t resolution); static void init(const char *userAgent); diff --git a/src/common/Platform_mac.cpp b/src/base/kernel/Platform_mac.cpp similarity index 100% rename from src/common/Platform_mac.cpp rename to src/base/kernel/Platform_mac.cpp diff --git a/src/common/Platform_unix.cpp b/src/base/kernel/Platform_unix.cpp similarity index 100% rename from src/common/Platform_unix.cpp rename to src/base/kernel/Platform_unix.cpp diff --git a/src/common/Platform_win.cpp b/src/base/kernel/Platform_win.cpp similarity index 100% rename from src/common/Platform_win.cpp rename to src/base/kernel/Platform_win.cpp diff --git a/src/base/net/http/HttpClient.cpp b/src/base/net/http/HttpClient.cpp index 319bb4dd..113e2f13 100644 --- a/src/base/net/http/HttpClient.cpp +++ b/src/base/net/http/HttpClient.cpp @@ -29,10 +29,10 @@ #include "3rdparty/http-parser/http_parser.h" #include "base/io/log/Log.h" +#include "base/kernel/Platform.h" #include "base/net/dns/Dns.h" #include "base/net/http/HttpClient.h" #include "base/tools/Baton.h" -#include "common/Platform.h" namespace xmrig { diff --git a/src/base/net/stratum/strategies/FailoverStrategy.cpp b/src/base/net/stratum/strategies/FailoverStrategy.cpp index d5247229..9545e9e1 100644 --- a/src/base/net/stratum/strategies/FailoverStrategy.cpp +++ b/src/base/net/stratum/strategies/FailoverStrategy.cpp @@ -24,9 +24,9 @@ #include "base/kernel/interfaces/IStrategyListener.h" +#include "base/kernel/Platform.h" #include "base/net/stratum/Client.h" #include "base/net/stratum/strategies/FailoverStrategy.h" -#include "common/Platform.h" #ifdef XMRIG_FEATURE_HTTP diff --git a/src/base/net/stratum/strategies/SinglePoolStrategy.cpp b/src/base/net/stratum/strategies/SinglePoolStrategy.cpp index f432514e..6c6a6fc1 100644 --- a/src/base/net/stratum/strategies/SinglePoolStrategy.cpp +++ b/src/base/net/stratum/strategies/SinglePoolStrategy.cpp @@ -24,9 +24,9 @@ #include "base/kernel/interfaces/IStrategyListener.h" +#include "base/kernel/Platform.h" #include "base/net/stratum/Client.h" #include "base/net/stratum/strategies/SinglePoolStrategy.h" -#include "common/Platform.h" #ifdef XMRIG_FEATURE_HTTP diff --git a/src/core/Controller.cpp b/src/core/Controller.cpp index 8e2e03a1..81c67d7c 100644 --- a/src/core/Controller.cpp +++ b/src/core/Controller.cpp @@ -27,7 +27,6 @@ #include "backend/cpu/Cpu.h" -#include "common/Platform.h" #include "core/Controller.h" #include "net/Network.h" diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp index 9669db9a..78c7acc5 100644 --- a/src/net/strategies/DonateStrategy.cpp +++ b/src/net/strategies/DonateStrategy.cpp @@ -26,13 +26,13 @@ #include +#include "base/kernel/Platform.h" #include "base/net/stratum/Client.h" #include "base/net/stratum/Job.h" #include "base/net/stratum/strategies/FailoverStrategy.h" #include "base/net/stratum/strategies/SinglePoolStrategy.h" #include "base/tools/Buffer.h" #include "base/tools/Timer.h" -#include "common/Platform.h" #include "common/xmrig.h" #include "core/config/Config.h" #include "core/Controller.h" diff --git a/src/workers/Worker.cpp b/src/workers/Worker.cpp index 3a9b693d..d85858af 100644 --- a/src/workers/Worker.cpp +++ b/src/workers/Worker.cpp @@ -27,7 +27,7 @@ #include "backend/cpu/Cpu.h" -#include "common/Platform.h" +#include "base/kernel/Platform.h" #include "workers/CpuThreadLegacy.h" #include "workers/ThreadHandle.h" #include "workers/Worker.h" From dc87ef60620b48ef9b3482583380850ff32bcc2d Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 13 Jul 2019 19:10:17 +0700 Subject: [PATCH 23/48] Removed xmrig.h. --- CMakeLists.txt | 1 - src/Mem_unix.cpp | 1 - src/Mem_win.cpp | 1 - src/base/kernel/config/BaseConfig.h | 1 - src/common/xmrig.h | 78 --------------------------- src/core/config/Config.cpp | 20 +++---- src/core/config/Config.h | 9 ++-- src/crypto/cn/CnHash.h | 16 +++++- src/crypto/cn/CryptoNight_monero.h | 1 - src/crypto/common/Assembly.h | 1 - src/net/strategies/DonateStrategy.cpp | 1 - src/workers/CpuThreadLegacy.cpp | 38 ++++++------- src/workers/CpuThreadLegacy.h | 11 ++-- 13 files changed, 53 insertions(+), 126 deletions(-) delete mode 100644 src/common/xmrig.h diff --git a/CMakeLists.txt b/CMakeLists.txt index a6adda76..48946c7e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,7 +27,6 @@ set(HEADERS "${HEADERS_BACKEND}" src/api/interfaces/IApiListener.h src/App.h - src/common/xmrig.h src/core/config/Config_default.h src/core/config/Config_platform.h src/core/config/Config.h diff --git a/src/Mem_unix.cpp b/src/Mem_unix.cpp index 9bdce0f5..4dc13e93 100644 --- a/src/Mem_unix.cpp +++ b/src/Mem_unix.cpp @@ -29,7 +29,6 @@ #include "base/io/log/Log.h" -#include "common/xmrig.h" #include "crypto/common/portable/mm_malloc.h" #include "crypto/common/VirtualMemory.h" #include "crypto/cn/CryptoNight.h" diff --git a/src/Mem_win.cpp b/src/Mem_win.cpp index 34460e9d..56b4521d 100644 --- a/src/Mem_win.cpp +++ b/src/Mem_win.cpp @@ -31,7 +31,6 @@ #include "base/io/log/Log.h" -#include "common/xmrig.h" #include "crypto/common/portable/mm_malloc.h" #include "crypto/common/VirtualMemory.h" #include "crypto/cn/CryptoNight.h" diff --git a/src/base/kernel/config/BaseConfig.h b/src/base/kernel/config/BaseConfig.h index 48d7c2cf..c5cf29a3 100644 --- a/src/base/kernel/config/BaseConfig.h +++ b/src/base/kernel/config/BaseConfig.h @@ -29,7 +29,6 @@ #include "base/kernel/interfaces/IConfig.h" #include "base/net/http/Http.h" #include "base/net/stratum/Pools.h" -#include "common/xmrig.h" struct option; diff --git a/src/common/xmrig.h b/src/common/xmrig.h deleted file mode 100644 index 169c4c1f..00000000 --- a/src/common/xmrig.h +++ /dev/null @@ -1,78 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017-2018 XMR-Stak , - * Copyright 2018-2019 SChernykh - * Copyright 2016-2019 XMRig , - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef XMRIG_XMRIG_H -#define XMRIG_XMRIG_H - - -namespace xmrig -{ - - -//--av=1 For CPUs with hardware AES. -//--av=2 Lower power mode (double hash) of 1. -//--av=3 Software AES implementation. -//--av=4 Lower power mode (double hash) of 3. -enum AlgoVariant { - AV_AUTO, // --av=0 Automatic mode. - AV_SINGLE, // --av=1 Single hash mode - AV_DOUBLE, // --av=2 Double hash mode - AV_SINGLE_SOFT, // --av=3 Single hash mode (Software AES) - AV_DOUBLE_SOFT, // --av=4 Double hash mode (Software AES) - AV_TRIPLE, // --av=5 Triple hash mode - AV_QUAD, // --av=6 Quard hash mode - AV_PENTA, // --av=7 Penta hash mode - AV_TRIPLE_SOFT, // --av=8 Triple hash mode (Software AES) - AV_QUAD_SOFT, // --av=9 Quard hash mode (Software AES) - AV_PENTA_SOFT, // --av=10 Penta hash mode (Software AES) - AV_MAX -}; - - -enum AlgoVerify { - VERIFY_HW_AES = 1, - VERIFY_SOFT_AES = 2 -}; - - -enum AesMode { - AES_AUTO, - AES_HW, - AES_SOFT -}; - - -enum OclVendor { - OCL_VENDOR_UNKNOWN = -2, - OCL_VENDOR_MANUAL = -1, - OCL_VENDOR_AMD = 0, - OCL_VENDOR_NVIDIA = 1, - OCL_VENDOR_INTEL = 2 -}; - - -} /* namespace xmrig */ - - -#endif /* XMRIG_XMRIG_H */ diff --git a/src/core/config/Config.cpp b/src/core/config/Config.cpp index 784e171c..02ef9c90 100644 --- a/src/core/config/Config.cpp +++ b/src/core/config/Config.cpp @@ -40,7 +40,7 @@ xmrig::Config::Config() : - m_algoVariant(AV_AUTO), + m_algoVariant(CnHash::AV_AUTO), m_shouldSave(false) { } @@ -131,7 +131,7 @@ bool xmrig::Config::finalize() return true; } - const AlgoVariant av = getAlgoVariant(); + const CnHash::AlgoVariant av = getAlgoVariant(); m_threads.mode = m_threads.count ? Simple : Automatic; const size_t size = CpuThreadLegacy::multiway(av) * CnAlgo<>::memory(algorithm) / 1024; // FIXME MEMORY @@ -158,8 +158,8 @@ bool xmrig::Config::finalize() void xmrig::Config::setAlgoVariant(int av) { - if (av >= AV_AUTO && av < AV_MAX) { - m_algoVariant = static_cast(av); + if (av >= CnHash::AV_AUTO && av < CnHash::AV_MAX) { + m_algoVariant = static_cast(av); } } @@ -192,7 +192,7 @@ void xmrig::Config::setThreads(const rapidjson::Value &threads) } -xmrig::AlgoVariant xmrig::Config::getAlgoVariant() const +xmrig::CnHash::AlgoVariant xmrig::Config::getAlgoVariant() const { # ifdef XMRIG_ALGO_CN_LITE // if (m_algorithm.algo() == xmrig::CRYPTONIGHT_LITE) { // FIXME @@ -200,8 +200,8 @@ xmrig::AlgoVariant xmrig::Config::getAlgoVariant() const // } # endif - if (m_algoVariant <= AV_AUTO || m_algoVariant >= AV_MAX) { - return Cpu::info()->hasAES() ? AV_SINGLE : AV_SINGLE_SOFT; + if (m_algoVariant <= CnHash::AV_AUTO || m_algoVariant >= CnHash::AV_MAX) { + return Cpu::info()->hasAES() ? CnHash::AV_SINGLE : CnHash::AV_SINGLE_SOFT; } // if (m_safe && !Cpu::info()->hasAES() && m_algoVariant <= AV_DOUBLE) { @@ -213,10 +213,10 @@ xmrig::AlgoVariant xmrig::Config::getAlgoVariant() const #ifdef XMRIG_ALGO_CN_LITE -xmrig::AlgoVariant xmrig::Config::getAlgoVariantLite() const +xmrig::CnHash::AlgoVariant xmrig::Config::getAlgoVariantLite() const { - if (m_algoVariant <= AV_AUTO || m_algoVariant >= AV_MAX) { - return Cpu::info()->hasAES() ? AV_DOUBLE : AV_DOUBLE_SOFT; + if (m_algoVariant <= CnHash::AV_AUTO || m_algoVariant >= CnHash::AV_MAX) { + return Cpu::info()->hasAES() ? CnHash::AV_DOUBLE : CnHash::AV_DOUBLE_SOFT; } // if (m_safe && !Cpu::info()->hasAES() && m_algoVariant <= AV_DOUBLE) { diff --git a/src/core/config/Config.h b/src/core/config/Config.h index 7b765892..aa547796 100644 --- a/src/core/config/Config.h +++ b/src/core/config/Config.h @@ -32,7 +32,6 @@ #include "backend/cpu/CpuConfig.h" #include "base/kernel/config/BaseConfig.h" -#include "common/xmrig.h" #include "rapidjson/fwd.h" #include "workers/CpuThreadLegacy.h" @@ -58,7 +57,7 @@ public: bool read(const IJsonReader &reader, const char *fileName) override; void getJSON(rapidjson::Document &doc) const override; - inline AlgoVariant algoVariant() const { return m_algoVariant; } + inline CnHash::AlgoVariant algoVariant() const { return m_algoVariant; } inline bool isShouldSave() const { return (m_shouldSave || m_upgrade || m_cpu.isShouldSave()) && isAutoSave(); } inline const CpuConfig &cpu() const { return m_cpu; } inline const std::vector &threads() const { return m_threads.list; } @@ -70,9 +69,9 @@ private: void setAlgoVariant(int av); void setThreads(const rapidjson::Value &threads); - AlgoVariant getAlgoVariant() const; + CnHash::AlgoVariant getAlgoVariant() const; # ifdef XMRIG_ALGO_CN_LITE - AlgoVariant getAlgoVariantLite() const; + CnHash::AlgoVariant getAlgoVariantLite() const; # endif struct Threads @@ -87,7 +86,7 @@ private: }; - AlgoVariant m_algoVariant; + CnHash::AlgoVariant m_algoVariant; bool m_shouldSave; CpuConfig m_cpu; Threads m_threads; diff --git a/src/crypto/cn/CnHash.h b/src/crypto/cn/CnHash.h index b57bff4c..fdfcc9f3 100644 --- a/src/crypto/cn/CnHash.h +++ b/src/crypto/cn/CnHash.h @@ -31,7 +31,6 @@ #include -#include "common/xmrig.h" #include "crypto/cn/CnAlgo.h" #include "crypto/common/Assembly.h" @@ -49,6 +48,21 @@ typedef void (*cn_mainloop_fun)(cryptonight_ctx **ctx); class CnHash { public: + enum AlgoVariant { + AV_AUTO, // --av=0 Automatic mode. + AV_SINGLE, // --av=1 Single hash mode + AV_DOUBLE, // --av=2 Double hash mode + AV_SINGLE_SOFT, // --av=3 Single hash mode (Software AES) + AV_DOUBLE_SOFT, // --av=4 Double hash mode (Software AES) + AV_TRIPLE, // --av=5 Triple hash mode + AV_QUAD, // --av=6 Quard hash mode + AV_PENTA, // --av=7 Penta hash mode + AV_TRIPLE_SOFT, // --av=8 Triple hash mode (Software AES) + AV_QUAD_SOFT, // --av=9 Quard hash mode (Software AES) + AV_PENTA_SOFT, // --av=10 Penta hash mode (Software AES) + AV_MAX + }; + CnHash(); cn_hash_fun fn(const Algorithm &algorithm, AlgoVariant av, Assembly::Id assembly) const; diff --git a/src/crypto/cn/CryptoNight_monero.h b/src/crypto/cn/CryptoNight_monero.h index 13948dcd..dc012bdc 100644 --- a/src/crypto/cn/CryptoNight_monero.h +++ b/src/crypto/cn/CryptoNight_monero.h @@ -178,7 +178,6 @@ #endif #endif -#include "common/xmrig.h" #include "crypto/cn/r/variant4_random_math.h" #define VARIANT4_RANDOM_MATH_INIT(part) \ diff --git a/src/crypto/common/Assembly.h b/src/crypto/common/Assembly.h index afd8a536..5ea29e11 100644 --- a/src/crypto/common/Assembly.h +++ b/src/crypto/common/Assembly.h @@ -26,7 +26,6 @@ #define XMRIG_ASSEMBLY_H -#include "common/xmrig.h" #include "rapidjson/fwd.h" diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp index 78c7acc5..2d0a5b43 100644 --- a/src/net/strategies/DonateStrategy.cpp +++ b/src/net/strategies/DonateStrategy.cpp @@ -33,7 +33,6 @@ #include "base/net/stratum/strategies/SinglePoolStrategy.h" #include "base/tools/Buffer.h" #include "base/tools/Timer.h" -#include "common/xmrig.h" #include "core/config/Config.h" #include "core/Controller.h" #include "crypto/common/keccak.h" diff --git a/src/workers/CpuThreadLegacy.cpp b/src/workers/CpuThreadLegacy.cpp index df9b9904..b8e33839 100644 --- a/src/workers/CpuThreadLegacy.cpp +++ b/src/workers/CpuThreadLegacy.cpp @@ -38,7 +38,7 @@ static const xmrig::CnHash cnHash; -xmrig::CpuThreadLegacy::CpuThreadLegacy(size_t index, Algorithm algorithm, AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch, Assembly assembly) : +xmrig::CpuThreadLegacy::CpuThreadLegacy(size_t index, Algorithm algorithm, CnHash::AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch, Assembly assembly) : m_algorithm(algorithm), m_av(av), m_assembly(assembly), @@ -59,15 +59,15 @@ xmrig::cn_hash_fun xmrig::CpuThreadLegacy::fn(const Algorithm &algorithm) const -bool xmrig::CpuThreadLegacy::isSoftAES(AlgoVariant av) +bool xmrig::CpuThreadLegacy::isSoftAES(CnHash::AlgoVariant av) { - return av == AV_SINGLE_SOFT || av == AV_DOUBLE_SOFT || av > AV_PENTA; + return av == CnHash::AV_SINGLE_SOFT || av == CnHash::AV_DOUBLE_SOFT || av > CnHash::AV_PENTA; } -xmrig::CpuThreadLegacy *xmrig::CpuThreadLegacy::createFromAV(size_t index, const Algorithm &algorithm, AlgoVariant av, int64_t affinity, int priority, Assembly assembly) +xmrig::CpuThreadLegacy *xmrig::CpuThreadLegacy::createFromAV(size_t index, const Algorithm &algorithm, CnHash::AlgoVariant av, int64_t affinity, int priority, Assembly assembly) { - assert(av > AV_AUTO && av < AV_MAX); + assert(av > CnHash::AV_AUTO && av < CnHash::AV_MAX); int64_t cpuId = -1L; @@ -94,7 +94,7 @@ xmrig::CpuThreadLegacy *xmrig::CpuThreadLegacy::createFromAV(size_t index, const xmrig::CpuThreadLegacy *xmrig::CpuThreadLegacy::createFromData(size_t index, const Algorithm &algorithm, const CpuThreadLegacy::Data &data, int priority, bool softAES) { - int av = AV_AUTO; + int av = CnHash::AV_AUTO; const Multiway multiway = data.multiway; if (multiway <= DoubleWay) { @@ -104,9 +104,9 @@ xmrig::CpuThreadLegacy *xmrig::CpuThreadLegacy::createFromData(size_t index, con av = softAES ? (multiway + 5) : (multiway + 2); } - assert(av > AV_AUTO && av < AV_MAX); + assert(av > CnHash::AV_AUTO && av < CnHash::AV_MAX); - return new CpuThreadLegacy(index, algorithm, static_cast(av), multiway, data.affinity, priority, softAES, false, data.assembly); + return new CpuThreadLegacy(index, algorithm, static_cast(av), multiway, data.affinity, priority, softAES, false, data.assembly); } @@ -140,27 +140,27 @@ xmrig::CpuThreadLegacy::Data xmrig::CpuThreadLegacy::parse(const rapidjson::Valu } -xmrig::IThread::Multiway xmrig::CpuThreadLegacy::multiway(AlgoVariant av) +xmrig::IThread::Multiway xmrig::CpuThreadLegacy::multiway(CnHash::AlgoVariant av) { switch (av) { - case AV_SINGLE: - case AV_SINGLE_SOFT: + case CnHash::AV_SINGLE: + case CnHash::AV_SINGLE_SOFT: return SingleWay; - case AV_DOUBLE_SOFT: - case AV_DOUBLE: + case CnHash::AV_DOUBLE_SOFT: + case CnHash::AV_DOUBLE: return DoubleWay; - case AV_TRIPLE_SOFT: - case AV_TRIPLE: + case CnHash::AV_TRIPLE_SOFT: + case CnHash::AV_TRIPLE: return TripleWay; - case AV_QUAD_SOFT: - case AV_QUAD: + case CnHash::AV_QUAD_SOFT: + case CnHash::AV_QUAD: return QuadWay; - case AV_PENTA_SOFT: - case AV_PENTA: + case CnHash::AV_PENTA_SOFT: + case CnHash::AV_PENTA: return PentaWay; default: diff --git a/src/workers/CpuThreadLegacy.h b/src/workers/CpuThreadLegacy.h index ed69d8ac..4553295c 100644 --- a/src/workers/CpuThreadLegacy.h +++ b/src/workers/CpuThreadLegacy.h @@ -26,7 +26,6 @@ #define XMRIG_CPUTHREADLEGACY_H -#include "common/xmrig.h" #include "crypto/cn/CnHash.h" #include "interfaces/IThread.h" @@ -59,15 +58,15 @@ public: }; - CpuThreadLegacy(size_t index, Algorithm algorithm, AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch, Assembly assembly); + CpuThreadLegacy(size_t index, Algorithm algorithm, CnHash::AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch, Assembly assembly); cn_hash_fun fn(const Algorithm &algorithm) const; - static bool isSoftAES(AlgoVariant av); - static CpuThreadLegacy *createFromAV(size_t index, const Algorithm &algorithm, AlgoVariant av, int64_t affinity, int priority, Assembly assembly); + static bool isSoftAES(CnHash::AlgoVariant av); + static CpuThreadLegacy *createFromAV(size_t index, const Algorithm &algorithm, CnHash::AlgoVariant av, int64_t affinity, int priority, Assembly assembly); static CpuThreadLegacy *createFromData(size_t index, const Algorithm &algorithm, const CpuThreadLegacy::Data &data, int priority, bool softAES); static Data parse(const rapidjson::Value &object); - static Multiway multiway(AlgoVariant av); + static Multiway multiway(CnHash::AlgoVariant av); inline bool isPrefetch() const { return m_prefetch; } inline bool isSoftAES() const { return m_softAES; } @@ -92,7 +91,7 @@ protected: private: const Algorithm m_algorithm; - const AlgoVariant m_av; + const CnHash::AlgoVariant m_av; const Assembly m_assembly; const bool m_prefetch; const bool m_softAES; From ee434a57081b7c61b13b54ab49518a2fc5f23b0b Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 13 Jul 2019 22:15:53 +0700 Subject: [PATCH 24/48] Move files. --- CMakeLists.txt | 7 ----- src/api/v1/ApiRouter.cpp | 2 +- src/backend/backend.cmake | 9 +++--- src/backend/{ => common}/Threads.cpp | 2 +- src/backend/{ => common}/Threads.h | 0 src/{workers => backend/common}/Worker.cpp | 2 +- src/{workers => backend/common}/Worker.h | 2 +- src/{core => backend/common}/WorkerJob.h | 0 src/backend/common/common.cmake | 12 ++++++++ src/{ => backend/common}/interfaces/IThread.h | 0 src/{ => backend/common}/interfaces/IWorker.h | 0 src/backend/cpu/CpuConfig.h | 2 +- .../cpu/CpuWorker.cpp} | 30 +++++++++---------- .../MultiWorker.h => backend/cpu/CpuWorker.h} | 27 ++++++++++++----- src/backend/cpu/cpu.cmake | 12 ++++---- src/workers/CpuThreadLegacy.h | 2 +- src/workers/ThreadHandle.h | 2 +- src/workers/Workers.cpp | 16 ++++------ 18 files changed, 71 insertions(+), 56 deletions(-) rename src/backend/{ => common}/Threads.cpp (99%) rename src/backend/{ => common}/Threads.h (100%) rename src/{workers => backend/common}/Worker.cpp (98%) rename src/{workers => backend/common}/Worker.h (97%) rename src/{core => backend/common}/WorkerJob.h (100%) create mode 100644 src/backend/common/common.cmake rename src/{ => backend/common}/interfaces/IThread.h (100%) rename src/{ => backend/common}/interfaces/IWorker.h (100%) rename src/{workers/MultiWorker.cpp => backend/cpu/CpuWorker.cpp} (90%) rename src/{workers/MultiWorker.h => backend/cpu/CpuWorker.h} (78%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 48946c7e..8291f606 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,9 +33,6 @@ set(HEADERS src/core/config/ConfigTransform.h src/core/config/usage.h src/core/Controller.h - src/core/WorkerJob.h - src/interfaces/IThread.h - src/interfaces/IWorker.h src/Mem.h src/net/interfaces/IJobResultListener.h src/net/JobResult.h @@ -47,9 +44,7 @@ set(HEADERS src/version.h src/workers/CpuThreadLegacy.h src/workers/Hashrate.h - src/workers/MultiWorker.h src/workers/ThreadHandle.h - src/workers/Worker.h src/workers/Workers.h ) @@ -97,9 +92,7 @@ set(SOURCES src/Summary.cpp src/workers/CpuThreadLegacy.cpp src/workers/Hashrate.cpp - src/workers/MultiWorker.cpp src/workers/ThreadHandle.cpp - src/workers/Worker.cpp src/workers/Workers.cpp src/xmrig.cpp ) diff --git a/src/api/v1/ApiRouter.cpp b/src/api/v1/ApiRouter.cpp index 18d97fda..5ed94c4b 100644 --- a/src/api/v1/ApiRouter.cpp +++ b/src/api/v1/ApiRouter.cpp @@ -29,11 +29,11 @@ #include "api/interfaces/IApiRequest.h" #include "api/v1/ApiRouter.h" +#include "backend/common/interfaces/IThread.h" #include "backend/cpu/Cpu.h" #include "base/kernel/Base.h" #include "base/kernel/Platform.h" #include "core/config/Config.h" -#include "interfaces/IThread.h" #include "rapidjson/document.h" #include "version.h" #include "workers/Hashrate.h" diff --git a/src/backend/backend.cmake b/src/backend/backend.cmake index 750cc9cb..c37cf262 100644 --- a/src/backend/backend.cmake +++ b/src/backend/backend.cmake @@ -1,12 +1,13 @@ include (src/backend/cpu/cpu.cmake) +include (src/backend/common/common.cmake) set(HEADERS_BACKEND - "${HEADERS_CPU}" - src/backend/Threads.h + "${HEADERS_BACKEND_COMMON}" + "${HEADERS_BACKEND_CPU}" ) set(SOURCES_BACKEND - "${SOURCES_CPU}" - src/backend/Threads.cpp + "${SOURCES_BACKEND_COMMON}" + "${SOURCES_BACKEND_CPU}" ) diff --git a/src/backend/Threads.cpp b/src/backend/common/Threads.cpp similarity index 99% rename from src/backend/Threads.cpp rename to src/backend/common/Threads.cpp index 11e1ec15..4cb9d4c6 100644 --- a/src/backend/Threads.cpp +++ b/src/backend/common/Threads.cpp @@ -23,8 +23,8 @@ */ +#include "backend/common/Threads.h" #include "backend/cpu/CpuThread.h" -#include "backend/Threads.h" #include "rapidjson/document.h" diff --git a/src/backend/Threads.h b/src/backend/common/Threads.h similarity index 100% rename from src/backend/Threads.h rename to src/backend/common/Threads.h diff --git a/src/workers/Worker.cpp b/src/backend/common/Worker.cpp similarity index 98% rename from src/workers/Worker.cpp rename to src/backend/common/Worker.cpp index d85858af..f0457bbb 100644 --- a/src/workers/Worker.cpp +++ b/src/backend/common/Worker.cpp @@ -26,11 +26,11 @@ #include +#include "backend/common/Worker.h" #include "backend/cpu/Cpu.h" #include "base/kernel/Platform.h" #include "workers/CpuThreadLegacy.h" #include "workers/ThreadHandle.h" -#include "workers/Worker.h" Worker::Worker(ThreadHandle *handle) : diff --git a/src/workers/Worker.h b/src/backend/common/Worker.h similarity index 97% rename from src/workers/Worker.h rename to src/backend/common/Worker.h index 997771b0..3e1d202f 100644 --- a/src/workers/Worker.h +++ b/src/backend/common/Worker.h @@ -31,7 +31,7 @@ #include -#include "interfaces/IWorker.h" +#include "backend/common/interfaces/IWorker.h" #include "Mem.h" diff --git a/src/core/WorkerJob.h b/src/backend/common/WorkerJob.h similarity index 100% rename from src/core/WorkerJob.h rename to src/backend/common/WorkerJob.h diff --git a/src/backend/common/common.cmake b/src/backend/common/common.cmake new file mode 100644 index 00000000..e7caa593 --- /dev/null +++ b/src/backend/common/common.cmake @@ -0,0 +1,12 @@ +set(HEADERS_BACKEND_COMMON + src/backend/common/interfaces/IThread.h + src/backend/common/interfaces/IWorker.h + src/backend/common/Threads.h + src/backend/common/Worker.h + src/backend/common/WorkerJob.h + ) + +set(SOURCES_BACKEND_COMMON + src/backend/common/Threads.cpp + src/backend/common/Worker.cpp + ) diff --git a/src/interfaces/IThread.h b/src/backend/common/interfaces/IThread.h similarity index 100% rename from src/interfaces/IThread.h rename to src/backend/common/interfaces/IThread.h diff --git a/src/interfaces/IWorker.h b/src/backend/common/interfaces/IWorker.h similarity index 100% rename from src/interfaces/IWorker.h rename to src/backend/common/interfaces/IWorker.h diff --git a/src/backend/cpu/CpuConfig.h b/src/backend/cpu/CpuConfig.h index 66da3a5f..88222ab1 100644 --- a/src/backend/cpu/CpuConfig.h +++ b/src/backend/cpu/CpuConfig.h @@ -26,8 +26,8 @@ #define XMRIG_CPUCONFIG_H +#include "backend/common/Threads.h" #include "backend/cpu/CpuThread.h" -#include "backend/Threads.h" #include "crypto/common/Assembly.h" diff --git a/src/workers/MultiWorker.cpp b/src/backend/cpu/CpuWorker.cpp similarity index 90% rename from src/workers/MultiWorker.cpp rename to src/backend/cpu/CpuWorker.cpp index 1f06455a..fc98048d 100644 --- a/src/workers/MultiWorker.cpp +++ b/src/backend/cpu/CpuWorker.cpp @@ -27,13 +27,13 @@ #include +#include "backend/cpu/CpuWorker.h" #include "crypto/cn/CryptoNight_test.h" #include "crypto/common/Nonce.h" #include "crypto/rx/Rx.h" #include "crypto/rx/RxVm.h" #include "net/JobResults.h" #include "workers/CpuThreadLegacy.h" -#include "workers/MultiWorker.h" #include "workers/Workers.h" @@ -45,7 +45,7 @@ static constexpr uint32_t kReserveCount = 4096; template -xmrig::MultiWorker::MultiWorker(ThreadHandle *handle) +xmrig::CpuWorker::CpuWorker(ThreadHandle *handle) : Worker(handle) { if (m_thread->algorithm().family() != Algorithm::RANDOM_X) { @@ -55,7 +55,7 @@ xmrig::MultiWorker::MultiWorker(ThreadHandle *handle) template -xmrig::MultiWorker::~MultiWorker() +xmrig::CpuWorker::~CpuWorker() { Mem::release(m_ctx, N, m_memory); @@ -67,7 +67,7 @@ xmrig::MultiWorker::~MultiWorker() #ifdef XMRIG_ALGO_RANDOMX template -void xmrig::MultiWorker::allocateRandomX_VM() +void xmrig::CpuWorker::allocateRandomX_VM() { if (!m_vm) { RxDataset *dataset = Rx::dataset(m_job.currentJob().seedHash(), m_job.currentJob().algorithm()); @@ -78,7 +78,7 @@ void xmrig::MultiWorker::allocateRandomX_VM() template -bool xmrig::MultiWorker::selfTest() +bool xmrig::CpuWorker::selfTest() { if (m_thread->algorithm().family() == Algorithm::CN) { const bool rc = verify(Algorithm::CN_0, test_output_v0) && @@ -137,7 +137,7 @@ bool xmrig::MultiWorker::selfTest() template -void xmrig::MultiWorker::start() +void xmrig::CpuWorker::start() { while (Nonce::sequence() > 0) { if (Workers::isPaused()) { @@ -189,7 +189,7 @@ void xmrig::MultiWorker::start() template -bool xmrig::MultiWorker::verify(const Algorithm &algorithm, const uint8_t *referenceValue) +bool xmrig::CpuWorker::verify(const Algorithm &algorithm, const uint8_t *referenceValue) { cn_hash_fun func = m_thread->fn(algorithm); if (!func) { @@ -202,7 +202,7 @@ bool xmrig::MultiWorker::verify(const Algorithm &algorithm, const uint8_t *re template -bool xmrig::MultiWorker::verify2(const Algorithm &algorithm, const uint8_t *referenceValue) +bool xmrig::CpuWorker::verify2(const Algorithm &algorithm, const uint8_t *referenceValue) { cn_hash_fun func = m_thread->fn(algorithm); if (!func) { @@ -231,7 +231,7 @@ bool xmrig::MultiWorker::verify2(const Algorithm &algorithm, const uint8_t *r namespace xmrig { template<> -bool MultiWorker<1>::verify2(const Algorithm &algorithm, const uint8_t *referenceValue) +bool CpuWorker<1>::verify2(const Algorithm &algorithm, const uint8_t *referenceValue) { cn_hash_fun func = m_thread->fn(algorithm); if (!func) { @@ -253,7 +253,7 @@ bool MultiWorker<1>::verify2(const Algorithm &algorithm, const uint8_t *referenc template -void xmrig::MultiWorker::consumeJob() +void xmrig::CpuWorker::consumeJob() { m_job.add(Workers::job(), Nonce::sequence(), kReserveCount); } @@ -261,11 +261,11 @@ void xmrig::MultiWorker::consumeJob() namespace xmrig { -template class MultiWorker<1>; -template class MultiWorker<2>; -template class MultiWorker<3>; -template class MultiWorker<4>; -template class MultiWorker<5>; +template class CpuWorker<1>; +template class CpuWorker<2>; +template class CpuWorker<3>; +template class CpuWorker<4>; +template class CpuWorker<5>; } // namespace xmrig diff --git a/src/workers/MultiWorker.h b/src/backend/cpu/CpuWorker.h similarity index 78% rename from src/workers/MultiWorker.h rename to src/backend/cpu/CpuWorker.h index 2bcb2333..7e878b54 100644 --- a/src/workers/MultiWorker.h +++ b/src/backend/cpu/CpuWorker.h @@ -23,15 +23,15 @@ * along with this program. If not, see . */ -#ifndef XMRIG_MULTIWORKER_H -#define XMRIG_MULTIWORKER_H +#ifndef XMRIG_CPUWORKER_H +#define XMRIG_CPUWORKER_H +#include "backend/common/WorkerJob.h" #include "base/net/stratum/Job.h" -#include "core/WorkerJob.h" #include "Mem.h" #include "net/JobResult.h" -#include "workers/Worker.h" +#include "backend/common/Worker.h" namespace xmrig { @@ -41,11 +41,11 @@ class RxVm; template -class MultiWorker : public Worker +class CpuWorker : public Worker { public: - MultiWorker(ThreadHandle *handle); - ~MultiWorker(); + CpuWorker(ThreadHandle *handle); + ~CpuWorker() override; protected: bool selfTest() override; @@ -71,7 +71,18 @@ private: }; +template<> +bool CpuWorker<1>::verify2(const Algorithm &algorithm, const uint8_t *referenceValue); + + +extern template class CpuWorker<1>; +extern template class CpuWorker<2>; +extern template class CpuWorker<3>; +extern template class CpuWorker<4>; +extern template class CpuWorker<5>; + + } // namespace xmrig -#endif /* XMRIG_MULTIWORKER_H */ +#endif /* XMRIG_CPUWORKER_H */ diff --git a/src/backend/cpu/cpu.cmake b/src/backend/cpu/cpu.cmake index df9b7cea..3e15a9fd 100644 --- a/src/backend/cpu/cpu.cmake +++ b/src/backend/cpu/cpu.cmake @@ -1,14 +1,16 @@ -set(HEADERS_CPU - src/backend/cpu/Cpu.h - src/backend/cpu/CpuConfig.h +set(HEADERS_BACKEND_CPU + src/backend/cpu/Cpu.h + src/backend/cpu/CpuConfig.h src/backend/cpu/CpuThread.h - src/backend/cpu/interfaces/ICpuInfo.h + src/backend/cpu/CpuWorker.h + src/backend/cpu/interfaces/ICpuInfo.h ) -set(SOURCES_CPU +set(SOURCES_BACKEND_CPU src/backend/cpu/Cpu.cpp src/backend/cpu/CpuConfig.cpp src/backend/cpu/CpuThread.cpp + src/backend/cpu/CpuWorker.cpp ) diff --git a/src/workers/CpuThreadLegacy.h b/src/workers/CpuThreadLegacy.h index 4553295c..b803a8c4 100644 --- a/src/workers/CpuThreadLegacy.h +++ b/src/workers/CpuThreadLegacy.h @@ -26,8 +26,8 @@ #define XMRIG_CPUTHREADLEGACY_H +#include "backend/common/interfaces/IThread.h" #include "crypto/cn/CnHash.h" -#include "interfaces/IThread.h" struct cryptonight_ctx; diff --git a/src/workers/ThreadHandle.h b/src/workers/ThreadHandle.h index c32aabf0..aedb4907 100644 --- a/src/workers/ThreadHandle.h +++ b/src/workers/ThreadHandle.h @@ -31,7 +31,7 @@ #include -#include "interfaces/IThread.h" +#include "backend/common/interfaces/IThread.h" class IWorker; diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index 53a8b712..b43546cd 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -28,6 +28,7 @@ #include "api/Api.h" +#include "backend/cpu/CpuWorker.h" #include "base/io/log/Log.h" #include "base/tools/Chrono.h" #include "base/tools/Handle.h" @@ -37,11 +38,9 @@ #include "crypto/rx/RxAlgo.h" #include "crypto/rx/RxCache.h" #include "crypto/rx/RxDataset.h" -#include "interfaces/IThread.h" #include "Mem.h" #include "rapidjson/document.h" #include "workers/Hashrate.h" -#include "workers/MultiWorker.h" #include "workers/ThreadHandle.h" #include "workers/Workers.h" @@ -250,26 +249,23 @@ void Workers::onReady(void *arg) switch (handle->config()->multiway()) { case 1: - worker = new xmrig::MultiWorker<1>(handle); + worker = new xmrig::CpuWorker<1>(handle); break; case 2: - worker = new xmrig::MultiWorker<2>(handle); + worker = new xmrig::CpuWorker<2>(handle); break; case 3: - worker = new xmrig::MultiWorker<3>(handle); + worker = new xmrig::CpuWorker<3>(handle); break; case 4: - worker = new xmrig::MultiWorker<4>(handle); + worker = new xmrig::CpuWorker<4>(handle); break; case 5: - worker = new xmrig::MultiWorker<5>(handle); - break; - - default: + worker = new xmrig::CpuWorker<5>(handle); break; } From dff59fabc241fc1612b614200a0db030000245cc Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 14 Jul 2019 00:35:38 +0700 Subject: [PATCH 25/48] Removed CPU specific code from Worker class. --- src/backend/common/Worker.cpp | 27 ++++++++------------------- src/backend/common/Worker.h | 14 ++++---------- src/backend/cpu/CpuWorker.cpp | 6 ++++-- src/backend/cpu/CpuWorker.h | 9 ++++++++- src/base/tools/Chrono.h | 8 ++++++++ src/workers/Hashrate.cpp | 13 ++++--------- src/workers/Workers.cpp | 6 +++--- 7 files changed, 39 insertions(+), 44 deletions(-) diff --git a/src/backend/common/Worker.cpp b/src/backend/common/Worker.cpp index f0457bbb..98da61d4 100644 --- a/src/backend/common/Worker.cpp +++ b/src/backend/common/Worker.cpp @@ -23,36 +23,25 @@ * along with this program. If not, see . */ -#include - #include "backend/common/Worker.h" -#include "backend/cpu/Cpu.h" #include "base/kernel/Platform.h" -#include "workers/CpuThreadLegacy.h" -#include "workers/ThreadHandle.h" +#include "base/tools/Chrono.h" -Worker::Worker(ThreadHandle *handle) : - m_id(handle->threadId()), +xmrig::Worker::Worker(size_t id, int64_t affinity, int priority) : + m_id(id), m_hashCount(0), m_timestamp(0), - m_count(0), - m_thread(static_cast(handle->config())) + m_count(0) { - if (xmrig::Cpu::info()->threads() > 1 && m_thread->affinity() != -1L) { - Platform::setThreadAffinity(m_thread->affinity()); - } - - Platform::setThreadPriority(m_thread->priority()); + Platform::trySetThreadAffinity(affinity); + Platform::setThreadPriority(priority); } -void Worker::storeStats() +void xmrig::Worker::storeStats() { - using namespace std::chrono; - - const uint64_t timestamp = time_point_cast(high_resolution_clock::now()).time_since_epoch().count(); m_hashCount.store(m_count, std::memory_order_relaxed); - m_timestamp.store(timestamp, std::memory_order_relaxed); + m_timestamp.store(Chrono::highResolutionMSecs(), std::memory_order_relaxed); } diff --git a/src/backend/common/Worker.h b/src/backend/common/Worker.h index 3e1d202f..3223a60c 100644 --- a/src/backend/common/Worker.h +++ b/src/backend/common/Worker.h @@ -32,23 +32,16 @@ #include "backend/common/interfaces/IWorker.h" -#include "Mem.h" - - -class ThreadHandle; namespace xmrig { - class CpuThreadLegacy; -} class Worker : public IWorker { public: - Worker(ThreadHandle *handle); + Worker(size_t id, int64_t affinity, int priority); - inline const MemInfo &memory() const { return m_memory; } inline size_t id() const override { return m_id; } inline uint64_t hashCount() const override { return m_hashCount.load(std::memory_order_relaxed); } inline uint64_t timestamp() const override { return m_timestamp.load(std::memory_order_relaxed); } @@ -57,12 +50,13 @@ protected: void storeStats(); const size_t m_id; - MemInfo m_memory; std::atomic m_hashCount; std::atomic m_timestamp; uint64_t m_count; - xmrig::CpuThreadLegacy *m_thread; }; +} // namespace xmrig + + #endif /* XMRIG_WORKER_H */ diff --git a/src/backend/cpu/CpuWorker.cpp b/src/backend/cpu/CpuWorker.cpp index fc98048d..e8aa2e3e 100644 --- a/src/backend/cpu/CpuWorker.cpp +++ b/src/backend/cpu/CpuWorker.cpp @@ -34,6 +34,7 @@ #include "crypto/rx/RxVm.h" #include "net/JobResults.h" #include "workers/CpuThreadLegacy.h" +#include "workers/ThreadHandle.h" #include "workers/Workers.h" @@ -45,8 +46,9 @@ static constexpr uint32_t kReserveCount = 4096; template -xmrig::CpuWorker::CpuWorker(ThreadHandle *handle) - : Worker(handle) +xmrig::CpuWorker::CpuWorker(ThreadHandle *handle) : + Worker(handle->threadId(), handle->config()->affinity(), handle->config()->priority()), + m_thread(static_cast(handle->config())) { if (m_thread->algorithm().family() != Algorithm::RANDOM_X) { m_memory = Mem::create(m_ctx, m_thread->algorithm(), N); diff --git a/src/backend/cpu/CpuWorker.h b/src/backend/cpu/CpuWorker.h index 7e878b54..b9adf0f1 100644 --- a/src/backend/cpu/CpuWorker.h +++ b/src/backend/cpu/CpuWorker.h @@ -34,9 +34,13 @@ #include "backend/common/Worker.h" +class ThreadHandle; + + namespace xmrig { +class CpuThreadLegacy; class RxVm; @@ -47,6 +51,8 @@ public: CpuWorker(ThreadHandle *handle); ~CpuWorker() override; + inline const MemInfo &memory() const { return m_memory; } + protected: bool selfTest() override; void start() override; @@ -60,9 +66,10 @@ private: bool verify2(const Algorithm &algorithm, const uint8_t *referenceValue); void consumeJob(); + CpuThreadLegacy *m_thread; cryptonight_ctx *m_ctx[N]; + MemInfo m_memory; uint8_t m_hash[N * 32]; - WorkerJob m_job; # ifdef XMRIG_ALGO_RANDOMX diff --git a/src/base/tools/Chrono.h b/src/base/tools/Chrono.h index d3c14602..e464f361 100644 --- a/src/base/tools/Chrono.h +++ b/src/base/tools/Chrono.h @@ -35,6 +35,14 @@ namespace xmrig { class Chrono { public: + static inline uint64_t highResolutionMSecs() + { + using namespace std::chrono; + + return static_cast(time_point_cast(high_resolution_clock::now()).time_since_epoch().count()); + } + + static inline uint64_t steadyMSecs() { using namespace std::chrono; diff --git a/src/workers/Hashrate.cpp b/src/workers/Hashrate.cpp index 568817cd..0a683caa 100644 --- a/src/workers/Hashrate.cpp +++ b/src/workers/Hashrate.cpp @@ -24,13 +24,13 @@ #include -#include #include #include #include #include "base/io/log/Log.h" +#include "base/tools/Chrono.h" #include "base/tools/Handle.h" #include "core/config/Config.h" #include "core/Controller.h" @@ -98,9 +98,6 @@ double Hashrate::calc(size_t threadId, size_t ms) const return nan(""); } - using namespace std::chrono; - const uint64_t now = time_point_cast(high_resolution_clock::now()).time_since_epoch().count(); - uint64_t earliestHashCount = 0; uint64_t earliestStamp = 0; uint64_t lastestStamp = 0; @@ -119,7 +116,7 @@ double Hashrate::calc(size_t threadId, size_t ms) const lastestHashCnt = m_counts[threadId][idx]; } - if (now - m_timestamps[threadId][idx] > ms) { + if (xmrig::Chrono::highResolutionMSecs() - m_timestamps[threadId][idx] > ms) { haveFullSet = true; break; } @@ -136,10 +133,8 @@ double Hashrate::calc(size_t threadId, size_t ms) const return nan(""); } - double hashes, time; - hashes = (double) lastestHashCnt - earliestHashCount; - time = (double) lastestStamp - earliestStamp; - time /= 1000.0; + const double hashes = static_cast(lastestHashCnt - earliestHashCount); + const double time = static_cast(lastestStamp - earliestStamp) / 1000.0; return hashes / time; } diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp index b43546cd..78954d8f 100644 --- a/src/workers/Workers.cpp +++ b/src/workers/Workers.cpp @@ -299,12 +299,12 @@ void Workers::onTick(uv_timer_t *) void Workers::start(IWorker *worker) { - const Worker *w = static_cast(worker); +// const Worker *w = static_cast(worker); uv_mutex_lock(&m_mutex); m_status.started++; - m_status.pages += w->memory().pages; - m_status.hugePages += w->memory().hugePages; +// m_status.pages += w->memory().pages; +// m_status.hugePages += w->memory().hugePages; if (m_status.started == m_status.threads) { const double percent = (double) m_status.hugePages / m_status.pages * 100.0; From 27f3008d791f53397281557bda3c696088a33ffd Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 16 Jul 2019 22:10:50 +0700 Subject: [PATCH 26/48] Added initial support for new style threads launch method. --- CMakeLists.txt | 8 +- src/App.cpp | 17 +- src/api/v1/ApiRouter.cpp | 12 +- src/backend/common/Thread.h | 62 ++++ src/backend/common/WorkerJob.h | 1 - src/backend/common/Workers.cpp | 152 ++++++++ .../common/Workers.h} | 48 ++- src/backend/common/common.cmake | 4 + .../common/interfaces/IBackend.h} | 38 +- src/backend/common/interfaces/IWorker.h | 6 + src/backend/cpu/CpuBackend.cpp | 151 ++++++++ src/backend/cpu/CpuBackend.h | 61 ++++ src/backend/cpu/CpuLaunchData.cpp | 51 +++ src/backend/cpu/CpuLaunchData.h | 67 ++++ src/backend/cpu/CpuThread.h | 16 +- src/backend/cpu/CpuWorker.cpp | 56 +-- src/backend/cpu/CpuWorker.h | 17 +- src/backend/cpu/cpu.cmake | 4 + src/base/io/log/Log.h | 82 ++--- src/core/Controller.cpp | 19 +- src/core/Controller.h | 6 +- src/core/Miner.cpp | 215 ++++++++++++ src/core/Miner.h | 65 ++++ src/crypto/cn/CnHash.cpp | 9 +- src/crypto/cn/CnHash.h | 2 +- src/crypto/common/Nonce.cpp | 29 +- src/crypto/common/Nonce.h | 23 +- src/net/Network.cpp | 8 +- src/workers/CpuThreadLegacy.cpp | 6 +- src/workers/Workers.cpp | 330 ----------------- src/workers/WorkersLegacy.cpp | 331 ++++++++++++++++++ src/workers/{Workers.h => WorkersLegacy.h} | 38 +- 32 files changed, 1429 insertions(+), 505 deletions(-) create mode 100644 src/backend/common/Thread.h create mode 100644 src/backend/common/Workers.cpp rename src/{workers/ThreadHandle.h => backend/common/Workers.h} (64%) rename src/{workers/ThreadHandle.cpp => backend/common/interfaces/IBackend.h} (71%) create mode 100644 src/backend/cpu/CpuBackend.cpp create mode 100644 src/backend/cpu/CpuBackend.h create mode 100644 src/backend/cpu/CpuLaunchData.cpp create mode 100644 src/backend/cpu/CpuLaunchData.h create mode 100644 src/core/Miner.cpp create mode 100644 src/core/Miner.h delete mode 100644 src/workers/Workers.cpp create mode 100644 src/workers/WorkersLegacy.cpp rename src/workers/{Workers.h => WorkersLegacy.h} (76%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8291f606..8749a003 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,6 +33,7 @@ set(HEADERS src/core/config/ConfigTransform.h src/core/config/usage.h src/core/Controller.h + src/core/Miner.h src/Mem.h src/net/interfaces/IJobResultListener.h src/net/JobResult.h @@ -44,8 +45,7 @@ set(HEADERS src/version.h src/workers/CpuThreadLegacy.h src/workers/Hashrate.h - src/workers/ThreadHandle.h - src/workers/Workers.h + src/workers/WorkersLegacy.h ) set(HEADERS_CRYPTO @@ -84,6 +84,7 @@ set(SOURCES src/core/config/Config.cpp src/core/config/ConfigTransform.cpp src/core/Controller.cpp + src/core/Miner.cpp src/Mem.cpp src/net/JobResults.cpp src/net/Network.cpp @@ -92,8 +93,7 @@ set(SOURCES src/Summary.cpp src/workers/CpuThreadLegacy.cpp src/workers/Hashrate.cpp - src/workers/ThreadHandle.cpp - src/workers/Workers.cpp + src/workers/WorkersLegacy.cpp src/xmrig.cpp ) diff --git a/src/App.cpp b/src/App.cpp index 5b2178ac..d6c39595 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -36,11 +36,11 @@ #include "base/kernel/Signals.h" #include "core/config/Config.h" #include "core/Controller.h" +#include "core/Miner.h" #include "Mem.h" #include "net/Network.h" #include "Summary.h" #include "version.h" -#include "workers/Workers.h" xmrig::App::App(Process *process) : @@ -86,8 +86,6 @@ int xmrig::App::exec() return 0; } - Workers::start(m_controller); - m_controller->start(); const int r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); @@ -102,23 +100,17 @@ void xmrig::App::onConsoleCommand(char command) switch (command) { case 'h': case 'H': - Workers::printHashrate(true); + m_controller->miner()->printHashrate(true); break; case 'p': case 'P': - if (Workers::isEnabled()) { - LOG_INFO(YELLOW_BOLD("paused") ", press " MAGENTA_BOLD("r") " to resume"); - Workers::setEnabled(false); - } + m_controller->miner()->setEnabled(false); break; case 'r': case 'R': - if (!Workers::isEnabled()) { - LOG_INFO(GREEN_BOLD("resumed")); - Workers::setEnabled(true); - } + m_controller->miner()->setEnabled(true); break; case 3: @@ -162,6 +154,5 @@ void xmrig::App::close() m_console->stop(); m_controller->stop(); - Workers::stop(); Log::destroy(); } diff --git a/src/api/v1/ApiRouter.cpp b/src/api/v1/ApiRouter.cpp index 5ed94c4b..9e609d13 100644 --- a/src/api/v1/ApiRouter.cpp +++ b/src/api/v1/ApiRouter.cpp @@ -37,7 +37,7 @@ #include "rapidjson/document.h" #include "version.h" #include "workers/Hashrate.h" -#include "workers/Workers.h" +#include "workers/WorkersLegacy.h" static inline rapidjson::Value normalize(double d) @@ -107,13 +107,13 @@ void xmrig::ApiRouter::getHashrate(rapidjson::Value &reply, rapidjson::Document Value total(kArrayType); Value threads(kArrayType); - const Hashrate *hr = Workers::hashrate(); + const Hashrate *hr = WorkersLegacy::hashrate(); total.PushBack(normalize(hr->calc(Hashrate::ShortInterval)), allocator); total.PushBack(normalize(hr->calc(Hashrate::MediumInterval)), allocator); total.PushBack(normalize(hr->calc(Hashrate::LargeInterval)), allocator); - for (size_t i = 0; i < Workers::threads(); i++) { + for (size_t i = 0; i < WorkersLegacy::threads(); i++) { Value thread(kArrayType); thread.PushBack(normalize(hr->calc(i, Hashrate::ShortInterval)), allocator); thread.PushBack(normalize(hr->calc(i, Hashrate::MediumInterval)), allocator); @@ -144,7 +144,7 @@ void xmrig::ApiRouter::getMiner(rapidjson::Value &reply, rapidjson::Document &do reply.AddMember("kind", APP_KIND, allocator); reply.AddMember("ua", StringRef(Platform::userAgent()), allocator); reply.AddMember("cpu", cpu, allocator); - reply.AddMember("hugepages", Workers::hugePages() > 0, allocator); + reply.AddMember("hugepages", WorkersLegacy::hugePages() > 0, allocator); reply.AddMember("donate_level", m_base->config()->pools().donateLevel(), allocator); } @@ -153,9 +153,9 @@ void xmrig::ApiRouter::getThreads(rapidjson::Value &reply, rapidjson::Document & { using namespace rapidjson; auto &allocator = doc.GetAllocator(); - const Hashrate *hr = Workers::hashrate(); + const Hashrate *hr = WorkersLegacy::hashrate(); - Workers::threadsSummary(doc); + WorkersLegacy::threadsSummary(doc); const std::vector &threads = m_base->config()->threads(); Value list(kArrayType); diff --git a/src/backend/common/Thread.h b/src/backend/common/Thread.h new file mode 100644 index 00000000..f1d174ec --- /dev/null +++ b/src/backend/common/Thread.h @@ -0,0 +1,62 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_THREAD_H +#define XMRIG_THREAD_H + + +#include + + +namespace xmrig { + + +class IWorker; + + +template +class Thread +{ +public: + inline Thread(size_t index, const T &config) : m_index(index), m_config(config) {} + inline ~Thread() { uv_thread_join(&m_thread); } + + inline const T &config() const { return m_config; } + inline IWorker *worker() const { return m_worker; } + inline size_t index() const { return m_index; } + inline void setWorker(IWorker *worker) { m_worker = worker; } + inline void start(void (*callback) (void *)) { uv_thread_create(&m_thread, callback, this); } + +private: + const size_t m_index = 0; + const T m_config; + IWorker *m_worker = nullptr; + uv_thread_t m_thread; +}; + + +} // namespace xmrig + + +#endif /* XMRIG_THREAD_H */ diff --git a/src/backend/common/WorkerJob.h b/src/backend/common/WorkerJob.h index 7b598ee6..c9a3d55c 100644 --- a/src/backend/common/WorkerJob.h +++ b/src/backend/common/WorkerJob.h @@ -26,7 +26,6 @@ #define XMRIG_WORKERJOB_H -#include #include diff --git a/src/backend/common/Workers.cpp b/src/backend/common/Workers.cpp new file mode 100644 index 00000000..987ca526 --- /dev/null +++ b/src/backend/common/Workers.cpp @@ -0,0 +1,152 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018 Lee Clagett + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "backend/common/Workers.h" +#include "backend/cpu/CpuWorker.h" +#include "base/io/log/Log.h" + + +namespace xmrig { + + +class WorkersPrivate +{ +public: + inline WorkersPrivate() + { + + } + + + inline ~WorkersPrivate() + { + } +}; + + +} // namespace xmrig + + +template +xmrig::Workers::Workers() : + d_ptr(new WorkersPrivate()) +{ + +} + + +template +xmrig::Workers::~Workers() +{ + delete d_ptr; +} + + +template +void xmrig::Workers::add(const T &data) +{ + m_workers.push_back(new Thread(m_workers.size(), data)); +} + + +template +void xmrig::Workers::start() +{ + for (Thread *worker : m_workers) { + worker->start(Workers::onReady); + } +} + + +template +void xmrig::Workers::stop() +{ + Nonce::stop(T::backend()); + + for (Thread *worker : m_workers) { + delete worker; + } + + m_workers.clear(); + Nonce::touch(T::backend()); +} + + +template +void xmrig::Workers::onReady(void *arg) +{ + printf("ON READY\n"); +} + + +namespace xmrig { + + +template<> +void xmrig::Workers::onReady(void *arg) +{ + auto handle = static_cast* >(arg); + + IWorker *worker = nullptr; + + switch (handle->config().intensity) { + case 1: + worker = new CpuWorker<1>(handle->index(), handle->config()); + break; + + case 2: + worker = new CpuWorker<2>(handle->index(), handle->config()); + break; + + case 3: + worker = new CpuWorker<3>(handle->index(), handle->config()); + break; + + case 4: + worker = new CpuWorker<4>(handle->index(), handle->config()); + break; + + case 5: + worker = new CpuWorker<5>(handle->index(), handle->config()); + break; + } + + handle->setWorker(worker); + + if (!worker->selfTest()) { + LOG_ERR("thread %zu error: \"hash self-test failed\".", handle->worker()->id()); + + return; + } + + worker->start(); +} + + +template class Workers; + + +} // namespace xmrig diff --git a/src/workers/ThreadHandle.h b/src/backend/common/Workers.h similarity index 64% rename from src/workers/ThreadHandle.h rename to src/backend/common/Workers.h index aedb4907..25f81c5b 100644 --- a/src/workers/ThreadHandle.h +++ b/src/backend/common/Workers.h @@ -5,6 +5,7 @@ * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , + * Copyright 2018 Lee Clagett * Copyright 2018-2019 SChernykh * Copyright 2016-2019 XMRig , * @@ -22,38 +23,47 @@ * along with this program. If not, see . */ -#ifndef XMRIG_THREADHANDLE_H -#define XMRIG_THREADHANDLE_H +#ifndef XMRIG_WORKERS_H +#define XMRIG_WORKERS_H -#include -#include -#include +#include "backend/common/Thread.h" +#include "backend/cpu/CpuLaunchData.h" -#include "backend/common/interfaces/IThread.h" +namespace xmrig { -class IWorker; +class WorkersPrivate; -class ThreadHandle +template +class Workers { public: - ThreadHandle(xmrig::IThread *config); - void join(); - void start(void (*callback) (void *)); + Workers(); + ~Workers(); - inline IWorker *worker() const { return m_worker; } - inline size_t threadId() const { return m_config->index(); } - inline void setWorker(IWorker *worker) { assert(worker != nullptr); m_worker = worker; } - inline xmrig::IThread *config() const { return m_config; } + void add(const T &data); + void start(); + void stop(); private: - IWorker *m_worker; - uv_thread_t m_thread; - xmrig::IThread *m_config; + static void onReady(void *arg); + + std::vector *> m_workers; + WorkersPrivate *d_ptr; }; -#endif /* XMRIG_THREADHANDLE_H */ +template<> +void Workers::onReady(void *arg); + + +extern template class Workers; + + +} // namespace xmrig + + +#endif /* XMRIG_WORKERS_H */ diff --git a/src/backend/common/common.cmake b/src/backend/common/common.cmake index e7caa593..bb84af58 100644 --- a/src/backend/common/common.cmake +++ b/src/backend/common/common.cmake @@ -1,12 +1,16 @@ set(HEADERS_BACKEND_COMMON + src/backend/common/interfaces/IBackend.h src/backend/common/interfaces/IThread.h src/backend/common/interfaces/IWorker.h + src/backend/common/Thread.h src/backend/common/Threads.h src/backend/common/Worker.h + src/backend/common/Workers.h src/backend/common/WorkerJob.h ) set(SOURCES_BACKEND_COMMON src/backend/common/Threads.cpp src/backend/common/Worker.cpp + src/backend/common/Workers.cpp ) diff --git a/src/workers/ThreadHandle.cpp b/src/backend/common/interfaces/IBackend.h similarity index 71% rename from src/workers/ThreadHandle.cpp rename to src/backend/common/interfaces/IBackend.h index ced5f326..d6fe1695 100644 --- a/src/workers/ThreadHandle.cpp +++ b/src/backend/common/interfaces/IBackend.h @@ -22,24 +22,34 @@ * along with this program. If not, see . */ - -#include "workers/ThreadHandle.h" +#ifndef XMRIG_IBACKEND_H +#define XMRIG_IBACKEND_H -ThreadHandle::ThreadHandle(xmrig::IThread *config) : - m_worker(nullptr), - m_config(config) +#include + + +namespace xmrig { + + +class Job; +class String; + + +class IBackend { -} +public: + virtual ~IBackend() = default; + + virtual const String &profileName() const = 0; + virtual void printHashrate(bool details) = 0; + virtual void setJob(const Job &job) = 0; + virtual void stop() = 0; + virtual void tick(uint64_t ticks) = 0; +}; -void ThreadHandle::join() -{ - uv_thread_join(&m_thread); -} +} // namespace xmrig -void ThreadHandle::start(void (*callback) (void *)) -{ - uv_thread_create(&m_thread, callback, this); -} +#endif // XMRIG_IBACKEND_H diff --git a/src/backend/common/interfaces/IWorker.h b/src/backend/common/interfaces/IWorker.h index 83e9306e..de22de02 100644 --- a/src/backend/common/interfaces/IWorker.h +++ b/src/backend/common/interfaces/IWorker.h @@ -29,6 +29,9 @@ #include +namespace xmrig { + + class IWorker { public: @@ -42,4 +45,7 @@ public: }; +} // namespace xmrig + + #endif // XMRIG_IWORKER_H diff --git a/src/backend/cpu/CpuBackend.cpp b/src/backend/cpu/CpuBackend.cpp new file mode 100644 index 00000000..a1ae5747 --- /dev/null +++ b/src/backend/cpu/CpuBackend.cpp @@ -0,0 +1,151 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "backend/common/Workers.h" +#include "backend/cpu/CpuBackend.h" +#include "base/net/stratum/Job.h" +#include "base/tools/String.h" +#include "core/config/Config.h" +#include "core/Controller.h" + + +#include "base/io/log/Log.h" + + +namespace xmrig { + + +extern template class Threads; + + +class CpuBackendPrivate +{ +public: + inline CpuBackendPrivate(const Miner *miner, Controller *controller) : + miner(miner), + controller(controller) + { + } + + + inline ~CpuBackendPrivate() + { + } + + + inline bool isReady(const Algorithm &nextAlgo) const + { + if (!algo.isValid()) { + return false; + } + + if (nextAlgo == algo) { + return true; + } + + const CpuThreads &nextThreads = controller->config()->cpu().threads().get(nextAlgo); + + return algo.memory() == nextAlgo.memory() + && threads.size() == nextThreads.size() + && std::equal(threads.begin(), threads.end(), nextThreads.begin()); + } + + + Algorithm algo; + const Miner *miner; + Controller *controller; + CpuThreads threads; + String profileName; + Workers workers; +}; + + +} // namespace xmrig + + +xmrig::CpuBackend::CpuBackend(const Miner *miner, Controller *controller) : + d_ptr(new CpuBackendPrivate(miner, controller)) +{ + +} + + +xmrig::CpuBackend::~CpuBackend() +{ + delete d_ptr; +} + + +const xmrig::String &xmrig::CpuBackend::profileName() const +{ + return d_ptr->profileName; +} + + +void xmrig::CpuBackend::printHashrate(bool details) +{ + +} + + +void xmrig::CpuBackend::setJob(const Job &job) +{ + LOG_WARN("PROFILE %s %zu", d_ptr->controller->config()->cpu().threads().profileName(job.algorithm()).data(), job.algorithm().memory()); + + if (d_ptr->isReady(job.algorithm())) { + return; + } + + LOG_INFO(GREEN_BOLD_S "INIT"); + + const CpuConfig &cpu = d_ptr->controller->config()->cpu(); + const Threads &threads = cpu.threads(); + + d_ptr->algo = job.algorithm(); + d_ptr->profileName = threads.profileName(job.algorithm()); + d_ptr->threads = threads.get(d_ptr->profileName); + + LOG_INFO(BLUE_BG_S " %zu ", d_ptr->threads.size()); + + d_ptr->workers.stop(); + + for (const CpuThread &thread : d_ptr->threads) { + d_ptr->workers.add(CpuLaunchData(d_ptr->miner, d_ptr->algo, cpu, thread)); + } + + d_ptr->workers.start(); +} + + +void xmrig::CpuBackend::stop() +{ + d_ptr->workers.stop(); +} + + +void xmrig::CpuBackend::tick(uint64_t ticks) +{ + +} diff --git a/src/backend/cpu/CpuBackend.h b/src/backend/cpu/CpuBackend.h new file mode 100644 index 00000000..d39ab38d --- /dev/null +++ b/src/backend/cpu/CpuBackend.h @@ -0,0 +1,61 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_CPUBACKEND_H +#define XMRIG_CPUBACKEND_H + + +#include "backend/common/interfaces/IBackend.h" + + +namespace xmrig { + + +class Controller; +class CpuBackendPrivate; +class Miner; + + +class CpuBackend : public IBackend +{ +public: + CpuBackend(const Miner *miner, Controller *controller); + ~CpuBackend() override; + +protected: + const String &profileName() const override; + void printHashrate(bool details) override; + void setJob(const Job &job) override; + void stop() override; + void tick(uint64_t ticks) override; + +private: + CpuBackendPrivate *d_ptr; +}; + + +} /* namespace xmrig */ + + +#endif /* XMRIG_CPUBACKEND_H */ diff --git a/src/backend/cpu/CpuLaunchData.cpp b/src/backend/cpu/CpuLaunchData.cpp new file mode 100644 index 00000000..68b8e7ae --- /dev/null +++ b/src/backend/cpu/CpuLaunchData.cpp @@ -0,0 +1,51 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018 Lee Clagett + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "backend/cpu/CpuLaunchData.h" +#include "backend/cpu/CpuConfig.h" + + +xmrig::CpuLaunchData::CpuLaunchData(const Miner *miner, const Algorithm &algorithm, const CpuConfig &config, const CpuThread &thread) : + algorithm(algorithm), + assembly(config.assembly()), + hugePages(config.isHugePages()), + hwAES(config.isHwAES()), + intensity(thread.intensity()), + priority(config.priority()), + affinity(thread.affinity()), + miner(miner) +{ +} + + +xmrig::CnHash::AlgoVariant xmrig::CpuLaunchData::av() const +{ + if (intensity <= 2) { + return static_cast(!hwAES ? (intensity + 2) : intensity); + } + + return static_cast(!hwAES ? (intensity + 5) : (intensity + 2)); +} diff --git a/src/backend/cpu/CpuLaunchData.h b/src/backend/cpu/CpuLaunchData.h new file mode 100644 index 00000000..208a68b7 --- /dev/null +++ b/src/backend/cpu/CpuLaunchData.h @@ -0,0 +1,67 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018 Lee Clagett + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_CPULAUNCHDATA_H +#define XMRIG_CPULAUNCHDATA_H + + +#include "crypto/cn/CnHash.h" +#include "crypto/common/Algorithm.h" +#include "crypto/common/Assembly.h" +#include "crypto/common/Nonce.h" + + +namespace xmrig { + + +class CpuConfig; +class CpuThread; +class Miner; + + +class CpuLaunchData +{ +public: + CpuLaunchData(const Miner *miner, const Algorithm &algorithm, const CpuConfig &config, const CpuThread &thread); + + CnHash::AlgoVariant av() const; + + inline constexpr static Nonce::Backend backend() { return Nonce::CPU; } + + const Algorithm algorithm; + const Assembly assembly; + const bool hugePages; + const bool hwAES; + const int intensity; + const int priority; + const int64_t affinity; + const Miner *miner; +}; + + +} // namespace xmrig + + +#endif /* XMRIG_CPULAUNCHDATA_H */ diff --git a/src/backend/cpu/CpuThread.h b/src/backend/cpu/CpuThread.h index 444b2709..adaffa68 100644 --- a/src/backend/cpu/CpuThread.h +++ b/src/backend/cpu/CpuThread.h @@ -38,19 +38,23 @@ namespace xmrig { class CpuThread { public: - inline constexpr CpuThread(int intensity = 1, int affinity = -1) : m_affinity(affinity), m_intensity(intensity) {} + inline constexpr CpuThread(int intensity = 1, int64_t affinity = -1) : m_intensity(intensity), m_affinity(affinity) {} CpuThread(const rapidjson::Value &value); - inline bool isValid() const { return m_intensity >= 1 && m_intensity <= 5; } - inline int affinity() const { return m_affinity; } - inline int intensity() const { return m_intensity; } + inline bool isEqual(const CpuThread &other) const { return other.m_affinity == m_affinity && other.m_intensity == m_intensity; } + inline bool isValid() const { return m_intensity >= 1 && m_intensity <= 5; } + inline int intensity() const { return m_intensity; } + inline int64_t affinity() const { return m_affinity; } + + inline bool operator!=(const CpuThread &other) const { return !isEqual(other); } + inline bool operator==(const CpuThread &other) const { return isEqual(other); } rapidjson::Value toJSON(rapidjson::Document &doc) const; private: - int m_affinity = -1; - int m_intensity = -1; + int m_intensity = -1; + int64_t m_affinity = -1; }; diff --git a/src/backend/cpu/CpuWorker.cpp b/src/backend/cpu/CpuWorker.cpp index e8aa2e3e..96466252 100644 --- a/src/backend/cpu/CpuWorker.cpp +++ b/src/backend/cpu/CpuWorker.cpp @@ -28,14 +28,17 @@ #include "backend/cpu/CpuWorker.h" +#include "core/Miner.h" #include "crypto/cn/CryptoNight_test.h" #include "crypto/common/Nonce.h" #include "crypto/rx/Rx.h" #include "crypto/rx/RxVm.h" #include "net/JobResults.h" -#include "workers/CpuThreadLegacy.h" -#include "workers/ThreadHandle.h" -#include "workers/Workers.h" + + +#ifdef XMRIG_ALGO_RANDOMX +# include "crypto/randomx/randomx.h" +#endif namespace xmrig { @@ -45,13 +48,18 @@ static constexpr uint32_t kReserveCount = 4096; } // namespace xmrig + template -xmrig::CpuWorker::CpuWorker(ThreadHandle *handle) : - Worker(handle->threadId(), handle->config()->affinity(), handle->config()->priority()), - m_thread(static_cast(handle->config())) +xmrig::CpuWorker::CpuWorker(size_t index, const CpuLaunchData &data) : + Worker(index, data.affinity, data.priority), + m_algorithm(data.algorithm), + m_assembly(data.assembly), + m_hwAES(data.hwAES), + m_av(data.av()), + m_miner(data.miner) { - if (m_thread->algorithm().family() != Algorithm::RANDOM_X) { - m_memory = Mem::create(m_ctx, m_thread->algorithm(), N); + if (m_algorithm.family() != Algorithm::RANDOM_X) { + m_memory = Mem::create(m_ctx, m_algorithm, N); } } @@ -73,7 +81,7 @@ void xmrig::CpuWorker::allocateRandomX_VM() { if (!m_vm) { RxDataset *dataset = Rx::dataset(m_job.currentJob().seedHash(), m_job.currentJob().algorithm()); - m_vm = new RxVm(dataset, true, m_thread->isSoftAES()); + m_vm = new RxVm(dataset, true, !m_hwAES); } } #endif @@ -82,7 +90,7 @@ void xmrig::CpuWorker::allocateRandomX_VM() template bool xmrig::CpuWorker::selfTest() { - if (m_thread->algorithm().family() == Algorithm::CN) { + if (m_algorithm.family() == Algorithm::CN) { const bool rc = verify(Algorithm::CN_0, test_output_v0) && verify(Algorithm::CN_1, test_output_v1) && verify(Algorithm::CN_2, test_output_v2) && @@ -108,14 +116,14 @@ bool xmrig::CpuWorker::selfTest() } # ifdef XMRIG_ALGO_CN_LITE - if (m_thread->algorithm().family() == Algorithm::CN_LITE) { + if (m_algorithm.family() == Algorithm::CN_LITE) { return verify(Algorithm::CN_LITE_0, test_output_v0_lite) && verify(Algorithm::CN_LITE_1, test_output_v1_lite); } # endif # ifdef XMRIG_ALGO_CN_HEAVY - if (m_thread->algorithm().family() == Algorithm::CN_HEAVY) { + if (m_algorithm.family() == Algorithm::CN_HEAVY) { return verify(Algorithm::CN_HEAVY_0, test_output_v0_heavy) && verify(Algorithm::CN_HEAVY_XHV, test_output_xhv_heavy) && verify(Algorithm::CN_HEAVY_TUBE, test_output_tube_heavy); @@ -123,13 +131,13 @@ bool xmrig::CpuWorker::selfTest() # endif # ifdef XMRIG_ALGO_CN_PICO - if (m_thread->algorithm().family() == Algorithm::CN_PICO) { + if (m_algorithm.family() == Algorithm::CN_PICO) { return verify(Algorithm::CN_PICO_0, test_output_pico_trtl); } # endif # ifdef XMRIG_ALGO_RANDOMX - if (m_thread->algorithm().family() == Algorithm::RANDOM_X) { + if (m_algorithm.family() == Algorithm::RANDOM_X) { return true; } # endif @@ -141,21 +149,21 @@ bool xmrig::CpuWorker::selfTest() template void xmrig::CpuWorker::start() { - while (Nonce::sequence() > 0) { - if (Workers::isPaused()) { + while (Nonce::sequence(Nonce::CPU) > 0) { + if (Nonce::isPaused()) { do { std::this_thread::sleep_for(std::chrono::milliseconds(200)); } - while (Workers::isPaused()); + while (Nonce::isPaused()); - if (Nonce::sequence() == 0) { + if (Nonce::sequence(Nonce::CPU) == 0) { break; } consumeJob(); } - while (!Nonce::isOutdated(m_job.sequence())) { + while (!Nonce::isOutdated(Nonce::CPU, m_job.sequence())) { if ((m_count & 0x7) == 0) { storeStats(); } @@ -170,7 +178,7 @@ void xmrig::CpuWorker::start() else # endif { - m_thread->fn(job.algorithm())(m_job.blob(), job.size(), m_hash, m_ctx, job.height()); + fn(job.algorithm())(m_job.blob(), job.size(), m_hash, m_ctx, job.height()); } for (size_t i = 0; i < N; ++i) { @@ -193,7 +201,7 @@ void xmrig::CpuWorker::start() template bool xmrig::CpuWorker::verify(const Algorithm &algorithm, const uint8_t *referenceValue) { - cn_hash_fun func = m_thread->fn(algorithm); + cn_hash_fun func = fn(algorithm); if (!func) { return false; } @@ -206,7 +214,7 @@ bool xmrig::CpuWorker::verify(const Algorithm &algorithm, const uint8_t *refe template bool xmrig::CpuWorker::verify2(const Algorithm &algorithm, const uint8_t *referenceValue) { - cn_hash_fun func = m_thread->fn(algorithm); + cn_hash_fun func = fn(algorithm); if (!func) { return false; } @@ -235,7 +243,7 @@ namespace xmrig { template<> bool CpuWorker<1>::verify2(const Algorithm &algorithm, const uint8_t *referenceValue) { - cn_hash_fun func = m_thread->fn(algorithm); + cn_hash_fun func = fn(algorithm); if (!func) { return false; } @@ -257,7 +265,7 @@ bool CpuWorker<1>::verify2(const Algorithm &algorithm, const uint8_t *referenceV template void xmrig::CpuWorker::consumeJob() { - m_job.add(Workers::job(), Nonce::sequence(), kReserveCount); + m_job.add(m_miner->job(), Nonce::sequence(Nonce::CPU), kReserveCount); } diff --git a/src/backend/cpu/CpuWorker.h b/src/backend/cpu/CpuWorker.h index b9adf0f1..c67d355b 100644 --- a/src/backend/cpu/CpuWorker.h +++ b/src/backend/cpu/CpuWorker.h @@ -27,20 +27,17 @@ #define XMRIG_CPUWORKER_H +#include "backend/common/Worker.h" #include "backend/common/WorkerJob.h" +#include "backend/cpu/CpuLaunchData.h" #include "base/net/stratum/Job.h" #include "Mem.h" #include "net/JobResult.h" -#include "backend/common/Worker.h" - - -class ThreadHandle; namespace xmrig { -class CpuThreadLegacy; class RxVm; @@ -48,7 +45,7 @@ template class CpuWorker : public Worker { public: - CpuWorker(ThreadHandle *handle); + CpuWorker(size_t index, const CpuLaunchData &data); ~CpuWorker() override; inline const MemInfo &memory() const { return m_memory; } @@ -58,6 +55,8 @@ protected: void start() override; private: + inline cn_hash_fun fn(const Algorithm &algorithm) const { return CnHash::fn(algorithm, m_av, m_assembly); } + # ifdef XMRIG_ALGO_RANDOMX void allocateRandomX_VM(); # endif @@ -66,7 +65,11 @@ private: bool verify2(const Algorithm &algorithm, const uint8_t *referenceValue); void consumeJob(); - CpuThreadLegacy *m_thread; + const Algorithm m_algorithm; + const Assembly m_assembly; + const bool m_hwAES; + const CnHash::AlgoVariant m_av; + const Miner *m_miner; cryptonight_ctx *m_ctx[N]; MemInfo m_memory; uint8_t m_hash[N * 32]; diff --git a/src/backend/cpu/cpu.cmake b/src/backend/cpu/cpu.cmake index 3e15a9fd..871debd3 100644 --- a/src/backend/cpu/cpu.cmake +++ b/src/backend/cpu/cpu.cmake @@ -1,6 +1,8 @@ set(HEADERS_BACKEND_CPU src/backend/cpu/Cpu.h + src/backend/cpu/CpuBackend.h src/backend/cpu/CpuConfig.h + src/backend/cpu/CpuLaunchData.cpp src/backend/cpu/CpuThread.h src/backend/cpu/CpuWorker.h src/backend/cpu/interfaces/ICpuInfo.h @@ -8,7 +10,9 @@ set(HEADERS_BACKEND_CPU set(SOURCES_BACKEND_CPU src/backend/cpu/Cpu.cpp + src/backend/cpu/CpuBackend.cpp src/backend/cpu/CpuConfig.cpp + src/backend/cpu/CpuLaunchData.h src/backend/cpu/CpuThread.cpp src/backend/cpu/CpuWorker.cpp ) diff --git a/src/base/io/log/Log.h b/src/base/io/log/Log.h index 962d1dba..078a8546 100644 --- a/src/base/io/log/Log.h +++ b/src/base/io/log/Log.h @@ -61,49 +61,53 @@ private: }; -#define CSI "\x1B[" // Control Sequence Introducer (ANSI spec name) -#define CLEAR CSI "0m" // all attributes off -#define BRIGHT_BLACK_S CSI "0;90m" // somewhat MD.GRAY -#define BLACK_S CSI "0;30m" -#define BLACK_BOLD_S CSI "1;30m" // another name for GRAY -#define RED_S CSI "0;31m" -#define RED_BOLD_S CSI "1;31m" -#define GREEN_S CSI "0;32m" -#define GREEN_BOLD_S CSI "1;32m" -#define YELLOW_S CSI "0;33m" -#define YELLOW_BOLD_S CSI "1;33m" -#define BLUE_S CSI "0;34m" -#define BLUE_BOLD_S CSI "1;34m" -#define MAGENTA_S CSI "0;35m" -#define MAGENTA_BOLD_S CSI "1;35m" -#define CYAN_S CSI "0;36m" -#define CYAN_BOLD_S CSI "1;36m" -#define WHITE_S CSI "0;37m" // another name for LT.GRAY -#define WHITE_BOLD_S CSI "1;37m" // actually white +#define CSI "\x1B[" // Control Sequence Introducer (ANSI spec name) +#define CLEAR CSI "0m" // all attributes off +#define BRIGHT_BLACK_S CSI "0;90m" // somewhat MD.GRAY +#define BLACK_S CSI "0;30m" +#define BLACK_BOLD_S CSI "1;30m" // another name for GRAY +#define RED_S CSI "0;31m" +#define RED_BOLD_S CSI "1;31m" +#define GREEN_S CSI "0;32m" +#define GREEN_BOLD_S CSI "1;32m" +#define YELLOW_S CSI "0;33m" +#define YELLOW_BOLD_S CSI "1;33m" +#define BLUE_S CSI "0;34m" +#define BLUE_BOLD_S CSI "1;34m" +#define MAGENTA_S CSI "0;35m" +#define MAGENTA_BOLD_S CSI "1;35m" +#define CYAN_S CSI "0;36m" +#define CYAN_BOLD_S CSI "1;36m" +#define WHITE_S CSI "0;37m" // another name for LT.GRAY +#define WHITE_BOLD_S CSI "1;37m" // actually white -#define BLUE_BG_S CSI "44m" -#define BLUE_BG_BOLD_S CSI "44;1m" +#define BLUE_BG_S CSI "44m" +#define BLUE_BG_BOLD_S CSI "44;1m" +#define MAGENTA_BG_S CSI "45m" +#define MAGENTA_BG_BOLD_S CSI "45;1m" //color wrappings -#define BLACK(x) BLACK_S x CLEAR -#define BLACK_BOLD(x) BLACK_BOLD_S x CLEAR -#define RED(x) RED_S x CLEAR -#define RED_BOLD(x) RED_BOLD_S x CLEAR -#define GREEN(x) GREEN_S x CLEAR -#define GREEN_BOLD(x) GREEN_BOLD_S x CLEAR -#define YELLOW(x) YELLOW_S x CLEAR -#define YELLOW_BOLD(x) YELLOW_BOLD_S x CLEAR -#define BLUE(x) BLUE_S x CLEAR -#define BLUE_BOLD(x) BLUE_BOLD_S x CLEAR -#define MAGENTA(x) MAGENTA_S x CLEAR -#define MAGENTA_BOLD(x) MAGENTA_BOLD_S x CLEAR -#define CYAN(x) CYAN_S x CLEAR -#define CYAN_BOLD(x) CYAN_BOLD_S x CLEAR -#define WHITE(x) WHITE_S x CLEAR -#define WHITE_BOLD(x) WHITE_BOLD_S x CLEAR +#define BLACK(x) BLACK_S x CLEAR +#define BLACK_BOLD(x) BLACK_BOLD_S x CLEAR +#define RED(x) RED_S x CLEAR +#define RED_BOLD(x) RED_BOLD_S x CLEAR +#define GREEN(x) GREEN_S x CLEAR +#define GREEN_BOLD(x) GREEN_BOLD_S x CLEAR +#define YELLOW(x) YELLOW_S x CLEAR +#define YELLOW_BOLD(x) YELLOW_BOLD_S x CLEAR +#define BLUE(x) BLUE_S x CLEAR +#define BLUE_BOLD(x) BLUE_BOLD_S x CLEAR +#define MAGENTA(x) MAGENTA_S x CLEAR +#define MAGENTA_BOLD(x) MAGENTA_BOLD_S x CLEAR +#define CYAN(x) CYAN_S x CLEAR +#define CYAN_BOLD(x) CYAN_BOLD_S x CLEAR +#define WHITE(x) WHITE_S x CLEAR +#define WHITE_BOLD(x) WHITE_BOLD_S x CLEAR -#define BLUE_BG(x) BLUE_BG_S x CLEAR -#define BLUE_BG_BOLD(x) BLUE_BG_BOLD_S x CLEAR +#define BLUE_BG(x) BLUE_BG_S x CLEAR +#define BLUE_BG_BOLD(x) BLUE_BG_BOLD_S x CLEAR +#define MAGENTA_BG(x) MAGENTA_BG_S x CLEAR +#define MAGENTA_BG_BOLD(x) MAGENTA_BG_BOLD_S x CLEAR #define LOG_EMERG(x, ...) xmrig::Log::print(xmrig::Log::EMERG, x, ##__VA_ARGS__) diff --git a/src/core/Controller.cpp b/src/core/Controller.cpp index 81c67d7c..54c9ee34 100644 --- a/src/core/Controller.cpp +++ b/src/core/Controller.cpp @@ -28,12 +28,12 @@ #include "backend/cpu/Cpu.h" #include "core/Controller.h" +#include "core/Miner.h" #include "net/Network.h" xmrig::Controller::Controller(Process *process) : - Base(process), - m_network(nullptr) + Base(process) { } @@ -68,6 +68,8 @@ void xmrig::Controller::start() { Base::start(); + m_miner = new Miner(this); + network()->connect(); } @@ -78,6 +80,19 @@ void xmrig::Controller::stop() delete m_network; m_network = nullptr; + + m_miner->stop(); + + delete m_miner; + m_miner = nullptr; +} + + +xmrig::Miner *xmrig::Controller::miner() const +{ + assert(m_miner != nullptr); + + return m_miner; } diff --git a/src/core/Controller.h b/src/core/Controller.h index 02f9ca92..da7ba368 100644 --- a/src/core/Controller.h +++ b/src/core/Controller.h @@ -32,6 +32,8 @@ namespace xmrig { +class Job; +class Miner; class Network; @@ -46,10 +48,12 @@ public: void start() override; void stop() override; + Miner *miner() const; Network *network() const; private: - Network *m_network; + Miner *m_miner = nullptr; + Network *m_network = nullptr; }; diff --git a/src/core/Miner.cpp b/src/core/Miner.cpp new file mode 100644 index 00000000..1f819694 --- /dev/null +++ b/src/core/Miner.cpp @@ -0,0 +1,215 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include + + +#include "backend/cpu/CpuBackend.h" +#include "base/io/log/Log.h" +#include "base/net/stratum/Job.h" +#include "base/tools/Timer.h" +#include "core/config/Config.h" +#include "core/Controller.h" +#include "core/Miner.h" +#include "crypto/common/Nonce.h" + +#include "base/tools/Chrono.h" + + +namespace xmrig { + + +class MinerPrivate +{ +public: + inline MinerPrivate(Controller *controller) : controller(controller) + { + uv_rwlock_init(&rwlock); + } + + + inline ~MinerPrivate() + { + uv_rwlock_destroy(&rwlock); + + delete timer; + + for (IBackend *backend : backends) { + delete backend; + } + } + + + inline void handleJobChange() + { + active = true; + if (enabled) { + Nonce::pause(false);; + } + + for (IBackend *backend : backends) { + backend->setJob(job); + } + + if (ticks == 0) { + ticks++; + timer->start(500, 500); + } + } + + + bool active = false; + bool enabled = true; + Controller *controller; + Job job; + std::vector backends; + Timer *timer = nullptr; + uint64_t ticks = 0; + uv_rwlock_t rwlock; +}; + + +} // namespace xmrig + + + +xmrig::Miner::Miner(Controller *controller) + : d_ptr(new MinerPrivate(controller)) +{ + d_ptr->timer = new Timer(this); + + d_ptr->backends.push_back(new CpuBackend(this, controller)); +} + + +xmrig::Miner::~Miner() +{ + delete d_ptr; +} + + +bool xmrig::Miner::isEnabled() const +{ + return d_ptr->enabled; +} + + +xmrig::Job xmrig::Miner::job() const +{ + uv_rwlock_rdlock(&d_ptr->rwlock); + Job job = d_ptr->job; + uv_rwlock_rdunlock(&d_ptr->rwlock); + + return job; +} + + +void xmrig::Miner::pause() +{ + d_ptr->active = false; + + Nonce::pause(true); + Nonce::touch(); +} + + +void xmrig::Miner::printHashrate(bool details) +{ + for (IBackend *backend : d_ptr->backends) { + backend->printHashrate(details); + } +} + + +void xmrig::Miner::setEnabled(bool enabled) +{ + if (d_ptr->enabled == enabled) { + return; + } + + d_ptr->enabled = enabled; + + if (enabled) { + LOG_INFO(GREEN_BOLD("resumed")); + } + else { + LOG_INFO(YELLOW_BOLD("paused") ", press " MAGENTA_BG_BOLD(" r ") " to resume"); + } + + if (!d_ptr->active) { + return; + } + + Nonce::pause(!enabled); + Nonce::touch(); +} + + +void xmrig::Miner::setJob(const Job &job, bool donate) +{ + uv_rwlock_wrlock(&d_ptr->rwlock); + + const uint8_t index = donate ? 1 : 0; + + d_ptr->job = job; + d_ptr->job.setIndex(index); + + Nonce::reset(index); + + uv_rwlock_wrunlock(&d_ptr->rwlock); + + d_ptr->handleJobChange(); +} + + +void xmrig::Miner::stop() +{ +// xmrig::Handle::close(m_timer); +// m_hashrate->stop(); + + Nonce::stop(); + +// for (size_t i = 0; i < m_workers.size(); ++i) { +// m_workers[i]->join(); +// } + + for (IBackend *backend : d_ptr->backends) { + backend->stop(); + } +} + + +void xmrig::Miner::onTimer(const Timer *) +{ + for (IBackend *backend : d_ptr->backends) { + backend->tick(d_ptr->ticks); + } + + if ((d_ptr->ticks % (d_ptr->controller->config()->printTime() * 2)) == 0) { + printHashrate(false); + } + + d_ptr->ticks++; +} diff --git a/src/core/Miner.h b/src/core/Miner.h new file mode 100644 index 00000000..e7904575 --- /dev/null +++ b/src/core/Miner.h @@ -0,0 +1,65 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_MINER_H +#define XMRIG_MINER_H + + +#include "base/kernel/interfaces/ITimerListener.h" + + +namespace xmrig { + + +class Controller; +class Job; +class MinerPrivate; + + +class Miner : public ITimerListener +{ +public: + Miner(Controller *controller); + ~Miner() override; + + bool isEnabled() const; + Job job() const; + void pause(); + void printHashrate(bool details); + void setEnabled(bool enabled); + void setJob(const Job &job, bool donate); + void stop(); + +protected: + void onTimer(const Timer *timer) override; + +private: + MinerPrivate *d_ptr; +}; + + +} // namespace xmrig + + +#endif /* XMRIG_MINER_H */ diff --git a/src/crypto/cn/CnHash.cpp b/src/crypto/cn/CnHash.cpp index 6582db10..40f4fbba 100644 --- a/src/crypto/cn/CnHash.cpp +++ b/src/crypto/cn/CnHash.cpp @@ -202,6 +202,9 @@ static void patchAsmVariants() #endif +static const xmrig::CnHash cnHash; + + xmrig::CnHash::CnHash() { ADD_FN(Algorithm::CN_0); @@ -252,18 +255,18 @@ xmrig::CnHash::CnHash() } -xmrig::cn_hash_fun xmrig::CnHash::fn(const Algorithm &algorithm, AlgoVariant av, Assembly::Id assembly) const +xmrig::cn_hash_fun xmrig::CnHash::fn(const Algorithm &algorithm, AlgoVariant av, Assembly::Id assembly) { if (!algorithm.isValid()) { return nullptr; } # ifdef XMRIG_FEATURE_ASM - cn_hash_fun fun = m_map[algorithm][av][assembly == Assembly::AUTO ? Cpu::info()->assembly() : assembly]; + cn_hash_fun fun = cnHash.m_map[algorithm][av][assembly == Assembly::AUTO ? Cpu::info()->assembly() : assembly]; if (fun) { return fun; } # endif - return m_map[algorithm][av][Assembly::NONE]; + return cnHash.m_map[algorithm][av][Assembly::NONE]; } diff --git a/src/crypto/cn/CnHash.h b/src/crypto/cn/CnHash.h index fdfcc9f3..e4a7ebd2 100644 --- a/src/crypto/cn/CnHash.h +++ b/src/crypto/cn/CnHash.h @@ -65,7 +65,7 @@ public: CnHash(); - cn_hash_fun fn(const Algorithm &algorithm, AlgoVariant av, Assembly::Id assembly) const; + static cn_hash_fun fn(const Algorithm &algorithm, AlgoVariant av, Assembly::Id assembly); private: cn_hash_fun m_map[Algorithm::MAX][AV_MAX][Assembly::MAX] = {}; diff --git a/src/crypto/common/Nonce.cpp b/src/crypto/common/Nonce.cpp index 6670308a..45c7001a 100644 --- a/src/crypto/common/Nonce.cpp +++ b/src/crypto/common/Nonce.cpp @@ -32,7 +32,8 @@ namespace xmrig { -std::atomic Nonce::m_sequence; +std::atomic Nonce::m_paused; +std::atomic Nonce::m_sequence[Nonce::MAX]; uint32_t Nonce::m_nonces[2] = { 0, 0 }; @@ -45,7 +46,11 @@ static Nonce nonce; xmrig::Nonce::Nonce() { - m_sequence = 1; + m_paused = true; + + for (int i = 0; i < MAX; ++i) { + m_sequence[i] = 1; + } uv_mutex_init(&mutex); } @@ -77,7 +82,25 @@ void xmrig::Nonce::reset(uint8_t index) uv_mutex_lock(&mutex); m_nonces[index] = 0; - m_sequence++; + touch(); uv_mutex_unlock(&mutex); } + + +void xmrig::Nonce::stop() +{ + pause(false); + + for (int i = 0; i < MAX; ++i) { + m_sequence[i] = 0; + } +} + + +void xmrig::Nonce::touch() +{ + for (int i = 0; i < MAX; ++i) { + m_sequence[i]++; + } +} diff --git a/src/crypto/common/Nonce.h b/src/crypto/common/Nonce.h index ea843bc9..401139fd 100644 --- a/src/crypto/common/Nonce.h +++ b/src/crypto/common/Nonce.h @@ -35,19 +35,32 @@ namespace xmrig { class Nonce { public: + enum Backend { + CPU, + OPENCL, + CUDA, + MAX + }; + + Nonce(); - static inline bool isOutdated(uint64_t sequence) { return m_sequence.load(std::memory_order_relaxed) != sequence; } - static inline uint64_t sequence() { return m_sequence.load(std::memory_order_relaxed); } - static inline void stop() { m_sequence = 0; } - static inline void touch() { m_sequence++; } + static inline bool isOutdated(Backend backend, uint64_t sequence) { return m_sequence[backend].load(std::memory_order_relaxed) != sequence; } + static inline bool isPaused() { return m_paused.load(std::memory_order_relaxed); } + static inline uint64_t sequence(Backend backend) { return m_sequence[backend].load(std::memory_order_relaxed); } + static inline void pause(bool paused) { m_paused = paused; } + static inline void stop(Backend backend) { m_sequence[backend] = 0; } + static inline void touch(Backend backend) { m_sequence[backend]++; } static uint32_t next(uint8_t index, uint32_t nonce, uint32_t reserveCount, bool nicehash); static void reset(uint8_t index); + static void stop(); + static void touch(); private: + static std::atomic m_paused; + static std::atomic m_sequence[MAX]; static uint32_t m_nonces[2]; - static std::atomic m_sequence; }; diff --git a/src/net/Network.cpp b/src/net/Network.cpp index d40bebd1..6622a080 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -40,11 +40,12 @@ #include "base/tools/Timer.h" #include "core/config/Config.h" #include "core/Controller.h" +#include "core/Miner.h" +#include "net/JobResult.h" #include "net/JobResults.h" #include "net/Network.h" #include "net/strategies/DonateStrategy.h" #include "rapidjson/document.h" -#include "workers/Workers.h" #ifdef XMRIG_FEATURE_API @@ -163,7 +164,8 @@ void xmrig::Network::onPause(IStrategy *strategy) if (!m_strategy->isActive()) { LOG_ERR("no active pools, stop mining"); m_state.stop(); - return Workers::pause(); + + return m_controller->miner()->pause(); } } @@ -212,7 +214,7 @@ void xmrig::Network::setJob(IClient *client, const Job &job, bool donate) } m_state.diff = job.diff(); - Workers::setJob(job, donate); + m_controller->miner()->setJob(job, donate); } diff --git a/src/workers/CpuThreadLegacy.cpp b/src/workers/CpuThreadLegacy.cpp index b8e33839..a560d33f 100644 --- a/src/workers/CpuThreadLegacy.cpp +++ b/src/workers/CpuThreadLegacy.cpp @@ -34,10 +34,6 @@ #include "workers/CpuThreadLegacy.h" - -static const xmrig::CnHash cnHash; - - xmrig::CpuThreadLegacy::CpuThreadLegacy(size_t index, Algorithm algorithm, CnHash::AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch, Assembly assembly) : m_algorithm(algorithm), m_av(av), @@ -54,7 +50,7 @@ xmrig::CpuThreadLegacy::CpuThreadLegacy(size_t index, Algorithm algorithm, CnHas xmrig::cn_hash_fun xmrig::CpuThreadLegacy::fn(const Algorithm &algorithm) const { - return cnHash.fn(algorithm, m_av, m_assembly); + return CnHash::fn(algorithm, m_av, m_assembly); } diff --git a/src/workers/Workers.cpp b/src/workers/Workers.cpp deleted file mode 100644 index 78954d8f..00000000 --- a/src/workers/Workers.cpp +++ /dev/null @@ -1,330 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017-2018 XMR-Stak , - * Copyright 2018-2019 SChernykh - * Copyright 2016-2019 XMRig , - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include - - -#include "api/Api.h" -#include "backend/cpu/CpuWorker.h" -#include "base/io/log/Log.h" -#include "base/tools/Chrono.h" -#include "base/tools/Handle.h" -#include "core/config/Config.h" -#include "core/Controller.h" -#include "crypto/common/Nonce.h" -#include "crypto/rx/RxAlgo.h" -#include "crypto/rx/RxCache.h" -#include "crypto/rx/RxDataset.h" -#include "Mem.h" -#include "rapidjson/document.h" -#include "workers/Hashrate.h" -#include "workers/ThreadHandle.h" -#include "workers/Workers.h" - - -bool Workers::m_active = false; -bool Workers::m_enabled = true; -Hashrate *Workers::m_hashrate = nullptr; -xmrig::Job Workers::m_job; -Workers::LaunchStatus Workers::m_status; -std::atomic Workers::m_paused; -std::vector Workers::m_workers; -uint64_t Workers::m_ticks = 0; -uv_mutex_t Workers::m_mutex; -uv_rwlock_t Workers::m_rwlock; -uv_timer_t *Workers::m_timer = nullptr; -xmrig::Controller *Workers::m_controller = nullptr; - - -xmrig::Job Workers::job() -{ - uv_rwlock_rdlock(&m_rwlock); - xmrig::Job job = m_job; - uv_rwlock_rdunlock(&m_rwlock); - - return job; -} - - -size_t Workers::hugePages() -{ - uv_mutex_lock(&m_mutex); - const size_t hugePages = m_status.hugePages; - uv_mutex_unlock(&m_mutex); - - return hugePages; -} - - -size_t Workers::threads() -{ - uv_mutex_lock(&m_mutex); - const size_t threads = m_status.threads; - uv_mutex_unlock(&m_mutex); - - return threads; -} - - -void Workers::pause() -{ - m_active = false; - m_paused = 1; - - xmrig::Nonce::touch(); -} - - -void Workers::printHashrate(bool detail) -{ - assert(m_controller != nullptr); - if (!m_controller) { - return; - } - - if (detail) { - char num1[8] = { 0 }; - char num2[8] = { 0 }; - char num3[8] = { 0 }; - - xmrig::Log::print(WHITE_BOLD_S "| THREAD | AFFINITY | 10s H/s | 60s H/s | 15m H/s |"); - - size_t i = 0; - for (const xmrig::IThread *thread : m_controller->config()->threads()) { - xmrig::Log::print("| %6zu | %8" PRId64 " | %7s | %7s | %7s |", - thread->index(), - thread->affinity(), - Hashrate::format(m_hashrate->calc(thread->index(), Hashrate::ShortInterval), num1, sizeof num1), - Hashrate::format(m_hashrate->calc(thread->index(), Hashrate::MediumInterval), num2, sizeof num2), - Hashrate::format(m_hashrate->calc(thread->index(), Hashrate::LargeInterval), num3, sizeof num3) - ); - - i++; - } - } - - m_hashrate->print(); -} - - -void Workers::setEnabled(bool enabled) -{ - if (m_enabled == enabled) { - return; - } - - m_enabled = enabled; - if (!m_active) { - return; - } - - m_paused = enabled ? 0 : 1; - xmrig::Nonce::touch(); -} - - -void Workers::setJob(const xmrig::Job &job, bool donate) -{ - uv_rwlock_wrlock(&m_rwlock); - - m_job = job; - m_job.setIndex(donate ? 1 : 0); - - xmrig::Nonce::reset(donate ? 1 : 0); - - uv_rwlock_wrunlock(&m_rwlock); - - m_active = true; - if (!m_enabled) { - return; - } - - m_paused = 0; -} - - -void Workers::start(xmrig::Controller *controller) -{ -# ifdef APP_DEBUG - LOG_NOTICE("THREADS ------------------------------------------------------------------"); - for (const xmrig::IThread *thread : controller->config()->threads()) { - thread->print(); - } - LOG_NOTICE("--------------------------------------------------------------------------"); -# endif - - m_controller = controller; - - const std::vector &threads = controller->config()->threads(); - m_status.algo = xmrig::Algorithm::RX_WOW; // FIXME algo - m_status.threads = threads.size(); - - for (const xmrig::IThread *thread : threads) { - m_status.ways += thread->multiway(); - } - - m_hashrate = new Hashrate(threads.size(), controller); - - uv_mutex_init(&m_mutex); - uv_rwlock_init(&m_rwlock); - - m_paused = 1; - - m_timer = new uv_timer_t; - uv_timer_init(uv_default_loop(), m_timer); - uv_timer_start(m_timer, Workers::onTick, 500, 500); - - for (xmrig::IThread *thread : threads) { - ThreadHandle *handle = new ThreadHandle(thread); - - m_workers.push_back(handle); - handle->start(Workers::onReady); - } -} - - -void Workers::stop() -{ - xmrig::Handle::close(m_timer); - m_hashrate->stop(); - - m_paused = 0; - - xmrig::Nonce::stop(); - - for (size_t i = 0; i < m_workers.size(); ++i) { - m_workers[i]->join(); - } -} - - -#ifdef XMRIG_FEATURE_API -void Workers::threadsSummary(rapidjson::Document &doc) -{ - uv_mutex_lock(&m_mutex); - const uint64_t pages[2] = { m_status.hugePages, m_status.pages }; - const uint64_t memory = m_status.ways * xmrig::CnAlgo<>::memory(m_status.algo); - uv_mutex_unlock(&m_mutex); - - auto &allocator = doc.GetAllocator(); - - rapidjson::Value hugepages(rapidjson::kArrayType); - hugepages.PushBack(pages[0], allocator); - hugepages.PushBack(pages[1], allocator); - - doc.AddMember("hugepages", hugepages, allocator); - doc.AddMember("memory", memory, allocator); -} -#endif - - -void Workers::onReady(void *arg) -{ - auto handle = static_cast(arg); - - IWorker *worker = nullptr; - - switch (handle->config()->multiway()) { - case 1: - worker = new xmrig::CpuWorker<1>(handle); - break; - - case 2: - worker = new xmrig::CpuWorker<2>(handle); - break; - - case 3: - worker = new xmrig::CpuWorker<3>(handle); - break; - - case 4: - worker = new xmrig::CpuWorker<4>(handle); - break; - - case 5: - worker = new xmrig::CpuWorker<5>(handle); - break; - } - - handle->setWorker(worker); - - if (!worker->selfTest()) { - LOG_ERR("thread %zu error: \"hash self-test failed\".", handle->worker()->id()); - - return; - } - - start(worker); -} - - -void Workers::onTick(uv_timer_t *) -{ - for (ThreadHandle *handle : m_workers) { - if (!handle->worker()) { - return; - } - - m_hashrate->add(handle->threadId(), handle->worker()->hashCount(), handle->worker()->timestamp()); - } - - if ((m_ticks++ & 0xF) == 0) { - m_hashrate->updateHighest(); - } -} - - -void Workers::start(IWorker *worker) -{ -// const Worker *w = static_cast(worker); - - uv_mutex_lock(&m_mutex); - m_status.started++; -// m_status.pages += w->memory().pages; -// m_status.hugePages += w->memory().hugePages; - - if (m_status.started == m_status.threads) { - const double percent = (double) m_status.hugePages / m_status.pages * 100.0; - const size_t memory = m_status.ways * xmrig::CnAlgo<>::memory(m_status.algo) / 1024; - -# ifdef XMRIG_ALGO_RANDOMX - if (m_status.algo.family() == xmrig::Algorithm::RANDOM_X) { - LOG_INFO(GREEN_BOLD("READY (CPU)") " threads " CYAN_BOLD("%zu(%zu)") " memory " CYAN_BOLD("%zu KB") "", - m_status.threads, m_status.ways, memory); - } else -# endif - { - LOG_INFO(GREEN_BOLD("READY (CPU)") " threads " CYAN_BOLD("%zu(%zu)") " huge pages %s%zu/%zu %1.0f%%\x1B[0m memory " CYAN_BOLD("%zu KB") "", - m_status.threads, m_status.ways, - (m_status.hugePages == m_status.pages ? GREEN_BOLD_S : (m_status.hugePages == 0 ? RED_BOLD_S : YELLOW_BOLD_S)), - m_status.hugePages, m_status.pages, percent, memory); - } - } - - uv_mutex_unlock(&m_mutex); - - worker->start(); -} diff --git a/src/workers/WorkersLegacy.cpp b/src/workers/WorkersLegacy.cpp new file mode 100644 index 00000000..29571608 --- /dev/null +++ b/src/workers/WorkersLegacy.cpp @@ -0,0 +1,331 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + + +#include "api/Api.h" +#include "backend/cpu/CpuWorker.h" +#include "base/io/log/Log.h" +#include "base/tools/Chrono.h" +#include "base/tools/Handle.h" +#include "core/config/Config.h" +#include "core/Controller.h" +#include "crypto/common/Nonce.h" +#include "crypto/rx/RxAlgo.h" +#include "crypto/rx/RxCache.h" +#include "crypto/rx/RxDataset.h" +#include "Mem.h" +#include "rapidjson/document.h" +#include "workers/Hashrate.h" +#include "workers/WorkersLegacy.h" + + +bool WorkersLegacy::m_active = false; +bool WorkersLegacy::m_enabled = true; +Hashrate *WorkersLegacy::m_hashrate = nullptr; +xmrig::Job WorkersLegacy::m_job; +WorkersLegacy::LaunchStatus WorkersLegacy::m_status; +std::vector* > WorkersLegacy::m_workers; +uint64_t WorkersLegacy::m_ticks = 0; +uv_mutex_t WorkersLegacy::m_mutex; +uv_rwlock_t WorkersLegacy::m_rwlock; +//uv_timer_t *Workers::m_timer = nullptr; +xmrig::Controller *WorkersLegacy::m_controller = nullptr; + + +//xmrig::Job WorkersLegacy::job() +//{ +// uv_rwlock_rdlock(&m_rwlock); +// xmrig::Job job = m_job; +// uv_rwlock_rdunlock(&m_rwlock); + +// return job; +//} + + +size_t WorkersLegacy::hugePages() +{ + uv_mutex_lock(&m_mutex); + const size_t hugePages = m_status.hugePages; + uv_mutex_unlock(&m_mutex); + + return hugePages; +} + + +size_t WorkersLegacy::threads() +{ + uv_mutex_lock(&m_mutex); + const size_t threads = m_status.threads; + uv_mutex_unlock(&m_mutex); + + return threads; +} + + +//void Workers::pause() +//{ +// m_active = false; + +// xmrig::Nonce::pause(true); +// xmrig::Nonce::touch(); +//} + + +//void Workers::printHashrate(bool detail) +//{ +// assert(m_controller != nullptr); +// if (!m_controller) { +// return; +// } + +// if (detail) { +// char num1[8] = { 0 }; +// char num2[8] = { 0 }; +// char num3[8] = { 0 }; + +// xmrig::Log::print(WHITE_BOLD_S "| THREAD | AFFINITY | 10s H/s | 60s H/s | 15m H/s |"); + +// size_t i = 0; +// for (const xmrig::IThread *thread : m_controller->config()->threads()) { +// xmrig::Log::print("| %6zu | %8" PRId64 " | %7s | %7s | %7s |", +// thread->index(), +// thread->affinity(), +// Hashrate::format(m_hashrate->calc(thread->index(), Hashrate::ShortInterval), num1, sizeof num1), +// Hashrate::format(m_hashrate->calc(thread->index(), Hashrate::MediumInterval), num2, sizeof num2), +// Hashrate::format(m_hashrate->calc(thread->index(), Hashrate::LargeInterval), num3, sizeof num3) +// ); + +// i++; +// } +// } + +// m_hashrate->print(); +//} + + +//void Workers::setEnabled(bool enabled) +//{ +// if (m_enabled == enabled) { +// return; +// } + +// m_enabled = enabled; +// if (!m_active) { +// return; +// } + +// xmrig::Nonce::pause(!enabled); +// xmrig::Nonce::touch(); +//} + + +//void Workers::setJob(const xmrig::Job &job, bool donate) +//{ +// uv_rwlock_wrlock(&m_rwlock); + +// m_job = job; +// m_job.setIndex(donate ? 1 : 0); + +// xmrig::Nonce::reset(donate ? 1 : 0); + +// uv_rwlock_wrunlock(&m_rwlock); + +// m_active = true; +// if (!m_enabled) { +// return; +// } + +// xmrig::Nonce::pause(false); +//} + + +void WorkersLegacy::start(xmrig::Controller *controller) +{ + using namespace xmrig; + +# ifdef APP_DEBUG + LOG_NOTICE("THREADS ------------------------------------------------------------------"); + for (const xmrig::IThread *thread : controller->config()->threads()) { + thread->print(); + } + LOG_NOTICE("--------------------------------------------------------------------------"); +# endif + + m_controller = controller; + + m_status.algo = xmrig::Algorithm::RX_WOW; // FIXME algo + const CpuThreads &threads = controller->config()->cpu().threads().get(m_status.algo); + m_status.threads = threads.size(); + + for (const CpuThread &thread : threads) { + m_status.ways += thread.intensity(); + } + + m_hashrate = new Hashrate(threads.size(), controller); + + uv_mutex_init(&m_mutex); + uv_rwlock_init(&m_rwlock); + +// m_timer = new uv_timer_t; +// uv_timer_init(uv_default_loop(), m_timer); +// uv_timer_start(m_timer, Workers::onTick, 500, 500); + +// size_t index = 0; +// for (const CpuThread &thread : threads) { +// Thread *handle = new Thread(index++, CpuLaunchData(m_status.algo, controller->config()->cpu(), thread)); + +// m_workers.push_back(handle); +// handle->start(WorkersLegacy::onReady); +// } +} + + +//void Workers::stop() +//{ +// xmrig::Handle::close(m_timer); +// m_hashrate->stop(); + +// xmrig::Nonce::stop(); + +// for (size_t i = 0; i < m_workers.size(); ++i) { +// m_workers[i]->join(); +// } +//} + + +#ifdef XMRIG_FEATURE_API +void WorkersLegacy::threadsSummary(rapidjson::Document &doc) +{ + uv_mutex_lock(&m_mutex); + const uint64_t pages[2] = { m_status.hugePages, m_status.pages }; + const uint64_t memory = m_status.ways * xmrig::CnAlgo<>::memory(m_status.algo); + uv_mutex_unlock(&m_mutex); + + auto &allocator = doc.GetAllocator(); + + rapidjson::Value hugepages(rapidjson::kArrayType); + hugepages.PushBack(pages[0], allocator); + hugepages.PushBack(pages[1], allocator); + + doc.AddMember("hugepages", hugepages, allocator); + doc.AddMember("memory", memory, allocator); +} +#endif + + +//void WorkersLegacy::onReady(void *arg) +//{ +// using namespace xmrig; + +// auto handle = static_cast* >(arg); + +// xmrig::IWorker *worker = nullptr; + +// switch (handle->config().intensity) { +// case 1: +// worker = new CpuWorker<1>(handle->index(), handle->config()); +// break; + +// case 2: +// worker = new CpuWorker<2>(handle->index(), handle->config()); +// break; + +// case 3: +// worker = new CpuWorker<3>(handle->index(), handle->config()); +// break; + +// case 4: +// worker = new CpuWorker<4>(handle->index(), handle->config()); +// break; + +// case 5: +// worker = new CpuWorker<5>(handle->index(), handle->config()); +// break; +// } + +// handle->setWorker(worker); + +// if (!worker->selfTest()) { +// LOG_ERR("thread %zu error: \"hash self-test failed\".", handle->worker()->id()); + +// return; +// } + +// start(worker); +//} + + +void WorkersLegacy::onTick(uv_timer_t *) +{ + using namespace xmrig; + + for (Thread *handle : m_workers) { + if (!handle->worker()) { + return; + } + + m_hashrate->add(handle->index(), handle->worker()->hashCount(), handle->worker()->timestamp()); + } + + if ((m_ticks++ & 0xF) == 0) { + m_hashrate->updateHighest(); + } +} + + +void WorkersLegacy::start(xmrig::IWorker *worker) +{ +// const Worker *w = static_cast(worker); + + uv_mutex_lock(&m_mutex); + m_status.started++; +// m_status.pages += w->memory().pages; +// m_status.hugePages += w->memory().hugePages; + + if (m_status.started == m_status.threads) { + const double percent = (double) m_status.hugePages / m_status.pages * 100.0; + const size_t memory = m_status.ways * xmrig::CnAlgo<>::memory(m_status.algo) / 1024; + +# ifdef XMRIG_ALGO_RANDOMX + if (m_status.algo.family() == xmrig::Algorithm::RANDOM_X) { + LOG_INFO(GREEN_BOLD("READY (CPU)") " threads " CYAN_BOLD("%zu(%zu)") " memory " CYAN_BOLD("%zu KB") "", + m_status.threads, m_status.ways, memory); + } else +# endif + { + LOG_INFO(GREEN_BOLD("READY (CPU)") " threads " CYAN_BOLD("%zu(%zu)") " huge pages %s%zu/%zu %1.0f%%\x1B[0m memory " CYAN_BOLD("%zu KB") "", + m_status.threads, m_status.ways, + (m_status.hugePages == m_status.pages ? GREEN_BOLD_S : (m_status.hugePages == 0 ? RED_BOLD_S : YELLOW_BOLD_S)), + m_status.hugePages, m_status.pages, percent, memory); + } + } + + uv_mutex_unlock(&m_mutex); + + worker->start(); +} diff --git a/src/workers/Workers.h b/src/workers/WorkersLegacy.h similarity index 76% rename from src/workers/Workers.h rename to src/workers/WorkersLegacy.h index 83777d0d..5ee53dbf 100644 --- a/src/workers/Workers.h +++ b/src/workers/WorkersLegacy.h @@ -22,8 +22,8 @@ * along with this program. If not, see . */ -#ifndef XMRIG_WORKERS_H -#define XMRIG_WORKERS_H +#ifndef XMRIG_WORKERSLEGACY_H +#define XMRIG_WORKERSLEGACY_H #include @@ -35,36 +35,37 @@ # include #endif +#include "backend/common/Thread.h" +#include "backend/cpu/CpuLaunchData.h" #include "base/net/stratum/Job.h" #include "net/JobResult.h" #include "rapidjson/fwd.h" class Hashrate; -class IWorker; -class ThreadHandle; namespace xmrig { + class IWorker; class Controller; + class ThreadHandle; } -class Workers +class WorkersLegacy { public: static size_t hugePages(); static size_t threads(); - static void pause(); - static void printHashrate(bool detail); - static void setEnabled(bool enabled); - static void setJob(const xmrig::Job &job, bool donate); +// static void pause(); +// static void printHashrate(bool detail); +// static void setEnabled(bool enabled); +// static void setJob(const xmrig::Job &job, bool donate); static void start(xmrig::Controller *controller); - static void stop(); - static xmrig::Job job(); +// static void stop(); +// static xmrig::Job job(); - static inline bool isEnabled() { return m_enabled; } - static inline bool isPaused() { return m_paused.load(std::memory_order_relaxed) == 1; } +// static inline bool isEnabled() { return m_enabled; } static inline Hashrate *hashrate() { return m_hashrate; } # ifdef XMRIG_FEATURE_API @@ -72,9 +73,9 @@ public: # endif private: - static void onReady(void *arg); +// static void onReady(void *arg); static void onTick(uv_timer_t *handle); - static void start(IWorker *worker); + static void start(xmrig::IWorker *worker); class LaunchStatus { @@ -100,14 +101,13 @@ private: static Hashrate *m_hashrate; static xmrig::Job m_job; static LaunchStatus m_status; - static std::atomic m_paused; - static std::vector m_workers; + static std::vector* > m_workers; static uint64_t m_ticks; static uv_mutex_t m_mutex; static uv_rwlock_t m_rwlock; - static uv_timer_t *m_timer; +// static uv_timer_t *m_timer; static xmrig::Controller *m_controller; }; -#endif /* XMRIG_WORKERS_H */ +#endif /* XMRIG_WORKERSLEGACY_H */ From 5699147aabe84a413c73e1e74dc6d416b100b885 Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 17 Jul 2019 01:28:42 +0700 Subject: [PATCH 27/48] Restored printable hashrate. --- CMakeLists.txt | 2 - src/api/v1/ApiRouter.cpp | 86 +++++++++--------- src/api/v1/ApiRouter.h | 2 +- src/{workers => backend/common}/Hashrate.cpp | 72 +++++---------- src/{workers => backend/common}/Hashrate.h | 14 +-- src/backend/common/Workers.cpp | 40 +++++++- src/backend/common/Workers.h | 3 + src/backend/common/common.cmake | 2 + src/backend/common/interfaces/IBackend.h | 2 + src/backend/cpu/CpuBackend.cpp | 32 ++++++- src/backend/cpu/CpuBackend.h | 1 + src/core/Miner.cpp | 35 ++++++- src/core/Miner.h | 5 + src/workers/WorkersLegacy.cpp | 96 +++----------------- src/workers/WorkersLegacy.h | 8 +- 15 files changed, 196 insertions(+), 204 deletions(-) rename src/{workers => backend/common}/Hashrate.cpp (71%) rename src/{workers => backend/common}/Hashrate.h (90%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8749a003..543836c8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,7 +44,6 @@ set(HEADERS src/Summary.h src/version.h src/workers/CpuThreadLegacy.h - src/workers/Hashrate.h src/workers/WorkersLegacy.h ) @@ -92,7 +91,6 @@ set(SOURCES src/net/strategies/DonateStrategy.cpp src/Summary.cpp src/workers/CpuThreadLegacy.cpp - src/workers/Hashrate.cpp src/workers/WorkersLegacy.cpp src/xmrig.cpp ) diff --git a/src/api/v1/ApiRouter.cpp b/src/api/v1/ApiRouter.cpp index 9e609d13..48a92c93 100644 --- a/src/api/v1/ApiRouter.cpp +++ b/src/api/v1/ApiRouter.cpp @@ -36,7 +36,7 @@ #include "core/config/Config.h" #include "rapidjson/document.h" #include "version.h" -#include "workers/Hashrate.h" +//#include "workers/Hashrate.h" #include "workers/WorkersLegacy.h" @@ -69,7 +69,7 @@ void xmrig::ApiRouter::onRequest(IApiRequest &request) if (request.url() == "/1/summary" || request.url() == "/api.json") { request.accept(); getMiner(request.reply(), request.doc()); - getHashrate(request.reply(), request.doc()); +// getHashrate(request.reply(), request.doc()); } else if (request.url() == "/1/threads") { request.accept(); @@ -98,35 +98,35 @@ void xmrig::ApiRouter::onRequest(IApiRequest &request) } -void xmrig::ApiRouter::getHashrate(rapidjson::Value &reply, rapidjson::Document &doc) const -{ - using namespace rapidjson; - auto &allocator = doc.GetAllocator(); +//void xmrig::ApiRouter::getHashrate(rapidjson::Value &reply, rapidjson::Document &doc) const +//{ +// using namespace rapidjson; +// auto &allocator = doc.GetAllocator(); - Value hashrate(kObjectType); - Value total(kArrayType); - Value threads(kArrayType); +// Value hashrate(kObjectType); +// Value total(kArrayType); +// Value threads(kArrayType); - const Hashrate *hr = WorkersLegacy::hashrate(); +// const Hashrate *hr = WorkersLegacy::hashrate(); - total.PushBack(normalize(hr->calc(Hashrate::ShortInterval)), allocator); - total.PushBack(normalize(hr->calc(Hashrate::MediumInterval)), allocator); - total.PushBack(normalize(hr->calc(Hashrate::LargeInterval)), allocator); +// total.PushBack(normalize(hr->calc(Hashrate::ShortInterval)), allocator); +// total.PushBack(normalize(hr->calc(Hashrate::MediumInterval)), allocator); +// total.PushBack(normalize(hr->calc(Hashrate::LargeInterval)), allocator); - for (size_t i = 0; i < WorkersLegacy::threads(); i++) { - Value thread(kArrayType); - thread.PushBack(normalize(hr->calc(i, Hashrate::ShortInterval)), allocator); - thread.PushBack(normalize(hr->calc(i, Hashrate::MediumInterval)), allocator); - thread.PushBack(normalize(hr->calc(i, Hashrate::LargeInterval)), allocator); +// for (size_t i = 0; i < WorkersLegacy::threads(); i++) { +// Value thread(kArrayType); +// thread.PushBack(normalize(hr->calc(i, Hashrate::ShortInterval)), allocator); +// thread.PushBack(normalize(hr->calc(i, Hashrate::MediumInterval)), allocator); +// thread.PushBack(normalize(hr->calc(i, Hashrate::LargeInterval)), allocator); - threads.PushBack(thread, allocator); - } +// threads.PushBack(thread, allocator); +// } - hashrate.AddMember("total", total, allocator); - hashrate.AddMember("highest", normalize(hr->highest()), allocator); - hashrate.AddMember("threads", threads, allocator); - reply.AddMember("hashrate", hashrate, allocator); -} +// hashrate.AddMember("total", total, allocator); +// hashrate.AddMember("highest", normalize(hr->highest()), allocator); +// hashrate.AddMember("threads", threads, allocator); +// reply.AddMember("hashrate", hashrate, allocator); +//} void xmrig::ApiRouter::getMiner(rapidjson::Value &reply, rapidjson::Document &doc) const @@ -151,29 +151,29 @@ void xmrig::ApiRouter::getMiner(rapidjson::Value &reply, rapidjson::Document &do void xmrig::ApiRouter::getThreads(rapidjson::Value &reply, rapidjson::Document &doc) const { - using namespace rapidjson; - auto &allocator = doc.GetAllocator(); - const Hashrate *hr = WorkersLegacy::hashrate(); +// using namespace rapidjson; +// auto &allocator = doc.GetAllocator(); +// const Hashrate *hr = WorkersLegacy::hashrate(); - WorkersLegacy::threadsSummary(doc); +// WorkersLegacy::threadsSummary(doc); - const std::vector &threads = m_base->config()->threads(); - Value list(kArrayType); +// const std::vector &threads = m_base->config()->threads(); +// Value list(kArrayType); - size_t i = 0; - for (const xmrig::IThread *thread : threads) { - Value value = thread->toAPI(doc); +// size_t i = 0; +// for (const xmrig::IThread *thread : threads) { +// Value value = thread->toAPI(doc); - Value hashrate(kArrayType); - hashrate.PushBack(normalize(hr->calc(i, Hashrate::ShortInterval)), allocator); - hashrate.PushBack(normalize(hr->calc(i, Hashrate::MediumInterval)), allocator); - hashrate.PushBack(normalize(hr->calc(i, Hashrate::LargeInterval)), allocator); +// Value hashrate(kArrayType); +// hashrate.PushBack(normalize(hr->calc(i, Hashrate::ShortInterval)), allocator); +// hashrate.PushBack(normalize(hr->calc(i, Hashrate::MediumInterval)), allocator); +// hashrate.PushBack(normalize(hr->calc(i, Hashrate::LargeInterval)), allocator); - i++; +// i++; - value.AddMember("hashrate", hashrate, allocator); - list.PushBack(value, allocator); - } +// value.AddMember("hashrate", hashrate, allocator); +// list.PushBack(value, allocator); +// } - reply.AddMember("threads", list, allocator); +// reply.AddMember("threads", list, allocator); } diff --git a/src/api/v1/ApiRouter.h b/src/api/v1/ApiRouter.h index bdbbaea4..e2b9bd25 100644 --- a/src/api/v1/ApiRouter.h +++ b/src/api/v1/ApiRouter.h @@ -49,7 +49,7 @@ protected: void onRequest(IApiRequest &request) override; private: - void getHashrate(rapidjson::Value &reply, rapidjson::Document &doc) const; +// void getHashrate(rapidjson::Value &reply, rapidjson::Document &doc) const; void getMiner(rapidjson::Value &reply, rapidjson::Document &doc) const; void getThreads(rapidjson::Value &reply, rapidjson::Document &doc) const; diff --git a/src/workers/Hashrate.cpp b/src/backend/common/Hashrate.cpp similarity index 71% rename from src/workers/Hashrate.cpp rename to src/backend/common/Hashrate.cpp index 0a683caa..6ffd45b7 100644 --- a/src/workers/Hashrate.cpp +++ b/src/backend/common/Hashrate.cpp @@ -29,12 +29,9 @@ #include -#include "base/io/log/Log.h" #include "base/tools/Chrono.h" #include "base/tools/Handle.h" -#include "core/config/Config.h" -#include "core/Controller.h" -#include "workers/Hashrate.h" +#include "backend/common/Hashrate.h" inline static const char *format(double h, char *buf, size_t size) @@ -48,10 +45,9 @@ inline static const char *format(double h, char *buf, size_t size) } -Hashrate::Hashrate(size_t threads, xmrig::Controller *controller) : +xmrig::Hashrate::Hashrate(size_t threads) : m_highest(0.0), - m_threads(threads), - m_timer(nullptr) + m_threads(threads) { m_counts = new uint64_t*[threads]; m_timestamps = new uint64_t*[threads]; @@ -62,20 +58,23 @@ Hashrate::Hashrate(size_t threads, xmrig::Controller *controller) : m_timestamps[i] = new uint64_t[kBucketSize](); m_top[i] = 0; } - - const int printTime = controller->config()->printTime(); - - if (printTime > 0) { - m_timer = new uv_timer_t; - uv_timer_init(uv_default_loop(), m_timer); - m_timer->data = this; - - uv_timer_start(m_timer, Hashrate::onReport, (printTime + 4) * 1000, printTime * 1000); - } } -double Hashrate::calc(size_t ms) const +xmrig::Hashrate::~Hashrate() +{ + for (size_t i = 0; i < m_threads; i++) { + delete [] m_counts[i]; + delete [] m_timestamps[i]; + } + + delete [] m_counts; + delete [] m_timestamps; + delete [] m_top; +} + + +double xmrig::Hashrate::calc(size_t ms) const { double result = 0.0; double data; @@ -91,7 +90,7 @@ double Hashrate::calc(size_t ms) const } -double Hashrate::calc(size_t threadId, size_t ms) const +double xmrig::Hashrate::calc(size_t threadId, size_t ms) const { assert(threadId < m_threads); if (threadId >= m_threads) { @@ -140,7 +139,7 @@ double Hashrate::calc(size_t threadId, size_t ms) const } -void Hashrate::add(size_t threadId, uint64_t count, uint64_t timestamp) +void xmrig::Hashrate::add(size_t threadId, uint64_t count, uint64_t timestamp) { const size_t top = m_top[threadId]; m_counts[threadId][top] = count; @@ -150,30 +149,7 @@ void Hashrate::add(size_t threadId, uint64_t count, uint64_t timestamp) } -void Hashrate::print() const -{ - char num1[8] = { 0 }; - char num2[8] = { 0 }; - char num3[8] = { 0 }; - char num4[8] = { 0 }; - - LOG_INFO(WHITE_BOLD("speed") " 10s/60s/15m " CYAN_BOLD("%s") CYAN(" %s %s ") CYAN_BOLD("H/s") " max " CYAN_BOLD("%s H/s"), - format(calc(ShortInterval), num1, sizeof(num1)), - format(calc(MediumInterval), num2, sizeof(num2)), - format(calc(LargeInterval), num3, sizeof(num3)), - format(m_highest, num4, sizeof(num4)) - ); -} - - -void Hashrate::stop() -{ - xmrig::Handle::close(m_timer); - m_timer = nullptr; -} - - -void Hashrate::updateHighest() +void xmrig::Hashrate::updateHighest() { double highest = calc(ShortInterval); if (isnormal(highest) && highest > m_highest) { @@ -182,13 +158,7 @@ void Hashrate::updateHighest() } -const char *Hashrate::format(double h, char *buf, size_t size) +const char *xmrig::Hashrate::format(double h, char *buf, size_t size) { return ::format(h, buf, size); } - - -void Hashrate::onReport(uv_timer_t *handle) -{ - static_cast(handle->data)->print(); -} diff --git a/src/workers/Hashrate.h b/src/backend/common/Hashrate.h similarity index 90% rename from src/workers/Hashrate.h rename to src/backend/common/Hashrate.h index d27b289e..1787bf6a 100644 --- a/src/workers/Hashrate.h +++ b/src/backend/common/Hashrate.h @@ -27,12 +27,9 @@ #include -#include namespace xmrig { - class Controller; -} class Hashrate @@ -44,12 +41,11 @@ public: LargeInterval = 900000 }; - Hashrate(size_t threads, xmrig::Controller *controller); + Hashrate(size_t threads); + ~Hashrate(); double calc(size_t ms) const; double calc(size_t threadId, size_t ms) const; void add(size_t threadId, uint64_t count, uint64_t timestamp); - void print() const; - void stop(); void updateHighest(); inline double highest() const { return m_highest; } @@ -58,8 +54,6 @@ public: static const char *format(double h, char *buf, size_t size); private: - static void onReport(uv_timer_t *handle); - constexpr static size_t kBucketSize = 2 << 11; constexpr static size_t kBucketMask = kBucketSize - 1; @@ -68,8 +62,10 @@ private: uint32_t* m_top; uint64_t** m_counts; uint64_t** m_timestamps; - uv_timer_t *m_timer; }; +} // namespace xmrig + + #endif /* XMRIG_HASHRATE_H */ diff --git a/src/backend/common/Workers.cpp b/src/backend/common/Workers.cpp index 987ca526..c4ac38a5 100644 --- a/src/backend/common/Workers.cpp +++ b/src/backend/common/Workers.cpp @@ -24,6 +24,7 @@ */ +#include "backend/common/Hashrate.h" #include "backend/common/Workers.h" #include "backend/cpu/CpuWorker.h" #include "base/io/log/Log.h" @@ -37,13 +38,16 @@ class WorkersPrivate public: inline WorkersPrivate() { - } inline ~WorkersPrivate() { + delete hashrate; } + + + Hashrate *hashrate = nullptr; }; @@ -65,6 +69,13 @@ xmrig::Workers::~Workers() } +template +const xmrig::Hashrate *xmrig::Workers::hashrate() const +{ + return d_ptr->hashrate; +} + + template void xmrig::Workers::add(const T &data) { @@ -75,6 +86,8 @@ void xmrig::Workers::add(const T &data) template void xmrig::Workers::start() { + d_ptr->hashrate = new Hashrate(m_workers.size()); + for (Thread *worker : m_workers) { worker->start(Workers::onReady); } @@ -92,13 +105,34 @@ void xmrig::Workers::stop() m_workers.clear(); Nonce::touch(T::backend()); + + delete d_ptr->hashrate; + d_ptr->hashrate = nullptr; } template -void xmrig::Workers::onReady(void *arg) +void xmrig::Workers::tick(uint64_t) +{ + if (!d_ptr->hashrate) { + return; + } + + for (Thread *handle : m_workers) { + if (!handle->worker()) { + return; + } + + d_ptr->hashrate->add(handle->index(), handle->worker()->hashCount(), handle->worker()->timestamp()); + } + + d_ptr->hashrate->updateHighest(); +} + + +template +void xmrig::Workers::onReady(void *) { - printf("ON READY\n"); } diff --git a/src/backend/common/Workers.h b/src/backend/common/Workers.h index 25f81c5b..3ef4b015 100644 --- a/src/backend/common/Workers.h +++ b/src/backend/common/Workers.h @@ -34,6 +34,7 @@ namespace xmrig { +class Hashrate; class WorkersPrivate; @@ -44,9 +45,11 @@ public: Workers(); ~Workers(); + const Hashrate *hashrate() const; void add(const T &data); void start(); void stop(); + void tick(uint64_t ticks); private: static void onReady(void *arg); diff --git a/src/backend/common/common.cmake b/src/backend/common/common.cmake index bb84af58..c470ea50 100644 --- a/src/backend/common/common.cmake +++ b/src/backend/common/common.cmake @@ -2,6 +2,7 @@ set(HEADERS_BACKEND_COMMON src/backend/common/interfaces/IBackend.h src/backend/common/interfaces/IThread.h src/backend/common/interfaces/IWorker.h + src/backend/common/Hashrate.h src/backend/common/Thread.h src/backend/common/Threads.h src/backend/common/Worker.h @@ -10,6 +11,7 @@ set(HEADERS_BACKEND_COMMON ) set(SOURCES_BACKEND_COMMON + src/backend/common/Hashrate.cpp src/backend/common/Threads.cpp src/backend/common/Worker.cpp src/backend/common/Workers.cpp diff --git a/src/backend/common/interfaces/IBackend.h b/src/backend/common/interfaces/IBackend.h index d6fe1695..69ed4c8c 100644 --- a/src/backend/common/interfaces/IBackend.h +++ b/src/backend/common/interfaces/IBackend.h @@ -32,6 +32,7 @@ namespace xmrig { +class Hashrate; class Job; class String; @@ -41,6 +42,7 @@ class IBackend public: virtual ~IBackend() = default; + virtual const Hashrate *hashrate() const = 0; virtual const String &profileName() const = 0; virtual void printHashrate(bool details) = 0; virtual void setJob(const Job &job) = 0; diff --git a/src/backend/cpu/CpuBackend.cpp b/src/backend/cpu/CpuBackend.cpp index a1ae5747..c8d38ca6 100644 --- a/src/backend/cpu/CpuBackend.cpp +++ b/src/backend/cpu/CpuBackend.cpp @@ -23,17 +23,16 @@ */ +#include "backend/common/Hashrate.h" #include "backend/common/Workers.h" #include "backend/cpu/CpuBackend.h" +#include "base/io/log/Log.h" #include "base/net/stratum/Job.h" #include "base/tools/String.h" #include "core/config/Config.h" #include "core/Controller.h" -#include "base/io/log/Log.h" - - namespace xmrig { @@ -98,6 +97,12 @@ xmrig::CpuBackend::~CpuBackend() } +const xmrig::Hashrate *xmrig::CpuBackend::hashrate() const +{ + return d_ptr->workers.hashrate(); +} + + const xmrig::String &xmrig::CpuBackend::profileName() const { return d_ptr->profileName; @@ -106,7 +111,26 @@ const xmrig::String &xmrig::CpuBackend::profileName() const void xmrig::CpuBackend::printHashrate(bool details) { + if (!details || !hashrate()) { + return; + } + char num[8 * 3] = { 0 }; + + Log::print(WHITE_BOLD_S "| CPU THREAD | AFFINITY | 10s H/s | 60s H/s | 15m H/s |"); + + size_t i = 0; + for (const CpuThread &thread : d_ptr->threads) { + Log::print("| %13zu | %8" PRId64 " | %7s | %7s | %7s |", + i, + thread.affinity(), + Hashrate::format(hashrate()->calc(i, Hashrate::ShortInterval), num, sizeof num / 3), + Hashrate::format(hashrate()->calc(i, Hashrate::MediumInterval), num + 8, sizeof num / 3), + Hashrate::format(hashrate()->calc(i, Hashrate::LargeInterval), num + 8 * 2, sizeof num / 3) + ); + + i++; + } } @@ -147,5 +171,5 @@ void xmrig::CpuBackend::stop() void xmrig::CpuBackend::tick(uint64_t ticks) { - + d_ptr->workers.tick(ticks); } diff --git a/src/backend/cpu/CpuBackend.h b/src/backend/cpu/CpuBackend.h index d39ab38d..a7b742eb 100644 --- a/src/backend/cpu/CpuBackend.h +++ b/src/backend/cpu/CpuBackend.h @@ -44,6 +44,7 @@ public: ~CpuBackend() override; protected: + const Hashrate *hashrate() const override; const String &profileName() const override; void printHashrate(bool details) override; void setJob(const Job &job) override; diff --git a/src/core/Miner.cpp b/src/core/Miner.cpp index 1f819694..83ce2206 100644 --- a/src/core/Miner.cpp +++ b/src/core/Miner.cpp @@ -26,6 +26,7 @@ #include +#include "backend/common/Hashrate.h" #include "backend/cpu/CpuBackend.h" #include "base/io/log/Log.h" #include "base/net/stratum/Job.h" @@ -35,8 +36,6 @@ #include "core/Miner.h" #include "crypto/common/Nonce.h" -#include "base/tools/Chrono.h" - namespace xmrig { @@ -83,6 +82,7 @@ public: bool active = false; bool enabled = true; Controller *controller; + double maxHashrate = 0.0; Job job; std::vector backends; Timer *timer = nullptr; @@ -116,6 +116,12 @@ bool xmrig::Miner::isEnabled() const } +const std::vector &xmrig::Miner::backends() const +{ + return d_ptr->backends; +} + + xmrig::Job xmrig::Miner::job() const { uv_rwlock_rdlock(&d_ptr->rwlock); @@ -137,9 +143,26 @@ void xmrig::Miner::pause() void xmrig::Miner::printHashrate(bool details) { + char num[8 * 4] = { 0 }; + double speed[3] = { 0.0 }; + for (IBackend *backend : d_ptr->backends) { + const Hashrate *hashrate = backend->hashrate(); + if (hashrate) { + speed[0] += hashrate->calc(Hashrate::ShortInterval); + speed[1] += hashrate->calc(Hashrate::MediumInterval); + speed[2] += hashrate->calc(Hashrate::LargeInterval); + } + backend->printHashrate(details); } + + LOG_INFO(WHITE_BOLD("speed") " 10s/60s/15m " CYAN_BOLD("%s") CYAN(" %s %s ") CYAN_BOLD("H/s") " max " CYAN_BOLD("%s H/s"), + Hashrate::format(speed[0], num, sizeof(num) / 4), + Hashrate::format(speed[1], num + 8, sizeof(num) / 4), + Hashrate::format(speed[2], num + 8 * 2, sizeof(num) / 4 ), + Hashrate::format(d_ptr->maxHashrate, num + 8 * 3, sizeof(num) / 4) + ); } @@ -203,10 +226,18 @@ void xmrig::Miner::stop() void xmrig::Miner::onTimer(const Timer *) { + double maxHashrate = 0.0; + for (IBackend *backend : d_ptr->backends) { backend->tick(d_ptr->ticks); + + if (backend->hashrate()) { + maxHashrate += backend->hashrate()->calc(Hashrate::ShortInterval); + } } + d_ptr->maxHashrate = std::max(d_ptr->maxHashrate, maxHashrate); + if ((d_ptr->ticks % (d_ptr->controller->config()->printTime() * 2)) == 0) { printHashrate(false); } diff --git a/src/core/Miner.h b/src/core/Miner.h index e7904575..f32524a7 100644 --- a/src/core/Miner.h +++ b/src/core/Miner.h @@ -26,6 +26,9 @@ #define XMRIG_MINER_H +#include + + #include "base/kernel/interfaces/ITimerListener.h" @@ -35,6 +38,7 @@ namespace xmrig { class Controller; class Job; class MinerPrivate; +class IBackend; class Miner : public ITimerListener @@ -44,6 +48,7 @@ public: ~Miner() override; bool isEnabled() const; + const std::vector &backends() const; Job job() const; void pause(); void printHashrate(bool details); diff --git a/src/workers/WorkersLegacy.cpp b/src/workers/WorkersLegacy.cpp index 29571608..0db0a3cf 100644 --- a/src/workers/WorkersLegacy.cpp +++ b/src/workers/WorkersLegacy.cpp @@ -40,13 +40,13 @@ #include "crypto/rx/RxDataset.h" #include "Mem.h" #include "rapidjson/document.h" -#include "workers/Hashrate.h" +//#include "workers/Hashrate.h" #include "workers/WorkersLegacy.h" bool WorkersLegacy::m_active = false; bool WorkersLegacy::m_enabled = true; -Hashrate *WorkersLegacy::m_hashrate = nullptr; +//Hashrate *WorkersLegacy::m_hashrate = nullptr; xmrig::Job WorkersLegacy::m_job; WorkersLegacy::LaunchStatus WorkersLegacy::m_status; std::vector* > WorkersLegacy::m_workers; @@ -96,38 +96,6 @@ size_t WorkersLegacy::threads() //} -//void Workers::printHashrate(bool detail) -//{ -// assert(m_controller != nullptr); -// if (!m_controller) { -// return; -// } - -// if (detail) { -// char num1[8] = { 0 }; -// char num2[8] = { 0 }; -// char num3[8] = { 0 }; - -// xmrig::Log::print(WHITE_BOLD_S "| THREAD | AFFINITY | 10s H/s | 60s H/s | 15m H/s |"); - -// size_t i = 0; -// for (const xmrig::IThread *thread : m_controller->config()->threads()) { -// xmrig::Log::print("| %6zu | %8" PRId64 " | %7s | %7s | %7s |", -// thread->index(), -// thread->affinity(), -// Hashrate::format(m_hashrate->calc(thread->index(), Hashrate::ShortInterval), num1, sizeof num1), -// Hashrate::format(m_hashrate->calc(thread->index(), Hashrate::MediumInterval), num2, sizeof num2), -// Hashrate::format(m_hashrate->calc(thread->index(), Hashrate::LargeInterval), num3, sizeof num3) -// ); - -// i++; -// } -// } - -// m_hashrate->print(); -//} - - //void Workers::setEnabled(bool enabled) //{ // if (m_enabled == enabled) { @@ -186,7 +154,7 @@ void WorkersLegacy::start(xmrig::Controller *controller) m_status.ways += thread.intensity(); } - m_hashrate = new Hashrate(threads.size(), controller); +// m_hashrate = new Hashrate(threads.size(), controller); uv_mutex_init(&m_mutex); uv_rwlock_init(&m_rwlock); @@ -238,66 +206,24 @@ void WorkersLegacy::threadsSummary(rapidjson::Document &doc) #endif -//void WorkersLegacy::onReady(void *arg) +//void WorkersLegacy::onTick(uv_timer_t *) //{ // using namespace xmrig; -// auto handle = static_cast* >(arg); +// for (Thread *handle : m_workers) { +// if (!handle->worker()) { +// return; +// } -// xmrig::IWorker *worker = nullptr; - -// switch (handle->config().intensity) { -// case 1: -// worker = new CpuWorker<1>(handle->index(), handle->config()); -// break; - -// case 2: -// worker = new CpuWorker<2>(handle->index(), handle->config()); -// break; - -// case 3: -// worker = new CpuWorker<3>(handle->index(), handle->config()); -// break; - -// case 4: -// worker = new CpuWorker<4>(handle->index(), handle->config()); -// break; - -// case 5: -// worker = new CpuWorker<5>(handle->index(), handle->config()); -// break; +// m_hashrate->add(handle->index(), handle->worker()->hashCount(), handle->worker()->timestamp()); // } -// handle->setWorker(worker); - -// if (!worker->selfTest()) { -// LOG_ERR("thread %zu error: \"hash self-test failed\".", handle->worker()->id()); - -// return; +// if ((m_ticks++ & 0xF) == 0) { +// m_hashrate->updateHighest(); // } - -// start(worker); //} -void WorkersLegacy::onTick(uv_timer_t *) -{ - using namespace xmrig; - - for (Thread *handle : m_workers) { - if (!handle->worker()) { - return; - } - - m_hashrate->add(handle->index(), handle->worker()->hashCount(), handle->worker()->timestamp()); - } - - if ((m_ticks++ & 0xF) == 0) { - m_hashrate->updateHighest(); - } -} - - void WorkersLegacy::start(xmrig::IWorker *worker) { // const Worker *w = static_cast(worker); diff --git a/src/workers/WorkersLegacy.h b/src/workers/WorkersLegacy.h index 5ee53dbf..be9e417a 100644 --- a/src/workers/WorkersLegacy.h +++ b/src/workers/WorkersLegacy.h @@ -42,7 +42,7 @@ #include "rapidjson/fwd.h" -class Hashrate; +//class Hashrate; namespace xmrig { @@ -66,7 +66,7 @@ public: // static xmrig::Job job(); // static inline bool isEnabled() { return m_enabled; } - static inline Hashrate *hashrate() { return m_hashrate; } +// static inline Hashrate *hashrate() { return m_hashrate; } # ifdef XMRIG_FEATURE_API static void threadsSummary(rapidjson::Document &doc); @@ -74,7 +74,7 @@ public: private: // static void onReady(void *arg); - static void onTick(uv_timer_t *handle); +// static void onTick(uv_timer_t *handle); static void start(xmrig::IWorker *worker); class LaunchStatus @@ -98,7 +98,7 @@ private: static bool m_active; static bool m_enabled; - static Hashrate *m_hashrate; +// static Hashrate *m_hashrate; static xmrig::Job m_job; static LaunchStatus m_status; static std::vector* > m_workers; From 20313cbc569442f1a7440607c7885ade2f207241 Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 17 Jul 2019 04:33:11 +0700 Subject: [PATCH 28/48] Implemented unified cryptonight and RandomX scratchpad memory. --- CMakeLists.txt | 2 + src/Mem.cpp | 51 ------------------ src/Mem.h | 2 - src/api/v1/ApiRouter.cpp | 2 +- src/backend/common/Worker.h | 7 +-- src/backend/common/interfaces/IWorker.h | 14 +++-- src/backend/cpu/CpuBackend.cpp | 10 ++-- src/backend/cpu/CpuWorker.cpp | 48 ++++++++++++----- src/backend/cpu/CpuWorker.h | 7 +-- src/crypto/cn/CnCtx.cpp | 60 +++++++++++++++++++++ src/crypto/cn/CnCtx.h | 52 ++++++++++++++++++ src/crypto/common/VirtualMemory.h | 20 +++++++ src/crypto/common/VirtualMemory_unix.cpp | 42 +++++++++++++++ src/crypto/common/VirtualMemory_win.cpp | 31 +++++++++++ src/crypto/randomx/randomx.cpp | 44 +++------------ src/crypto/randomx/randomx.h | 2 +- src/crypto/randomx/virtual_machine.cpp | 40 ++++++-------- src/crypto/randomx/virtual_machine.hpp | 19 ++++--- src/crypto/randomx/vm_compiled.cpp | 22 ++++---- src/crypto/randomx/vm_compiled.hpp | 28 +++++----- src/crypto/randomx/vm_compiled_light.cpp | 20 ++++--- src/crypto/randomx/vm_compiled_light.hpp | 27 +++++----- src/crypto/randomx/vm_interpreted.cpp | 30 +++++------ src/crypto/randomx/vm_interpreted.hpp | 31 ++++++----- src/crypto/randomx/vm_interpreted_light.cpp | 14 +++-- src/crypto/randomx/vm_interpreted_light.hpp | 18 ++++--- src/crypto/rx/RxVm.cpp | 18 +------ src/crypto/rx/RxVm.h | 2 +- src/workers/WorkersLegacy.cpp | 58 ++++++++++---------- src/workers/WorkersLegacy.h | 10 ++-- 30 files changed, 434 insertions(+), 297 deletions(-) create mode 100644 src/crypto/cn/CnCtx.cpp create mode 100644 src/crypto/cn/CnCtx.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 543836c8..f8a56c48 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,6 +54,7 @@ set(HEADERS_CRYPTO src/crypto/cn/c_jh.h src/crypto/cn/c_skein.h src/crypto/cn/CnAlgo.h + src/crypto/cn/CnCtx.h src/crypto/cn/CnHash.h src/crypto/cn/CryptoNight_monero.h src/crypto/cn/CryptoNight_test.h @@ -100,6 +101,7 @@ set(SOURCES_CRYPTO src/crypto/cn/c_groestl.c src/crypto/cn/c_jh.c src/crypto/cn/c_skein.c + src/crypto/cn/CnCtx.cpp src/crypto/cn/CnHash.cpp src/crypto/common/Algorithm.cpp src/crypto/common/keccak.cpp diff --git a/src/Mem.cpp b/src/Mem.cpp index e8eabe3b..5fcea306 100644 --- a/src/Mem.cpp +++ b/src/Mem.cpp @@ -24,59 +24,8 @@ */ -#include - - -#include "crypto/cn/CryptoNight.h" -#include "crypto/common/portable/mm_malloc.h" -#include "crypto/common/VirtualMemory.h" #include "Mem.h" bool Mem::m_enabled = true; int Mem::m_flags = 0; - - -MemInfo Mem::create(cryptonight_ctx **ctx, const xmrig::Algorithm &algorithm, size_t count) -{ - using namespace xmrig; - - constexpr CnAlgo props; - - MemInfo info; - info.size = props.memory(algorithm.id()) * count; - - constexpr const size_t align_size = 2 * 1024 * 1024; - info.size = ((info.size + align_size - 1) / align_size) * align_size; - info.pages = info.size / align_size; - - allocate(info, m_enabled); - - for (size_t i = 0; i < count; ++i) { - cryptonight_ctx *c = static_cast(_mm_malloc(sizeof(cryptonight_ctx), 4096)); - c->memory = info.memory + (i * props.memory(algorithm.id())); - - c->generated_code = reinterpret_cast(VirtualMemory::allocateExecutableMemory(0x4000)); - c->generated_code_data.algo = Algorithm::INVALID; - c->generated_code_data.height = std::numeric_limits::max(); - - ctx[i] = c; - } - - return info; -} - - -void Mem::release(cryptonight_ctx **ctx, size_t count, MemInfo &info) -{ - if (info.memory == nullptr) { - return; - } - - release(info); - - for (size_t i = 0; i < count; ++i) { - _mm_free(ctx[i]); - } -} - diff --git a/src/Mem.h b/src/Mem.h index 5c60d281..8e5c418b 100644 --- a/src/Mem.h +++ b/src/Mem.h @@ -56,9 +56,7 @@ public: Lock = 4 }; - static MemInfo create(cryptonight_ctx **ctx, const xmrig::Algorithm &algorithm, size_t count); static void init(bool enabled); - static void release(cryptonight_ctx **ctx, size_t count, MemInfo &info); static inline bool isHugepagesAvailable() { return (m_flags & HugepagesAvailable) != 0; } diff --git a/src/api/v1/ApiRouter.cpp b/src/api/v1/ApiRouter.cpp index 48a92c93..2e6a815c 100644 --- a/src/api/v1/ApiRouter.cpp +++ b/src/api/v1/ApiRouter.cpp @@ -144,7 +144,7 @@ void xmrig::ApiRouter::getMiner(rapidjson::Value &reply, rapidjson::Document &do reply.AddMember("kind", APP_KIND, allocator); reply.AddMember("ua", StringRef(Platform::userAgent()), allocator); reply.AddMember("cpu", cpu, allocator); - reply.AddMember("hugepages", WorkersLegacy::hugePages() > 0, allocator); + reply.AddMember("hugepages", false, allocator); // FIXME hugepages reply.AddMember("donate_level", m_base->config()->pools().donateLevel(), allocator); } diff --git a/src/backend/common/Worker.h b/src/backend/common/Worker.h index 3223a60c..faebf128 100644 --- a/src/backend/common/Worker.h +++ b/src/backend/common/Worker.h @@ -42,9 +42,10 @@ class Worker : public IWorker public: Worker(size_t id, int64_t affinity, int priority); - inline size_t id() const override { return m_id; } - inline uint64_t hashCount() const override { return m_hashCount.load(std::memory_order_relaxed); } - inline uint64_t timestamp() const override { return m_timestamp.load(std::memory_order_relaxed); } + inline const VirtualMemory *memory() const override { return nullptr; } + inline size_t id() const override { return m_id; } + inline uint64_t hashCount() const override { return m_hashCount.load(std::memory_order_relaxed); } + inline uint64_t timestamp() const override { return m_timestamp.load(std::memory_order_relaxed); } protected: void storeStats(); diff --git a/src/backend/common/interfaces/IWorker.h b/src/backend/common/interfaces/IWorker.h index de22de02..5c99680b 100644 --- a/src/backend/common/interfaces/IWorker.h +++ b/src/backend/common/interfaces/IWorker.h @@ -32,16 +32,20 @@ namespace xmrig { +class VirtualMemory; + + class IWorker { public: virtual ~IWorker() = default; - virtual bool selfTest() = 0; - virtual size_t id() const = 0; - virtual uint64_t hashCount() const = 0; - virtual uint64_t timestamp() const = 0; - virtual void start() = 0; + virtual bool selfTest() = 0; + virtual const VirtualMemory *memory() const = 0; + virtual size_t id() const = 0; + virtual uint64_t hashCount() const = 0; + virtual uint64_t timestamp() const = 0; + virtual void start() = 0; }; diff --git a/src/backend/cpu/CpuBackend.cpp b/src/backend/cpu/CpuBackend.cpp index c8d38ca6..a0463832 100644 --- a/src/backend/cpu/CpuBackend.cpp +++ b/src/backend/cpu/CpuBackend.cpp @@ -136,14 +136,10 @@ void xmrig::CpuBackend::printHashrate(bool details) void xmrig::CpuBackend::setJob(const Job &job) { - LOG_WARN("PROFILE %s %zu", d_ptr->controller->config()->cpu().threads().profileName(job.algorithm()).data(), job.algorithm().memory()); - if (d_ptr->isReady(job.algorithm())) { return; } - LOG_INFO(GREEN_BOLD_S "INIT"); - const CpuConfig &cpu = d_ptr->controller->config()->cpu(); const Threads &threads = cpu.threads(); @@ -151,7 +147,11 @@ void xmrig::CpuBackend::setJob(const Job &job) d_ptr->profileName = threads.profileName(job.algorithm()); d_ptr->threads = threads.get(d_ptr->profileName); - LOG_INFO(BLUE_BG_S " %zu ", d_ptr->threads.size()); + LOG_INFO(GREEN_BOLD("CPU") " use profile " BLUE_BG(WHITE_BOLD_S " %s ") WHITE_BOLD_S " (" CYAN_BOLD("%zu") WHITE_BOLD(" threads)") " scratchpad " CYAN_BOLD("%zu KB"), + d_ptr->profileName.data(), + d_ptr->threads.size(), + d_ptr->algo.memory() / 1024 + ); d_ptr->workers.stop(); diff --git a/src/backend/cpu/CpuWorker.cpp b/src/backend/cpu/CpuWorker.cpp index 96466252..356dfb1b 100644 --- a/src/backend/cpu/CpuWorker.cpp +++ b/src/backend/cpu/CpuWorker.cpp @@ -29,8 +29,10 @@ #include "backend/cpu/CpuWorker.h" #include "core/Miner.h" +#include "crypto/cn/CnCtx.h" #include "crypto/cn/CryptoNight_test.h" #include "crypto/common/Nonce.h" +#include "crypto/common/VirtualMemory.h" #include "crypto/rx/Rx.h" #include "crypto/rx/RxVm.h" #include "net/JobResults.h" @@ -56,18 +58,18 @@ xmrig::CpuWorker::CpuWorker(size_t index, const CpuLaunchData &data) : m_assembly(data.assembly), m_hwAES(data.hwAES), m_av(data.av()), - m_miner(data.miner) + m_miner(data.miner), + m_ctx() { - if (m_algorithm.family() != Algorithm::RANDOM_X) { - m_memory = Mem::create(m_ctx, m_algorithm, N); - } + m_memory = new VirtualMemory(m_algorithm.memory() * N, data.hugePages); } template xmrig::CpuWorker::~CpuWorker() { - Mem::release(m_ctx, N, m_memory); + CnCtx::release(m_ctx, N); + delete m_memory; # ifdef XMRIG_ALGO_RANDOMX delete m_vm; @@ -81,7 +83,7 @@ void xmrig::CpuWorker::allocateRandomX_VM() { if (!m_vm) { RxDataset *dataset = Rx::dataset(m_job.currentJob().seedHash(), m_job.currentJob().algorithm()); - m_vm = new RxVm(dataset, true, !m_hwAES); + m_vm = new RxVm(dataset, m_memory->scratchpad(), !m_hwAES); } } #endif @@ -90,6 +92,14 @@ void xmrig::CpuWorker::allocateRandomX_VM() template bool xmrig::CpuWorker::selfTest() { +# ifdef XMRIG_ALGO_RANDOMX + if (m_algorithm.family() == Algorithm::RANDOM_X) { + return true; + } +# endif + + allocateCnCtx(); + if (m_algorithm.family() == Algorithm::CN) { const bool rc = verify(Algorithm::CN_0, test_output_v0) && verify(Algorithm::CN_1, test_output_v1) && @@ -136,12 +146,6 @@ bool xmrig::CpuWorker::selfTest() } # endif -# ifdef XMRIG_ALGO_RANDOMX - if (m_algorithm.family() == Algorithm::RANDOM_X) { - return true; - } -# endif - return false; } @@ -172,7 +176,6 @@ void xmrig::CpuWorker::start() # ifdef XMRIG_ALGO_RANDOMX if (job.algorithm().family() == Algorithm::RANDOM_X) { - allocateRandomX_VM(); randomx_calculate_hash(m_vm->get(), m_job.blob(), job.size(), m_hash); } else @@ -262,10 +265,29 @@ bool CpuWorker<1>::verify2(const Algorithm &algorithm, const uint8_t *referenceV } // namespace xmrig +template +void xmrig::CpuWorker::allocateCnCtx() +{ + if (m_ctx[0] == nullptr) { + CnCtx::create(m_ctx, m_memory->scratchpad(), m_memory->size(), N); + } +} + + template void xmrig::CpuWorker::consumeJob() { m_job.add(m_miner->job(), Nonce::sequence(Nonce::CPU), kReserveCount); + +# ifdef XMRIG_ALGO_RANDOMX + if (m_job.currentJob().algorithm().family() == Algorithm::RANDOM_X) { + allocateRandomX_VM(); + } + else +# endif + { + allocateCnCtx(); + } } diff --git a/src/backend/cpu/CpuWorker.h b/src/backend/cpu/CpuWorker.h index c67d355b..c0f9dfaf 100644 --- a/src/backend/cpu/CpuWorker.h +++ b/src/backend/cpu/CpuWorker.h @@ -48,12 +48,12 @@ public: CpuWorker(size_t index, const CpuLaunchData &data); ~CpuWorker() override; - inline const MemInfo &memory() const { return m_memory; } - protected: bool selfTest() override; void start() override; + inline const VirtualMemory *memory() const override { return m_memory; } + private: inline cn_hash_fun fn(const Algorithm &algorithm) const { return CnHash::fn(algorithm, m_av, m_assembly); } @@ -63,6 +63,7 @@ private: bool verify(const Algorithm &algorithm, const uint8_t *referenceValue); bool verify2(const Algorithm &algorithm, const uint8_t *referenceValue); + void allocateCnCtx(); void consumeJob(); const Algorithm m_algorithm; @@ -71,8 +72,8 @@ private: const CnHash::AlgoVariant m_av; const Miner *m_miner; cryptonight_ctx *m_ctx[N]; - MemInfo m_memory; uint8_t m_hash[N * 32]; + VirtualMemory *m_memory = nullptr; WorkerJob m_job; # ifdef XMRIG_ALGO_RANDOMX diff --git a/src/crypto/cn/CnCtx.cpp b/src/crypto/cn/CnCtx.cpp new file mode 100644 index 00000000..5d41bca0 --- /dev/null +++ b/src/crypto/cn/CnCtx.cpp @@ -0,0 +1,60 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2019 XMR-Stak , + * Copyright 2018 Lee Clagett + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + + +#include "crypto/cn/CnCtx.h" +#include "crypto/cn/CryptoNight.h" +#include "crypto/common/Algorithm.h" +#include "crypto/common/portable/mm_malloc.h" +#include "crypto/common/VirtualMemory.h" + + +void xmrig::CnCtx::create(cryptonight_ctx **ctx, uint8_t *memory, size_t size, size_t count) +{ + for (size_t i = 0; i < count; ++i) { + cryptonight_ctx *c = static_cast(_mm_malloc(sizeof(cryptonight_ctx), 4096)); + c->memory = memory + (i * size); + + c->generated_code = reinterpret_cast(VirtualMemory::allocateExecutableMemory(0x4000)); + c->generated_code_data.algo = Algorithm::INVALID; + c->generated_code_data.height = std::numeric_limits::max(); + + ctx[i] = c; + } +} + + +void xmrig::CnCtx::release(cryptonight_ctx **ctx, size_t count) +{ + if (ctx[0] == nullptr) { + return; + } + + for (size_t i = 0; i < count; ++i) { + _mm_free(ctx[i]); + } +} diff --git a/src/crypto/cn/CnCtx.h b/src/crypto/cn/CnCtx.h new file mode 100644 index 00000000..7b0adbec --- /dev/null +++ b/src/crypto/cn/CnCtx.h @@ -0,0 +1,52 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2019 XMR-Stak , + * Copyright 2018 Lee Clagett + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_CN_CTX_H +#define XMRIG_CN_CTX_H + + +#include +#include + + +struct cryptonight_ctx; + + +namespace xmrig +{ + + +class CnCtx +{ +public: + static void create(cryptonight_ctx **ctx, uint8_t *memory, size_t size, size_t count); + static void release(cryptonight_ctx **ctx, size_t count); +}; + + +} /* namespace xmrig */ + + +#endif /* XMRIG_CN_CTX_H */ diff --git a/src/crypto/common/VirtualMemory.h b/src/crypto/common/VirtualMemory.h index a83c35ed..98212e40 100644 --- a/src/crypto/common/VirtualMemory.h +++ b/src/crypto/common/VirtualMemory.h @@ -38,6 +38,15 @@ namespace xmrig { class VirtualMemory { public: + inline VirtualMemory() {} + VirtualMemory(size_t size, bool hugePages = true, size_t align = 64); + ~VirtualMemory(); + + inline bool isHugePages() const { return m_flags & HUGEPAGES; } + inline size_t hugePages() const { return isHugePages() ? (align(size()) / 2097152) : 0; } + inline size_t size() const { return m_size; } + inline uint8_t *scratchpad() const { return m_scratchpad; } + static void *allocateExecutableMemory(size_t size); static void *allocateLargePagesMemory(size_t size); static void flushInstructionCache(void *p, size_t size); @@ -46,6 +55,17 @@ public: static void unprotectExecutableMemory(void *p, size_t size); static inline constexpr size_t align(size_t pos, size_t align = 2097152) { return ((pos - 1) / align + 1) * align; } + +private: + enum Flags { + HUGEPAGES_AVAILABLE = 1, + HUGEPAGES = 2, + LOCK = 4 + }; + + int m_flags = 0; + size_t m_size = 0; + uint8_t *m_scratchpad = nullptr; }; diff --git a/src/crypto/common/VirtualMemory_unix.cpp b/src/crypto/common/VirtualMemory_unix.cpp index beac976d..665fc02b 100644 --- a/src/crypto/common/VirtualMemory_unix.cpp +++ b/src/crypto/common/VirtualMemory_unix.cpp @@ -29,6 +29,7 @@ #include +#include "crypto/common/portable/mm_malloc.h" #include "crypto/common/VirtualMemory.h" @@ -37,6 +38,47 @@ #endif +xmrig::VirtualMemory::VirtualMemory(size_t size, bool hugePages, size_t align) : + m_size(VirtualMemory::align(size)) +{ + if (hugePages) { + m_scratchpad = static_cast(allocateLargePagesMemory(m_size)); + if (m_scratchpad) { + m_flags |= HUGEPAGES; + + madvise(m_scratchpad, size, MADV_RANDOM | MADV_WILLNEED); + + if (mlock(m_scratchpad, m_size) == 0) { + m_flags |= LOCK; + } + + return; + } + } + + m_scratchpad = static_cast(_mm_malloc(m_size, align)); +} + + +xmrig::VirtualMemory::~VirtualMemory() +{ + if (!m_scratchpad) { + return; + } + + if (isHugePages()) { + if (m_flags & LOCK) { + munlock(m_scratchpad, m_size); + } + + freeLargePagesMemory(m_scratchpad, m_size); + } + else { + _mm_free(m_scratchpad); + } +} + + void *xmrig::VirtualMemory::allocateExecutableMemory(size_t size) { diff --git a/src/crypto/common/VirtualMemory_win.cpp b/src/crypto/common/VirtualMemory_win.cpp index 7f1d6f43..7aa98f89 100644 --- a/src/crypto/common/VirtualMemory_win.cpp +++ b/src/crypto/common/VirtualMemory_win.cpp @@ -32,6 +32,37 @@ #include "crypto/common/VirtualMemory.h" +xmrig::VirtualMemory::VirtualMemory(size_t size, bool hugePages, size_t align) : + m_size(VirtualMemory::align(size)) +{ + if (hugePages) { + m_scratchpad = static_cast(allocateLargePagesMemory(m_size)); + if (m_scratchpad) { + m_flags |= HUGEPAGES; + + return; + } + } + + m_scratchpad = static_cast(_mm_malloc(m_size, align)); +} + + +xmrig::VirtualMemory::~VirtualMemory() +{ + if (!m_scratchpad) { + return; + } + + if (isHugePages()) { + freeLargePagesMemory(m_scratchpad, m_size); + } + else { + _mm_free(m_scratchpad); + } +} + + void *xmrig::VirtualMemory::allocateExecutableMemory(size_t size) { return VirtualAlloc(nullptr, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); diff --git a/src/crypto/randomx/randomx.cpp b/src/crypto/randomx/randomx.cpp index dde838b9..df5fc9cb 100644 --- a/src/crypto/randomx/randomx.cpp +++ b/src/crypto/randomx/randomx.cpp @@ -345,7 +345,7 @@ extern "C" { delete dataset; } - randomx_vm *randomx_create_vm(randomx_flags flags, randomx_cache *cache, randomx_dataset *dataset) { + randomx_vm *randomx_create_vm(randomx_flags flags, randomx_cache *cache, randomx_dataset *dataset, uint8_t *scratchpad) { assert(cache != nullptr || (flags & RANDOMX_FLAG_FULL_MEM)); assert(cache == nullptr || cache->isInitialized()); assert(dataset != nullptr || !(flags & RANDOMX_FLAG_FULL_MEM)); @@ -353,7 +353,7 @@ extern "C" { randomx_vm *vm = nullptr; try { - switch (flags & (RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_JIT | RANDOMX_FLAG_HARD_AES | RANDOMX_FLAG_LARGE_PAGES)) { + switch (flags & (RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_JIT | RANDOMX_FLAG_HARD_AES)) { case RANDOMX_FLAG_DEFAULT: vm = new randomx::InterpretedLightVmDefault(); break; @@ -386,49 +386,19 @@ extern "C" { vm = new randomx::CompiledVmHardAes(); break; - case RANDOMX_FLAG_LARGE_PAGES: - vm = new randomx::InterpretedLightVmLargePage(); - break; - - case RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_LARGE_PAGES: - vm = new randomx::InterpretedVmLargePage(); - break; - - case RANDOMX_FLAG_JIT | RANDOMX_FLAG_LARGE_PAGES: - vm = new randomx::CompiledLightVmLargePage(); - break; - - case RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_JIT | RANDOMX_FLAG_LARGE_PAGES: - vm = new randomx::CompiledVmLargePage(); - break; - - case RANDOMX_FLAG_HARD_AES | RANDOMX_FLAG_LARGE_PAGES: - vm = new randomx::InterpretedLightVmLargePageHardAes(); - break; - - case RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_HARD_AES | RANDOMX_FLAG_LARGE_PAGES: - vm = new randomx::InterpretedVmLargePageHardAes(); - break; - - case RANDOMX_FLAG_JIT | RANDOMX_FLAG_HARD_AES | RANDOMX_FLAG_LARGE_PAGES: - vm = new randomx::CompiledLightVmLargePageHardAes(); - break; - - case RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_JIT | RANDOMX_FLAG_HARD_AES | RANDOMX_FLAG_LARGE_PAGES: - vm = new randomx::CompiledVmLargePageHardAes(); - break; - default: UNREACHABLE; } - if(cache != nullptr) + if (cache != nullptr) { vm->setCache(cache); + } - if(dataset != nullptr) + if (dataset != nullptr) { vm->setDataset(dataset); + } - vm->allocate(); + vm->setScratchpad(scratchpad); } catch (std::exception &ex) { delete vm; diff --git a/src/crypto/randomx/randomx.h b/src/crypto/randomx/randomx.h index cd07ac64..d688189f 100644 --- a/src/crypto/randomx/randomx.h +++ b/src/crypto/randomx/randomx.h @@ -286,7 +286,7 @@ RANDOMX_EXPORT void randomx_release_dataset(randomx_dataset *dataset); * (3) cache parameter is NULL and RANDOMX_FLAG_FULL_MEM is not set * (4) dataset parameter is NULL and RANDOMX_FLAG_FULL_MEM is set */ -RANDOMX_EXPORT randomx_vm *randomx_create_vm(randomx_flags flags, randomx_cache *cache, randomx_dataset *dataset); +RANDOMX_EXPORT randomx_vm *randomx_create_vm(randomx_flags flags, randomx_cache *cache, randomx_dataset *dataset, uint8_t *scratchpad); /** * Reinitializes a virtual machine with a new Cache. This function should be called anytime diff --git a/src/crypto/randomx/virtual_machine.cpp b/src/crypto/randomx/virtual_machine.cpp index caa1efbf..6560dc95 100644 --- a/src/crypto/randomx/virtual_machine.cpp +++ b/src/crypto/randomx/virtual_machine.cpp @@ -95,43 +95,35 @@ void randomx_vm::initialize() { namespace randomx { - alignas(16) volatile static rx_vec_i128 aesDummy; - - template - VmBase::~VmBase() { - Allocator::freeMemory(scratchpad, RANDOMX_SCRATCHPAD_L3_MAX_SIZE); + template + VmBase::~VmBase() { } - template - void VmBase::allocate() { - if (datasetPtr == nullptr) + template + void VmBase::setScratchpad(uint8_t *scratchpad) { + if (datasetPtr == nullptr) { throw std::invalid_argument("Cache/Dataset not set"); - if (!softAes) { //if hardware AES is not supported, it's better to fail now than to return a ticking bomb - rx_vec_i128 tmp = rx_load_vec_i128((const rx_vec_i128*)&aesDummy); - tmp = rx_aesenc_vec_i128(tmp, tmp); - rx_store_vec_i128((rx_vec_i128*)&aesDummy, tmp); } - scratchpad = (uint8_t*)Allocator::allocMemory(RANDOMX_SCRATCHPAD_L3_MAX_SIZE); + + this->scratchpad = scratchpad; } - template - void VmBase::getFinalResult(void* out, size_t outSize) { + template + void VmBase::getFinalResult(void* out, size_t outSize) { hashAes1Rx4(scratchpad, ScratchpadSize, ®.a); blake2b(out, outSize, ®, sizeof(RegisterFile), nullptr, 0); } - template - void VmBase::initScratchpad(void* seed) { + template + void VmBase::initScratchpad(void* seed) { fillAes1Rx4(seed, ScratchpadSize, scratchpad); } - template - void VmBase::generateProgram(void* seed) { + template + void VmBase::generateProgram(void* seed) { fillAes4Rx4(seed, sizeof(program), &program); } - template class VmBase, false>; - template class VmBase, true>; - template class VmBase; - template class VmBase; -} \ No newline at end of file + template class VmBase; + template class VmBase; +} diff --git a/src/crypto/randomx/virtual_machine.hpp b/src/crypto/randomx/virtual_machine.hpp index 488994df..cba79d72 100644 --- a/src/crypto/randomx/virtual_machine.hpp +++ b/src/crypto/randomx/virtual_machine.hpp @@ -33,26 +33,31 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "program.hpp" /* Global namespace for C binding */ -class randomx_vm { +class randomx_vm +{ public: virtual ~randomx_vm() = 0; - virtual void allocate() = 0; + virtual void setScratchpad(uint8_t *scratchpad) = 0; virtual void getFinalResult(void* out, size_t outSize) = 0; virtual void setDataset(randomx_dataset* dataset) { } virtual void setCache(randomx_cache* cache) { } virtual void initScratchpad(void* seed) = 0; virtual void run(void* seed) = 0; void resetRoundingMode(); + randomx::RegisterFile *getRegisterFile() { return ® } + const void* getScratchpad() { return scratchpad; } + const randomx::Program& getProgram() { return program; } + protected: void initialize(); alignas(64) randomx::Program program; @@ -69,15 +74,17 @@ protected: namespace randomx { - template - class VmBase : public randomx_vm { + template + class VmBase : public randomx_vm + { public: ~VmBase() override; - void allocate() override; + void setScratchpad(uint8_t *scratchpad) override; void initScratchpad(void* seed) override; void getFinalResult(void* out, size_t outSize) override; + protected: void generateProgram(void* seed); }; -} \ No newline at end of file +} diff --git a/src/crypto/randomx/vm_compiled.cpp b/src/crypto/randomx/vm_compiled.cpp index 7f621a33..4d14c793 100644 --- a/src/crypto/randomx/vm_compiled.cpp +++ b/src/crypto/randomx/vm_compiled.cpp @@ -34,27 +34,25 @@ namespace randomx { static_assert(sizeof(MemoryRegisters) == 2 * sizeof(addr_t) + sizeof(uintptr_t), "Invalid alignment of struct randomx::MemoryRegisters"); static_assert(sizeof(RegisterFile) == 256, "Invalid alignment of struct randomx::RegisterFile"); - template - void CompiledVm::setDataset(randomx_dataset* dataset) { + template + void CompiledVm::setDataset(randomx_dataset* dataset) { datasetPtr = dataset; } - template - void CompiledVm::run(void* seed) { - VmBase::generateProgram(seed); + template + void CompiledVm::run(void* seed) { + VmBase::generateProgram(seed); randomx_vm::initialize(); compiler.generateProgram(program, config); mem.memory = datasetPtr->memory + datasetOffset; execute(); } - template - void CompiledVm::execute() { + template + void CompiledVm::execute() { compiler.getProgramFunc()(reg, mem, scratchpad, RandomX_CurrentConfig.ProgramIterations); } - template class CompiledVm, false>; - template class CompiledVm, true>; - template class CompiledVm; - template class CompiledVm; -} \ No newline at end of file + template class CompiledVm; + template class CompiledVm; +} diff --git a/src/crypto/randomx/vm_compiled.hpp b/src/crypto/randomx/vm_compiled.hpp index 856f00d8..05b34b9c 100644 --- a/src/crypto/randomx/vm_compiled.hpp +++ b/src/crypto/randomx/vm_compiled.hpp @@ -37,8 +37,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace randomx { - template - class CompiledVm : public VmBase { + template + class CompiledVm : public VmBase + { public: void* operator new(size_t size) { void* ptr = AlignedAllocator::allocMemory(size); @@ -46,27 +47,28 @@ namespace randomx { throw std::bad_alloc(); return ptr; } + void operator delete(void* ptr) { AlignedAllocator::freeMemory(ptr, sizeof(CompiledVm)); } + void setDataset(randomx_dataset* dataset) override; void run(void* seed) override; - using VmBase::mem; - using VmBase::program; - using VmBase::config; - using VmBase::reg; - using VmBase::scratchpad; - using VmBase::datasetPtr; - using VmBase::datasetOffset; + using VmBase::mem; + using VmBase::program; + using VmBase::config; + using VmBase::reg; + using VmBase::scratchpad; + using VmBase::datasetPtr; + using VmBase::datasetOffset; + protected: void execute(); JitCompiler compiler; }; - using CompiledVmDefault = CompiledVm, true>; - using CompiledVmHardAes = CompiledVm, false>; - using CompiledVmLargePage = CompiledVm; - using CompiledVmLargePageHardAes = CompiledVm; + using CompiledVmDefault = CompiledVm; + using CompiledVmHardAes = CompiledVm; } diff --git a/src/crypto/randomx/vm_compiled_light.cpp b/src/crypto/randomx/vm_compiled_light.cpp index c083f4aa..6009216b 100644 --- a/src/crypto/randomx/vm_compiled_light.cpp +++ b/src/crypto/randomx/vm_compiled_light.cpp @@ -32,23 +32,21 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace randomx { - template - void CompiledLightVm::setCache(randomx_cache* cache) { + template + void CompiledLightVm::setCache(randomx_cache* cache) { cachePtr = cache; mem.memory = cache->memory; compiler.generateSuperscalarHash(cache->programs, cache->reciprocalCache); } - template - void CompiledLightVm::run(void* seed) { - VmBase::generateProgram(seed); + template + void CompiledLightVm::run(void* seed) { + VmBase::generateProgram(seed); randomx_vm::initialize(); compiler.generateProgramLight(program, config, datasetOffset); - CompiledVm::execute(); + CompiledVm::execute(); } - template class CompiledLightVm, false>; - template class CompiledLightVm, true>; - template class CompiledLightVm; - template class CompiledLightVm; -} \ No newline at end of file + template class CompiledLightVm; + template class CompiledLightVm; +} diff --git a/src/crypto/randomx/vm_compiled_light.hpp b/src/crypto/randomx/vm_compiled_light.hpp index 6af82bbe..6cd3cb20 100644 --- a/src/crypto/randomx/vm_compiled_light.hpp +++ b/src/crypto/randomx/vm_compiled_light.hpp @@ -33,8 +33,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace randomx { - template - class CompiledLightVm : public CompiledVm { + template + class CompiledLightVm : public CompiledVm + { public: void* operator new(size_t size) { void* ptr = AlignedAllocator::allocMemory(size); @@ -42,23 +43,23 @@ namespace randomx { throw std::bad_alloc(); return ptr; } + void operator delete(void* ptr) { AlignedAllocator::freeMemory(ptr, sizeof(CompiledLightVm)); } + void setCache(randomx_cache* cache) override; void setDataset(randomx_dataset* dataset) override { } void run(void* seed) override; - using CompiledVm::mem; - using CompiledVm::compiler; - using CompiledVm::program; - using CompiledVm::config; - using CompiledVm::cachePtr; - using CompiledVm::datasetOffset; + using CompiledVm::mem; + using CompiledVm::compiler; + using CompiledVm::program; + using CompiledVm::config; + using CompiledVm::cachePtr; + using CompiledVm::datasetOffset; }; - using CompiledLightVmDefault = CompiledLightVm, true>; - using CompiledLightVmHardAes = CompiledLightVm, false>; - using CompiledLightVmLargePage = CompiledLightVm; - using CompiledLightVmLargePageHardAes = CompiledLightVm; -} \ No newline at end of file + using CompiledLightVmDefault = CompiledLightVm; + using CompiledLightVmHardAes = CompiledLightVm; +} diff --git a/src/crypto/randomx/vm_interpreted.cpp b/src/crypto/randomx/vm_interpreted.cpp index 236d3efe..f4c1e05c 100644 --- a/src/crypto/randomx/vm_interpreted.cpp +++ b/src/crypto/randomx/vm_interpreted.cpp @@ -33,21 +33,21 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace randomx { - template - void InterpretedVm::setDataset(randomx_dataset* dataset) { + template + void InterpretedVm::setDataset(randomx_dataset* dataset) { datasetPtr = dataset; mem.memory = dataset->memory; } - template - void InterpretedVm::run(void* seed) { - VmBase::generateProgram(seed); + template + void InterpretedVm::run(void* seed) { + VmBase::generateProgram(seed); randomx_vm::initialize(); execute(); } - template - void InterpretedVm::execute() { + template + void InterpretedVm::execute() { NativeRegisterFile nreg; @@ -106,20 +106,18 @@ namespace randomx { rx_store_vec_f128(®.e[i].lo, nreg.e[i]); } - template - void InterpretedVm::datasetRead(uint64_t address, int_reg_t(&r)[RegistersCount]) { + template + void InterpretedVm::datasetRead(uint64_t address, int_reg_t(&r)[RegistersCount]) { uint64_t* datasetLine = (uint64_t*)(mem.memory + address); for (int i = 0; i < RegistersCount; ++i) r[i] ^= datasetLine[i]; } - template - void InterpretedVm::datasetPrefetch(uint64_t address) { + template + void InterpretedVm::datasetPrefetch(uint64_t address) { rx_prefetch_nta(mem.memory + address); } - template class InterpretedVm, false>; - template class InterpretedVm, true>; - template class InterpretedVm; - template class InterpretedVm; -} \ No newline at end of file + template class InterpretedVm; + template class InterpretedVm; +} diff --git a/src/crypto/randomx/vm_interpreted.hpp b/src/crypto/randomx/vm_interpreted.hpp index 99c88852..1dc9ab6d 100644 --- a/src/crypto/randomx/vm_interpreted.hpp +++ b/src/crypto/randomx/vm_interpreted.hpp @@ -38,38 +38,41 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace randomx { - template - class InterpretedVm : public VmBase, public BytecodeMachine { + template + class InterpretedVm : public VmBase, public BytecodeMachine { public: - using VmBase::mem; - using VmBase::scratchpad; - using VmBase::program; - using VmBase::config; - using VmBase::reg; - using VmBase::datasetPtr; - using VmBase::datasetOffset; + using VmBase::mem; + using VmBase::scratchpad; + using VmBase::program; + using VmBase::config; + using VmBase::reg; + using VmBase::datasetPtr; + using VmBase::datasetOffset; + void* operator new(size_t size) { void* ptr = AlignedAllocator::allocMemory(size); if (ptr == nullptr) throw std::bad_alloc(); return ptr; } + void operator delete(void* ptr) { AlignedAllocator::freeMemory(ptr, sizeof(InterpretedVm)); } + void run(void* seed) override; void setDataset(randomx_dataset* dataset) override; + protected: virtual void datasetRead(uint64_t blockNumber, int_reg_t(&r)[RegistersCount]); virtual void datasetPrefetch(uint64_t blockNumber); + private: void execute(); InstructionByteCode bytecode[RANDOMX_PROGRAM_MAX_SIZE]; }; - using InterpretedVmDefault = InterpretedVm, true>; - using InterpretedVmHardAes = InterpretedVm, false>; - using InterpretedVmLargePage = InterpretedVm; - using InterpretedVmLargePageHardAes = InterpretedVm; -} \ No newline at end of file + using InterpretedVmDefault = InterpretedVm; + using InterpretedVmHardAes = InterpretedVm; +} diff --git a/src/crypto/randomx/vm_interpreted_light.cpp b/src/crypto/randomx/vm_interpreted_light.cpp index c54b32f6..9c97187b 100644 --- a/src/crypto/randomx/vm_interpreted_light.cpp +++ b/src/crypto/randomx/vm_interpreted_light.cpp @@ -31,14 +31,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace randomx { - template - void InterpretedLightVm::setCache(randomx_cache* cache) { + template + void InterpretedLightVm::setCache(randomx_cache* cache) { cachePtr = cache; mem.memory = cache->memory; } - template - void InterpretedLightVm::datasetRead(uint64_t address, int_reg_t(&r)[8]) { + template + void InterpretedLightVm::datasetRead(uint64_t address, int_reg_t(&r)[8]) { uint32_t itemNumber = address / CacheLineSize; int_reg_t rl[8]; @@ -48,8 +48,6 @@ namespace randomx { r[q] ^= rl[q]; } - template class InterpretedLightVm, false>; - template class InterpretedLightVm, true>; - template class InterpretedLightVm; - template class InterpretedLightVm; + template class InterpretedLightVm; + template class InterpretedLightVm; } diff --git a/src/crypto/randomx/vm_interpreted_light.hpp b/src/crypto/randomx/vm_interpreted_light.hpp index 02d678f6..1a35c580 100644 --- a/src/crypto/randomx/vm_interpreted_light.hpp +++ b/src/crypto/randomx/vm_interpreted_light.hpp @@ -33,29 +33,31 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace randomx { - template - class InterpretedLightVm : public InterpretedVm { + template + class InterpretedLightVm : public InterpretedVm { public: - using VmBase::mem; - using VmBase::cachePtr; + using VmBase::mem; + using VmBase::cachePtr; + void* operator new(size_t size) { void* ptr = AlignedAllocator::allocMemory(size); if (ptr == nullptr) throw std::bad_alloc(); return ptr; } + void operator delete(void* ptr) { AlignedAllocator::freeMemory(ptr, sizeof(InterpretedLightVm)); } + void setDataset(randomx_dataset* dataset) override { } void setCache(randomx_cache* cache) override; + protected: void datasetRead(uint64_t address, int_reg_t(&r)[8]) override; void datasetPrefetch(uint64_t address) override { } }; - using InterpretedLightVmDefault = InterpretedLightVm, true>; - using InterpretedLightVmHardAes = InterpretedLightVm, false>; - using InterpretedLightVmLargePage = InterpretedLightVm; - using InterpretedLightVmLargePageHardAes = InterpretedLightVm; + using InterpretedLightVmDefault = InterpretedLightVm; + using InterpretedLightVmHardAes = InterpretedLightVm; } diff --git a/src/crypto/rx/RxVm.cpp b/src/crypto/rx/RxVm.cpp index b02f708e..6426443a 100644 --- a/src/crypto/rx/RxVm.cpp +++ b/src/crypto/rx/RxVm.cpp @@ -31,12 +31,8 @@ #include "crypto/rx/RxVm.h" -xmrig::RxVm::RxVm(RxDataset *dataset, bool hugePages, bool softAes) +xmrig::RxVm::RxVm(RxDataset *dataset, uint8_t *scratchpad, bool softAes) { - if (hugePages) { - m_flags |= RANDOMX_FLAG_LARGE_PAGES; - } - if (!softAes) { m_flags |= RANDOMX_FLAG_HARD_AES; } @@ -49,17 +45,7 @@ xmrig::RxVm::RxVm(RxDataset *dataset, bool hugePages, bool softAes) m_flags |= RANDOMX_FLAG_JIT; } - m_vm = randomx_create_vm(static_cast(m_flags), dataset->cache()->get(), dataset->get()); - - if (!m_vm) { - m_flags &= ~RANDOMX_FLAG_LARGE_PAGES; - m_vm = randomx_create_vm(static_cast(m_flags), dataset->cache()->get(), dataset->get()); - } - - if (!m_vm) { - m_flags &= ~RANDOMX_FLAG_HARD_AES; - m_vm = randomx_create_vm(static_cast(m_flags), dataset->cache()->get(), dataset->get()); - } + m_vm = randomx_create_vm(static_cast(m_flags), dataset->cache()->get(), dataset->get(), scratchpad); } diff --git a/src/crypto/rx/RxVm.h b/src/crypto/rx/RxVm.h index 90af8187..d7e617e4 100644 --- a/src/crypto/rx/RxVm.h +++ b/src/crypto/rx/RxVm.h @@ -44,7 +44,7 @@ class RxDataset; class RxVm { public: - RxVm(RxDataset *dataset, bool hugePages, bool softAes); + RxVm(RxDataset *dataset, uint8_t *scratchpad, bool softAes); ~RxVm(); inline randomx_vm *get() const { return m_vm; } diff --git a/src/workers/WorkersLegacy.cpp b/src/workers/WorkersLegacy.cpp index 0db0a3cf..4d6f9de9 100644 --- a/src/workers/WorkersLegacy.cpp +++ b/src/workers/WorkersLegacy.cpp @@ -67,24 +67,24 @@ xmrig::Controller *WorkersLegacy::m_controller = nullptr; //} -size_t WorkersLegacy::hugePages() -{ - uv_mutex_lock(&m_mutex); - const size_t hugePages = m_status.hugePages; - uv_mutex_unlock(&m_mutex); +//size_t WorkersLegacy::hugePages() +//{ +// uv_mutex_lock(&m_mutex); +// const size_t hugePages = m_status.hugePages; +// uv_mutex_unlock(&m_mutex); - return hugePages; -} +// return hugePages; +//} -size_t WorkersLegacy::threads() -{ - uv_mutex_lock(&m_mutex); - const size_t threads = m_status.threads; - uv_mutex_unlock(&m_mutex); +//size_t WorkersLegacy::threads() +//{ +// uv_mutex_lock(&m_mutex); +// const size_t threads = m_status.threads; +// uv_mutex_unlock(&m_mutex); - return threads; -} +// return threads; +//} //void Workers::pause() @@ -186,24 +186,24 @@ void WorkersLegacy::start(xmrig::Controller *controller) //} -#ifdef XMRIG_FEATURE_API -void WorkersLegacy::threadsSummary(rapidjson::Document &doc) -{ - uv_mutex_lock(&m_mutex); - const uint64_t pages[2] = { m_status.hugePages, m_status.pages }; - const uint64_t memory = m_status.ways * xmrig::CnAlgo<>::memory(m_status.algo); - uv_mutex_unlock(&m_mutex); +//#ifdef XMRIG_FEATURE_API +//void WorkersLegacy::threadsSummary(rapidjson::Document &doc) +//{ +// uv_mutex_lock(&m_mutex); +// const uint64_t pages[2] = { m_status.hugePages, m_status.pages }; +// const uint64_t memory = m_status.ways * xmrig::CnAlgo<>::memory(m_status.algo); +// uv_mutex_unlock(&m_mutex); - auto &allocator = doc.GetAllocator(); +// auto &allocator = doc.GetAllocator(); - rapidjson::Value hugepages(rapidjson::kArrayType); - hugepages.PushBack(pages[0], allocator); - hugepages.PushBack(pages[1], allocator); +// rapidjson::Value hugepages(rapidjson::kArrayType); +// hugepages.PushBack(pages[0], allocator); +// hugepages.PushBack(pages[1], allocator); - doc.AddMember("hugepages", hugepages, allocator); - doc.AddMember("memory", memory, allocator); -} -#endif +// doc.AddMember("hugepages", hugepages, allocator); +// doc.AddMember("memory", memory, allocator); +//} +//#endif //void WorkersLegacy::onTick(uv_timer_t *) diff --git a/src/workers/WorkersLegacy.h b/src/workers/WorkersLegacy.h index be9e417a..d8ab1e59 100644 --- a/src/workers/WorkersLegacy.h +++ b/src/workers/WorkersLegacy.h @@ -55,8 +55,8 @@ namespace xmrig { class WorkersLegacy { public: - static size_t hugePages(); - static size_t threads(); +// static size_t hugePages(); +// static size_t threads(); // static void pause(); // static void printHashrate(bool detail); // static void setEnabled(bool enabled); @@ -68,9 +68,9 @@ public: // static inline bool isEnabled() { return m_enabled; } // static inline Hashrate *hashrate() { return m_hashrate; } -# ifdef XMRIG_FEATURE_API - static void threadsSummary(rapidjson::Document &doc); -# endif +//# ifdef XMRIG_FEATURE_API +// static void threadsSummary(rapidjson::Document &doc); +//# endif private: // static void onReady(void *arg); From 2bf5ffb2df492734ffc69db1582effac4d28607f Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 17 Jul 2019 04:57:58 +0700 Subject: [PATCH 29/48] Class Mem replaced to VirtualMemory. --- CMakeLists.txt | 5 - src/App.cpp | 4 +- src/Mem.cpp | 31 ---- src/Mem.h | 72 --------- src/Mem_unix.cpp | 88 ----------- src/Mem_win.cpp | 184 ----------------------- src/Summary.cpp | 4 +- src/backend/common/interfaces/IWorker.h | 1 + src/core/Miner.cpp | 1 + src/crypto/common/VirtualMemory.h | 4 + src/crypto/common/VirtualMemory_unix.cpp | 11 ++ src/crypto/common/VirtualMemory_win.cpp | 126 ++++++++++++++++ 12 files changed, 147 insertions(+), 384 deletions(-) delete mode 100644 src/Mem.cpp delete mode 100644 src/Mem.h delete mode 100644 src/Mem_unix.cpp delete mode 100644 src/Mem_win.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index f8a56c48..97491518 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,7 +34,6 @@ set(HEADERS src/core/config/usage.h src/core/Controller.h src/core/Miner.h - src/Mem.h src/net/interfaces/IJobResultListener.h src/net/JobResult.h src/net/JobResults.h @@ -85,7 +84,6 @@ set(SOURCES src/core/config/ConfigTransform.cpp src/core/Controller.cpp src/core/Miner.cpp - src/Mem.cpp src/net/JobResults.cpp src/net/Network.cpp src/net/NetworkState.cpp @@ -113,7 +111,6 @@ if (WIN32) "${SOURCES_OS}" res/app.rc src/App_win.cpp - src/Mem_win.cpp src/crypto/common/VirtualMemory_win.cpp ) @@ -123,14 +120,12 @@ elseif (APPLE) set(SOURCES_OS "${SOURCES_OS}" src/App_unix.cpp - src/Mem_unix.cpp src/crypto/common/VirtualMemory_unix.cpp ) else() set(SOURCES_OS "${SOURCES_OS}" src/App_unix.cpp - src/Mem_unix.cpp src/crypto/common/VirtualMemory_unix.cpp ) diff --git a/src/App.cpp b/src/App.cpp index d6c39595..ccbaad4f 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -37,7 +37,7 @@ #include "core/config/Config.h" #include "core/Controller.h" #include "core/Miner.h" -#include "Mem.h" +#include "crypto/common/VirtualMemory.h" #include "net/Network.h" #include "Summary.h" #include "version.h" @@ -76,7 +76,7 @@ int xmrig::App::exec() background(); - Mem::init(m_controller->config()->cpu().isHugePages()); + VirtualMemory::init(m_controller->config()->cpu().isHugePages()); Summary::print(m_controller); diff --git a/src/Mem.cpp b/src/Mem.cpp deleted file mode 100644 index 5fcea306..00000000 --- a/src/Mem.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017-2018 XMR-Stak , - * Copyright 2018 Lee Clagett - * Copyright 2018-2019 SChernykh - * Copyright 2016-2019 XMRig , - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -#include "Mem.h" - - -bool Mem::m_enabled = true; -int Mem::m_flags = 0; diff --git a/src/Mem.h b/src/Mem.h deleted file mode 100644 index 8e5c418b..00000000 --- a/src/Mem.h +++ /dev/null @@ -1,72 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017-2018 XMR-Stak , - * Copyright 2018 Lee Clagett - * Copyright 2018-2019 SChernykh - * Copyright 2016-2019 XMRig , - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef XMRIG_MEM_H -#define XMRIG_MEM_H - - -#include -#include - - -#include "crypto/cn/CnAlgo.h" - - -struct cryptonight_ctx; - - -struct MemInfo -{ - alignas(16) uint8_t *memory = nullptr; - - size_t hugePages = 0; - size_t pages = 0; - size_t size = 0; -}; - - -class Mem -{ -public: - enum Flags { - HugepagesAvailable = 1, - HugepagesEnabled = 2, - Lock = 4 - }; - - static void init(bool enabled); - - static inline bool isHugepagesAvailable() { return (m_flags & HugepagesAvailable) != 0; } - -private: - static void allocate(MemInfo &info, bool enabled); - static void release(MemInfo &info); - - static int m_flags; - static bool m_enabled; -}; - - -#endif /* XMRIG_MEM_H */ diff --git a/src/Mem_unix.cpp b/src/Mem_unix.cpp deleted file mode 100644 index 4dc13e93..00000000 --- a/src/Mem_unix.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017-2018 XMR-Stak , - * Copyright 2018 Lee Clagett - * Copyright 2018-2019 SChernykh - * Copyright 2016-2019 XMRig , - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -#include -#include - - -#include "base/io/log/Log.h" -#include "crypto/common/portable/mm_malloc.h" -#include "crypto/common/VirtualMemory.h" -#include "crypto/cn/CryptoNight.h" -#include "Mem.h" - - -#if defined(__APPLE__) -# include -#endif - - -void Mem::init(bool enabled) -{ - m_enabled = enabled; -} - - -void Mem::allocate(MemInfo &info, bool enabled) -{ - info.hugePages = 0; - - if (!enabled) { - info.memory = static_cast(_mm_malloc(info.size, 4096)); - - return; - } - - info.memory = static_cast(xmrig::VirtualMemory::allocateLargePagesMemory(info.size)); - if (!info.memory) { - return allocate(info, false);; - } - - info.hugePages = info.pages; - - if (madvise(info.memory, info.size, MADV_RANDOM | MADV_WILLNEED) != 0) { - LOG_ERR("madvise failed"); - } - - if (mlock(info.memory, info.size) == 0) { - m_flags |= Lock; - } -} - - -void Mem::release(MemInfo &info) -{ - if (info.hugePages) { - if (m_flags & Lock) { - munlock(info.memory, info.size); - } - - xmrig::VirtualMemory::freeLargePagesMemory(info.memory, info.size); - } - else { - _mm_free(info.memory); - } -} diff --git a/src/Mem_win.cpp b/src/Mem_win.cpp deleted file mode 100644 index 56b4521d..00000000 --- a/src/Mem_win.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017-2018 XMR-Stak , - * Copyright 2018 Lee Clagett - * Copyright 2018-2019 SChernykh - * Copyright 2016-2019 XMRig , - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -#include -#include -#include -#include - - -#include "base/io/log/Log.h" -#include "crypto/common/portable/mm_malloc.h" -#include "crypto/common/VirtualMemory.h" -#include "crypto/cn/CryptoNight.h" -#include "Mem.h" - - -/***************************************************************** -SetLockPagesPrivilege: a function to obtain or -release the privilege of locking physical pages. - -Inputs: - -HANDLE hProcess: Handle for the process for which the -privilege is needed - -BOOL bEnable: Enable (TRUE) or disable? - -Return value: TRUE indicates success, FALSE failure. - -*****************************************************************/ -/** - * AWE Example: https://msdn.microsoft.com/en-us/library/windows/desktop/aa366531(v=vs.85).aspx - * Creating a File Mapping Using Large Pages: https://msdn.microsoft.com/en-us/library/aa366543(VS.85).aspx - */ -static BOOL SetLockPagesPrivilege() { - HANDLE token; - - if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token) != TRUE) { - return FALSE; - } - - TOKEN_PRIVILEGES tp; - tp.PrivilegeCount = 1; - tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - - if (LookupPrivilegeValue(nullptr, SE_LOCK_MEMORY_NAME, &(tp.Privileges[0].Luid)) != TRUE) { - return FALSE; - } - - BOOL rc = AdjustTokenPrivileges(token, FALSE, (PTOKEN_PRIVILEGES) &tp, 0, nullptr, nullptr); - if (rc != TRUE || GetLastError() != ERROR_SUCCESS) { - return FALSE; - } - - CloseHandle(token); - - return TRUE; -} - - -static LSA_UNICODE_STRING StringToLsaUnicodeString(LPCTSTR string) { - LSA_UNICODE_STRING lsaString; - - DWORD dwLen = (DWORD) wcslen(string); - lsaString.Buffer = (LPWSTR) string; - lsaString.Length = (USHORT)((dwLen) * sizeof(WCHAR)); - lsaString.MaximumLength = (USHORT)((dwLen + 1) * sizeof(WCHAR)); - return lsaString; -} - - -static BOOL ObtainLockPagesPrivilege() { - HANDLE token; - PTOKEN_USER user = nullptr; - - if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token) == TRUE) { - DWORD size = 0; - - GetTokenInformation(token, TokenUser, nullptr, 0, &size); - if (size) { - user = (PTOKEN_USER) LocalAlloc(LPTR, size); - } - - GetTokenInformation(token, TokenUser, user, size, &size); - CloseHandle(token); - } - - if (!user) { - return FALSE; - } - - LSA_HANDLE handle; - LSA_OBJECT_ATTRIBUTES attributes; - ZeroMemory(&attributes, sizeof(attributes)); - - BOOL result = FALSE; - if (LsaOpenPolicy(nullptr, &attributes, POLICY_ALL_ACCESS, &handle) == 0) { - LSA_UNICODE_STRING str = StringToLsaUnicodeString(_T(SE_LOCK_MEMORY_NAME)); - - if (LsaAddAccountRights(handle, user->User.Sid, &str, 1) == 0) { - LOG_NOTICE("Huge pages support was successfully enabled, but reboot required to use it"); - result = TRUE; - } - - LsaClose(handle); - } - - LocalFree(user); - return result; -} - - -static BOOL TrySetLockPagesPrivilege() { - if (SetLockPagesPrivilege()) { - return TRUE; - } - - return ObtainLockPagesPrivilege() && SetLockPagesPrivilege(); -} - - -void Mem::init(bool enabled) -{ - m_enabled = enabled; - - if (enabled && TrySetLockPagesPrivilege()) { - m_flags |= HugepagesAvailable; - } -} - - -void Mem::allocate(MemInfo &info, bool enabled) -{ - info.hugePages = 0; - - if (!enabled) { - info.memory = static_cast(_mm_malloc(info.size, 4096)); - - return; - } - - info.memory = static_cast(xmrig::VirtualMemory::allocateLargePagesMemory(info.size)); - if (info.memory) { - info.hugePages = info.pages; - - return; - } - - allocate(info, false); -} - - -void Mem::release(MemInfo &info) -{ - if (info.hugePages) { - xmrig::VirtualMemory::freeLargePagesMemory(info.memory, info.size); - } - else { - _mm_free(info.memory); - } -} diff --git a/src/Summary.cpp b/src/Summary.cpp index 59e540d4..af7cad09 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -34,7 +34,7 @@ #include "core/config/Config.h" #include "core/Controller.h" #include "crypto/common/Assembly.h" -#include "Mem.h" +#include "crypto/common/VirtualMemory.h" #include "Summary.h" #include "version.h" @@ -59,7 +59,7 @@ inline static const char *asmName(xmrig::Assembly::Id assembly) static void print_memory(xmrig::Config *) { # ifdef _WIN32 xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") "%s", - "HUGE PAGES", Mem::isHugepagesAvailable() ? GREEN_BOLD("available") : RED_BOLD("unavailable")); + "HUGE PAGES", xmrig::VirtualMemory::isHugepagesAvailable() ? GREEN_BOLD("available") : RED_BOLD("unavailable")); # endif } diff --git a/src/backend/common/interfaces/IWorker.h b/src/backend/common/interfaces/IWorker.h index 5c99680b..0d7fe1d2 100644 --- a/src/backend/common/interfaces/IWorker.h +++ b/src/backend/common/interfaces/IWorker.h @@ -27,6 +27,7 @@ #include +#include namespace xmrig { diff --git a/src/core/Miner.cpp b/src/core/Miner.cpp index 83ce2206..1764a79e 100644 --- a/src/core/Miner.cpp +++ b/src/core/Miner.cpp @@ -23,6 +23,7 @@ */ +#include #include diff --git a/src/crypto/common/VirtualMemory.h b/src/crypto/common/VirtualMemory.h index 98212e40..e2a5ac22 100644 --- a/src/crypto/common/VirtualMemory.h +++ b/src/crypto/common/VirtualMemory.h @@ -51,9 +51,11 @@ public: static void *allocateLargePagesMemory(size_t size); static void flushInstructionCache(void *p, size_t size); static void freeLargePagesMemory(void *p, size_t size); + static void init(bool hugePages); static void protectExecutableMemory(void *p, size_t size); static void unprotectExecutableMemory(void *p, size_t size); + static inline bool isHugepagesAvailable() { return (m_globalFlags & HUGEPAGES_AVAILABLE) != 0; } static inline constexpr size_t align(size_t pos, size_t align = 2097152) { return ((pos - 1) / align + 1) * align; } private: @@ -63,6 +65,8 @@ private: LOCK = 4 }; + static int m_globalFlags; + int m_flags = 0; size_t m_size = 0; uint8_t *m_scratchpad = nullptr; diff --git a/src/crypto/common/VirtualMemory_unix.cpp b/src/crypto/common/VirtualMemory_unix.cpp index 665fc02b..310a043a 100644 --- a/src/crypto/common/VirtualMemory_unix.cpp +++ b/src/crypto/common/VirtualMemory_unix.cpp @@ -38,6 +38,9 @@ #endif +int xmrig::VirtualMemory::m_globalFlags = 0; + + xmrig::VirtualMemory::VirtualMemory(size_t size, bool hugePages, size_t align) : m_size(VirtualMemory::align(size)) { @@ -120,6 +123,14 @@ void xmrig::VirtualMemory::freeLargePagesMemory(void *p, size_t size) } +void xmrig::VirtualMemory::init(bool hugePages) +{ + if (hugePages) { + m_globalFlags = HUGEPAGES | HUGEPAGES_AVAILABLE; + } +} + + void xmrig::VirtualMemory::protectExecutableMemory(void *p, size_t size) { mprotect(p, size, PROT_READ | PROT_EXEC); diff --git a/src/crypto/common/VirtualMemory_win.cpp b/src/crypto/common/VirtualMemory_win.cpp index 7aa98f89..7bdb6365 100644 --- a/src/crypto/common/VirtualMemory_win.cpp +++ b/src/crypto/common/VirtualMemory_win.cpp @@ -27,11 +27,123 @@ #include #include +#include +#include +#include "base/io/log/Log.h" +#include "crypto/common/portable/mm_malloc.h" #include "crypto/common/VirtualMemory.h" +/***************************************************************** +SetLockPagesPrivilege: a function to obtain or +release the privilege of locking physical pages. + +Inputs: + +HANDLE hProcess: Handle for the process for which the +privilege is needed + +BOOL bEnable: Enable (TRUE) or disable? + +Return value: TRUE indicates success, FALSE failure. + +*****************************************************************/ +/** + * AWE Example: https://msdn.microsoft.com/en-us/library/windows/desktop/aa366531(v=vs.85).aspx + * Creating a File Mapping Using Large Pages: https://msdn.microsoft.com/en-us/library/aa366543(VS.85).aspx + */ +static BOOL SetLockPagesPrivilege() { + HANDLE token; + + if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token) != TRUE) { + return FALSE; + } + + TOKEN_PRIVILEGES tp; + tp.PrivilegeCount = 1; + tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + + if (LookupPrivilegeValue(nullptr, SE_LOCK_MEMORY_NAME, &(tp.Privileges[0].Luid)) != TRUE) { + return FALSE; + } + + BOOL rc = AdjustTokenPrivileges(token, FALSE, (PTOKEN_PRIVILEGES) &tp, 0, nullptr, nullptr); + if (rc != TRUE || GetLastError() != ERROR_SUCCESS) { + return FALSE; + } + + CloseHandle(token); + + return TRUE; +} + + +static LSA_UNICODE_STRING StringToLsaUnicodeString(LPCTSTR string) { + LSA_UNICODE_STRING lsaString; + + DWORD dwLen = (DWORD) wcslen(string); + lsaString.Buffer = (LPWSTR) string; + lsaString.Length = (USHORT)((dwLen) * sizeof(WCHAR)); + lsaString.MaximumLength = (USHORT)((dwLen + 1) * sizeof(WCHAR)); + return lsaString; +} + + +static BOOL ObtainLockPagesPrivilege() { + HANDLE token; + PTOKEN_USER user = nullptr; + + if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token) == TRUE) { + DWORD size = 0; + + GetTokenInformation(token, TokenUser, nullptr, 0, &size); + if (size) { + user = (PTOKEN_USER) LocalAlloc(LPTR, size); + } + + GetTokenInformation(token, TokenUser, user, size, &size); + CloseHandle(token); + } + + if (!user) { + return FALSE; + } + + LSA_HANDLE handle; + LSA_OBJECT_ATTRIBUTES attributes; + ZeroMemory(&attributes, sizeof(attributes)); + + BOOL result = FALSE; + if (LsaOpenPolicy(nullptr, &attributes, POLICY_ALL_ACCESS, &handle) == 0) { + LSA_UNICODE_STRING str = StringToLsaUnicodeString(_T(SE_LOCK_MEMORY_NAME)); + + if (LsaAddAccountRights(handle, user->User.Sid, &str, 1) == 0) { + LOG_NOTICE("Huge pages support was successfully enabled, but reboot required to use it"); + result = TRUE; + } + + LsaClose(handle); + } + + LocalFree(user); + return result; +} + + +static BOOL TrySetLockPagesPrivilege() { + if (SetLockPagesPrivilege()) { + return TRUE; + } + + return ObtainLockPagesPrivilege() && SetLockPagesPrivilege(); +} + + +int xmrig::VirtualMemory::m_globalFlags = 0; + + xmrig::VirtualMemory::VirtualMemory(size_t size, bool hugePages, size_t align) : m_size(VirtualMemory::align(size)) { @@ -94,6 +206,20 @@ void xmrig::VirtualMemory::freeLargePagesMemory(void *p, size_t) } +void xmrig::VirtualMemory::init(bool hugePages) +{ + if (!hugePages) { + return; + } + + m_globalFlags = HUGEPAGES; + + if (TrySetLockPagesPrivilege()) { + m_globalFlags |= HUGEPAGES_AVAILABLE; + } +} + + void xmrig::VirtualMemory::protectExecutableMemory(void *p, size_t size) { DWORD oldProtect; From bcae974ea1b3dfed8797e161c3852c95c4c76c9b Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 17 Jul 2019 05:01:12 +0700 Subject: [PATCH 30/48] Fixed build. --- src/backend/cpu/CpuWorker.h | 1 - src/crypto/cn/r/CryptonightR_gen.cpp | 1 - src/workers/CpuThreadLegacy.cpp | 1 - src/workers/WorkersLegacy.cpp | 1 - 4 files changed, 4 deletions(-) diff --git a/src/backend/cpu/CpuWorker.h b/src/backend/cpu/CpuWorker.h index c0f9dfaf..4cdd10f8 100644 --- a/src/backend/cpu/CpuWorker.h +++ b/src/backend/cpu/CpuWorker.h @@ -31,7 +31,6 @@ #include "backend/common/WorkerJob.h" #include "backend/cpu/CpuLaunchData.h" #include "base/net/stratum/Job.h" -#include "Mem.h" #include "net/JobResult.h" diff --git a/src/crypto/cn/r/CryptonightR_gen.cpp b/src/crypto/cn/r/CryptonightR_gen.cpp index 3037327a..3b80f805 100644 --- a/src/crypto/cn/r/CryptonightR_gen.cpp +++ b/src/crypto/cn/r/CryptonightR_gen.cpp @@ -31,7 +31,6 @@ typedef void(*void_func)(); #include "crypto/cn/asm/CryptonightR_template.h" #include "crypto/common/Assembly.h" #include "crypto/common/VirtualMemory.h" -#include "Mem.h" static inline void add_code(uint8_t* &p, void (*p1)(), void (*p2)()) diff --git a/src/workers/CpuThreadLegacy.cpp b/src/workers/CpuThreadLegacy.cpp index a560d33f..b5d457c7 100644 --- a/src/workers/CpuThreadLegacy.cpp +++ b/src/workers/CpuThreadLegacy.cpp @@ -29,7 +29,6 @@ #include "crypto/cn/CnHash.h" #include "crypto/common/Assembly.h" #include "crypto/common/VirtualMemory.h" -#include "Mem.h" #include "rapidjson/document.h" #include "workers/CpuThreadLegacy.h" diff --git a/src/workers/WorkersLegacy.cpp b/src/workers/WorkersLegacy.cpp index 4d6f9de9..e7191116 100644 --- a/src/workers/WorkersLegacy.cpp +++ b/src/workers/WorkersLegacy.cpp @@ -38,7 +38,6 @@ #include "crypto/rx/RxAlgo.h" #include "crypto/rx/RxCache.h" #include "crypto/rx/RxDataset.h" -#include "Mem.h" #include "rapidjson/document.h" //#include "workers/Hashrate.h" #include "workers/WorkersLegacy.h" From 4f49533e9876fe9902809a0599bed22e570157cc Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 17 Jul 2019 05:33:13 +0700 Subject: [PATCH 31/48] Fixed warnings. --- src/backend/common/Hashrate.h | 1 + src/crypto/randomx/argon2_core.c | 13 ++++++------- src/crypto/randomx/bytecode_machine.hpp | 2 +- src/crypto/randomx/dataset.cpp | 2 +- src/crypto/randomx/jit_compiler_x86.cpp | 2 +- src/crypto/randomx/randomx.cpp | 12 +++++------- src/crypto/randomx/superscalar.cpp | 12 ++++++------ 7 files changed, 21 insertions(+), 23 deletions(-) diff --git a/src/backend/common/Hashrate.h b/src/backend/common/Hashrate.h index 1787bf6a..2187c0be 100644 --- a/src/backend/common/Hashrate.h +++ b/src/backend/common/Hashrate.h @@ -26,6 +26,7 @@ #define XMRIG_HASHRATE_H +#include #include diff --git a/src/crypto/randomx/argon2_core.c b/src/crypto/randomx/argon2_core.c index e9174222..4b8fa43d 100644 --- a/src/crypto/randomx/argon2_core.c +++ b/src/crypto/randomx/argon2_core.c @@ -90,12 +90,12 @@ static void load_block(block *dst, const void *input) { } } -static void store_block(void *output, const block *src) { - unsigned i; - for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) { - store64((uint8_t *)output + i * sizeof(src->v[i]), src->v[i]); - } -} +//static void store_block(void *output, const block *src) { +// unsigned i; +// for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) { +// store64((uint8_t *)output + i * sizeof(src->v[i]), src->v[i]); +// } +//} /***************Memory functions*****************/ @@ -484,7 +484,6 @@ void rxa2_initial_hash(uint8_t *blockhash, argon2_context *context, argon2_type int rxa2_argon_initialize(argon2_instance_t *instance, argon2_context *context) { uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH]; - int result = ARGON2_OK; if (instance == NULL || context == NULL) return ARGON2_INCORRECT_PARAMETER; diff --git a/src/crypto/randomx/bytecode_machine.hpp b/src/crypto/randomx/bytecode_machine.hpp index 3b05f378..810f854a 100644 --- a/src/crypto/randomx/bytecode_machine.hpp +++ b/src/crypto/randomx/bytecode_machine.hpp @@ -90,7 +90,7 @@ namespace randomx { } static void executeBytecode(InstructionByteCode* bytecode, uint8_t* scratchpad, ProgramConfiguration& config) { - for (int pc = 0; pc < RandomX_CurrentConfig.ProgramSize; ++pc) { + for (int pc = 0; pc < static_cast(RandomX_CurrentConfig.ProgramSize); ++pc) { auto& ibc = bytecode[pc]; executeInstruction(ibc, pc, scratchpad, config); } diff --git a/src/crypto/randomx/dataset.cpp b/src/crypto/randomx/dataset.cpp index 3951b55b..b094b1cb 100644 --- a/src/crypto/randomx/dataset.cpp +++ b/src/crypto/randomx/dataset.cpp @@ -121,7 +121,7 @@ namespace randomx { cache->reciprocalCache.clear(); randomx::Blake2Generator gen(key, keySize); - for (int i = 0; i < RandomX_CurrentConfig.CacheAccesses; ++i) { + for (uint32_t i = 0; i < RandomX_CurrentConfig.CacheAccesses; ++i) { randomx::generateSuperscalar(cache->programs[i], gen); for (unsigned j = 0; j < cache->programs[i].getSize(); ++j) { auto& instr = cache->programs[i](j); diff --git a/src/crypto/randomx/jit_compiler_x86.cpp b/src/crypto/randomx/jit_compiler_x86.cpp index 8870a018..6f04e28a 100644 --- a/src/crypto/randomx/jit_compiler_x86.cpp +++ b/src/crypto/randomx/jit_compiler_x86.cpp @@ -194,7 +194,7 @@ namespace randomx { static const uint8_t NOP7[] = { 0x0F, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00 }; static const uint8_t NOP8[] = { 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 }; - static const uint8_t* NOPX[] = { NOP1, NOP2, NOP3, NOP4, NOP5, NOP6, NOP7, NOP8 }; +// static const uint8_t* NOPX[] = { NOP1, NOP2, NOP3, NOP4, NOP5, NOP6, NOP7, NOP8 }; size_t JitCompilerX86::getCodeSize() { return codePos - prologueSize; diff --git a/src/crypto/randomx/randomx.cpp b/src/crypto/randomx/randomx.cpp index df5fc9cb..9e88bc6d 100644 --- a/src/crypto/randomx/randomx.cpp +++ b/src/crypto/randomx/randomx.cpp @@ -233,7 +233,7 @@ RandomX_ConfigurationBase RandomX_CurrentConfig; extern "C" { randomx_cache *randomx_alloc_cache(randomx_flags flags) { - randomx_cache *cache; + randomx_cache *cache = nullptr; try { cache = new randomx_cache(); @@ -297,7 +297,7 @@ extern "C" { } randomx_dataset *randomx_alloc_dataset(randomx_flags flags) { - randomx_dataset *dataset; + randomx_dataset *dataset = nullptr; try { dataset = new randomx_dataset(); @@ -430,14 +430,12 @@ extern "C" { assert(inputSize == 0 || input != nullptr); assert(output != nullptr); alignas(16) uint64_t tempHash[8]; - int blakeResult = blake2b(tempHash, sizeof(tempHash), input, inputSize, nullptr, 0); - assert(blakeResult == 0); + blake2b(tempHash, sizeof(tempHash), input, inputSize, nullptr, 0); machine->initScratchpad(&tempHash); machine->resetRoundingMode(); - for (int chain = 0; chain < RandomX_CurrentConfig.ProgramCount - 1; ++chain) { + for (uint32_t chain = 0; chain < RandomX_CurrentConfig.ProgramCount - 1; ++chain) { machine->run(&tempHash); - blakeResult = blake2b(tempHash, sizeof(tempHash), machine->getRegisterFile(), sizeof(randomx::RegisterFile), nullptr, 0); - assert(blakeResult == 0); + blake2b(tempHash, sizeof(tempHash), machine->getRegisterFile(), sizeof(randomx::RegisterFile), nullptr, 0); } machine->run(&tempHash); machine->getFinalResult(output, RANDOMX_HASH_SIZE); diff --git a/src/crypto/randomx/superscalar.cpp b/src/crypto/randomx/superscalar.cpp index da605622..0ca1fe69 100644 --- a/src/crypto/randomx/superscalar.cpp +++ b/src/crypto/randomx/superscalar.cpp @@ -500,7 +500,7 @@ namespace randomx { // * either the last instruction applied to the register or its source must be different than this instruction // - this avoids optimizable instruction sequences such as "xor r1, r2; xor r1, r2" or "ror r, C1; ror r, C2" or "add r, C1; add r, C2" // * register r5 cannot be the destination of the IADD_RS instruction (limitation of the x86 lea instruction) - for (unsigned i = 0; i < 8; ++i) { + for (int i = 0; i < 8; ++i) { if (registers[i].latency <= cycle && (canReuse_ || i != src_) && (allowChainedMul || opGroup_ != SuperscalarInstructionType::IMUL_R || registers[i].lastOpGroup != SuperscalarInstructionType::IMUL_R) && (registers[i].lastOpGroup != opGroup_ || registers[i].lastOpPar != opGroupPar_) && (info_->getType() != SuperscalarInstructionType::IADD_RS || i != RegisterNeedsDisplacement)) availableRegisters.push_back(i); } @@ -581,7 +581,7 @@ namespace randomx { static int scheduleUop(ExecutionPort::type uop, ExecutionPort::type(&portBusy)[CYCLE_MAP_SIZE][3], int cycle) { //The scheduling here is done optimistically by checking port availability in order P5 -> P0 -> P1 to not overload //port P1 (multiplication) by instructions that can go to any port. - for (; cycle < RandomX_CurrentConfig.SuperscalarLatency + 4; ++cycle) { + for (; cycle < static_cast(RandomX_CurrentConfig.SuperscalarLatency) + 4; ++cycle) { if ((uop & ExecutionPort::P5) != 0 && !portBusy[cycle][2]) { if (commit) { if (trace) std::cout << "; P5 at cycle " << cycle << std::endl; @@ -626,7 +626,7 @@ namespace randomx { } else { //macro-ops with 2 uOPs are scheduled conservatively by requiring both uOPs to execute in the same cycle - for (; cycle < RandomX_CurrentConfig.SuperscalarLatency + 4; ++cycle) { + for (; cycle < static_cast(RandomX_CurrentConfig.SuperscalarLatency) + 4; ++cycle) { int cycle1 = scheduleUop(mop.getUop1(), portBusy, cycle); int cycle2 = scheduleUop(mop.getUop2(), portBusy, cycle); @@ -669,7 +669,7 @@ namespace randomx { //Since a decode cycle produces on average 3.45 macro-ops and there are only 3 ALU ports, execution ports are always //saturated first. The cycle limit is present only to guarantee loop termination. //Program size is limited to SuperscalarMaxSize instructions. - for (decodeCycle = 0; decodeCycle < RandomX_CurrentConfig.SuperscalarLatency && !portsSaturated && programSize < 3 * RandomX_CurrentConfig.SuperscalarLatency + 2; ++decodeCycle) { + for (decodeCycle = 0; decodeCycle < static_cast(RandomX_CurrentConfig.SuperscalarLatency) && !portsSaturated && programSize < 3 * static_cast(RandomX_CurrentConfig.SuperscalarLatency) + 2; ++decodeCycle) { //select a decode configuration decodeBuffer = decodeBuffer->fetchNext(currentInstruction.getType(), decodeCycle, mulCount, gen); @@ -683,7 +683,7 @@ namespace randomx { //if we have issued all macro-ops for the current RandomX instruction, create a new instruction if (macroOpIndex >= currentInstruction.getInfo().getSize()) { - if (portsSaturated || programSize >= 3 * RandomX_CurrentConfig.SuperscalarLatency + 2) + if (portsSaturated || programSize >= 3 * static_cast(RandomX_CurrentConfig.SuperscalarLatency) + 2) break; //select an instruction so that the first macro-op fits into the current slot currentInstruction.createForSlot(gen, decodeBuffer->getCounts()[bufferIndex], decodeBuffer->getIndex(), decodeBuffer->getSize() == bufferIndex + 1, bufferIndex == 0); @@ -777,7 +777,7 @@ namespace randomx { macroOpCount++; //terminating condition - if (scheduleCycle >= RandomX_CurrentConfig.SuperscalarLatency) { + if (scheduleCycle >= static_cast(RandomX_CurrentConfig.SuperscalarLatency)) { portsSaturated = true; } cycle = topCycle; From 8ce00adda4bb607f8bee5c69c8673921059ac3ce Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 17 Jul 2019 14:54:08 +0700 Subject: [PATCH 32/48] Restored "CPU READY" message. --- CMakeLists.txt | 2 - src/api/v1/ApiRouter.cpp | 2 - src/backend/common/Thread.h | 5 +- src/backend/common/Workers.cpp | 13 +- src/backend/common/Workers.h | 1 + src/backend/common/interfaces/IBackend.h | 2 + src/backend/cpu/CpuBackend.cpp | 106 ++++++++-- src/backend/cpu/CpuBackend.h | 3 +- src/core/Miner.cpp | 9 +- src/crypto/common/VirtualMemory.h | 7 +- src/crypto/rx/Rx.cpp | 2 +- src/workers/WorkersLegacy.cpp | 256 ----------------------- src/workers/WorkersLegacy.h | 113 ---------- 13 files changed, 114 insertions(+), 407 deletions(-) delete mode 100644 src/workers/WorkersLegacy.cpp delete mode 100644 src/workers/WorkersLegacy.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 97491518..89be20ec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,7 +43,6 @@ set(HEADERS src/Summary.h src/version.h src/workers/CpuThreadLegacy.h - src/workers/WorkersLegacy.h ) set(HEADERS_CRYPTO @@ -90,7 +89,6 @@ set(SOURCES src/net/strategies/DonateStrategy.cpp src/Summary.cpp src/workers/CpuThreadLegacy.cpp - src/workers/WorkersLegacy.cpp src/xmrig.cpp ) diff --git a/src/api/v1/ApiRouter.cpp b/src/api/v1/ApiRouter.cpp index 2e6a815c..2a5bd3d0 100644 --- a/src/api/v1/ApiRouter.cpp +++ b/src/api/v1/ApiRouter.cpp @@ -36,8 +36,6 @@ #include "core/config/Config.h" #include "rapidjson/document.h" #include "version.h" -//#include "workers/Hashrate.h" -#include "workers/WorkersLegacy.h" static inline rapidjson::Value normalize(double d) diff --git a/src/backend/common/Thread.h b/src/backend/common/Thread.h index f1d174ec..b62d880c 100644 --- a/src/backend/common/Thread.h +++ b/src/backend/common/Thread.h @@ -32,6 +32,7 @@ namespace xmrig { +class IBackend; class IWorker; @@ -39,10 +40,11 @@ template class Thread { public: - inline Thread(size_t index, const T &config) : m_index(index), m_config(config) {} + inline Thread(IBackend *backend, size_t index, const T &config) : m_index(index), m_config(config), m_backend(backend) {} inline ~Thread() { uv_thread_join(&m_thread); } inline const T &config() const { return m_config; } + inline IBackend *backend() const { return m_backend; } inline IWorker *worker() const { return m_worker; } inline size_t index() const { return m_index; } inline void setWorker(IWorker *worker) { m_worker = worker; } @@ -51,6 +53,7 @@ public: private: const size_t m_index = 0; const T m_config; + IBackend *m_backend; IWorker *m_worker = nullptr; uv_thread_t m_thread; }; diff --git a/src/backend/common/Workers.cpp b/src/backend/common/Workers.cpp index c4ac38a5..629b564b 100644 --- a/src/backend/common/Workers.cpp +++ b/src/backend/common/Workers.cpp @@ -25,6 +25,7 @@ #include "backend/common/Hashrate.h" +#include "backend/common/interfaces/IBackend.h" #include "backend/common/Workers.h" #include "backend/cpu/CpuWorker.h" #include "base/io/log/Log.h" @@ -48,6 +49,7 @@ public: Hashrate *hashrate = nullptr; + IBackend *backend = nullptr; }; @@ -79,7 +81,14 @@ const xmrig::Hashrate *xmrig::Workers::hashrate() const template void xmrig::Workers::add(const T &data) { - m_workers.push_back(new Thread(m_workers.size(), data)); + m_workers.push_back(new Thread(d_ptr->backend, m_workers.size(), data)); +} + + +template +void xmrig::Workers::setBackend(IBackend *backend) +{ + d_ptr->backend = backend; } @@ -176,7 +185,7 @@ void xmrig::Workers::onReady(void *arg) return; } - worker->start(); + handle->backend()->start(worker); } diff --git a/src/backend/common/Workers.h b/src/backend/common/Workers.h index 3ef4b015..c13f5e77 100644 --- a/src/backend/common/Workers.h +++ b/src/backend/common/Workers.h @@ -47,6 +47,7 @@ public: const Hashrate *hashrate() const; void add(const T &data); + void setBackend(IBackend *backend); void start(); void stop(); void tick(uint64_t ticks); diff --git a/src/backend/common/interfaces/IBackend.h b/src/backend/common/interfaces/IBackend.h index 69ed4c8c..8ad7bb53 100644 --- a/src/backend/common/interfaces/IBackend.h +++ b/src/backend/common/interfaces/IBackend.h @@ -33,6 +33,7 @@ namespace xmrig { class Hashrate; +class IWorker; class Job; class String; @@ -46,6 +47,7 @@ public: virtual const String &profileName() const = 0; virtual void printHashrate(bool details) = 0; virtual void setJob(const Job &job) = 0; + virtual void start(IWorker *worker) = 0; virtual void stop() = 0; virtual void tick(uint64_t ticks) = 0; }; diff --git a/src/backend/cpu/CpuBackend.cpp b/src/backend/cpu/CpuBackend.cpp index a0463832..bdb592ff 100644 --- a/src/backend/cpu/CpuBackend.cpp +++ b/src/backend/cpu/CpuBackend.cpp @@ -23,7 +23,11 @@ */ +#include + + #include "backend/common/Hashrate.h" +#include "backend/common/interfaces/IWorker.h" #include "backend/common/Workers.h" #include "backend/cpu/CpuBackend.h" #include "base/io/log/Log.h" @@ -31,6 +35,7 @@ #include "base/tools/String.h" #include "core/config/Config.h" #include "core/Controller.h" +#include "crypto/common/VirtualMemory.h" namespace xmrig { @@ -39,18 +44,41 @@ namespace xmrig { extern template class Threads; +struct LaunchStatus +{ +public: + inline void reset() + { + hugePages = 0; + memory = 0; + pages = 0; + started = 0; + threads = 0; + ways = 0; + } + + size_t hugePages; + size_t memory; + size_t pages; + size_t started; + size_t threads; + size_t ways; +}; + + class CpuBackendPrivate { public: - inline CpuBackendPrivate(const Miner *miner, Controller *controller) : - miner(miner), + inline CpuBackendPrivate(Controller *controller) : controller(controller) { + uv_mutex_init(&mutex); } inline ~CpuBackendPrivate() { + uv_mutex_destroy(&mutex); } @@ -72,11 +100,42 @@ public: } + inline void start(const Job &job) + { + const CpuConfig &cpu = controller->config()->cpu(); + + algo = job.algorithm(); + profileName = cpu.threads().profileName(job.algorithm()); + threads = cpu.threads().get(profileName); + + LOG_INFO(GREEN_BOLD("CPU") " use profile " BLUE_BG(WHITE_BOLD_S " %s ") WHITE_BOLD_S " (" CYAN_BOLD("%zu") WHITE_BOLD(" threads)") " scratchpad " CYAN_BOLD("%zu KB"), + profileName.data(), + threads.size(), + algo.memory() / 1024 + ); + + workers.stop(); + + status.reset(); + status.memory = algo.memory(); + status.threads = threads.size(); + + for (const CpuThread &thread : threads) { + workers.add(CpuLaunchData(controller->miner(), algo, cpu, thread)); + + status.ways += static_cast(thread.intensity()); + } + + workers.start(); + } + + Algorithm algo; - const Miner *miner; Controller *controller; CpuThreads threads; + LaunchStatus status; String profileName; + uv_mutex_t mutex; Workers workers; }; @@ -84,10 +143,10 @@ public: } // namespace xmrig -xmrig::CpuBackend::CpuBackend(const Miner *miner, Controller *controller) : - d_ptr(new CpuBackendPrivate(miner, controller)) +xmrig::CpuBackend::CpuBackend(Controller *controller) : + d_ptr(new CpuBackendPrivate(controller)) { - + d_ptr->workers.setBackend(this); } @@ -140,26 +199,33 @@ void xmrig::CpuBackend::setJob(const Job &job) return; } - const CpuConfig &cpu = d_ptr->controller->config()->cpu(); - const Threads &threads = cpu.threads(); + d_ptr->start(job); +} - d_ptr->algo = job.algorithm(); - d_ptr->profileName = threads.profileName(job.algorithm()); - d_ptr->threads = threads.get(d_ptr->profileName); - LOG_INFO(GREEN_BOLD("CPU") " use profile " BLUE_BG(WHITE_BOLD_S " %s ") WHITE_BOLD_S " (" CYAN_BOLD("%zu") WHITE_BOLD(" threads)") " scratchpad " CYAN_BOLD("%zu KB"), - d_ptr->profileName.data(), - d_ptr->threads.size(), - d_ptr->algo.memory() / 1024 - ); +void xmrig::CpuBackend::start(IWorker *worker) +{ + uv_mutex_lock(&d_ptr->mutex); - d_ptr->workers.stop(); + const auto pages = worker->memory()->hugePages(); - for (const CpuThread &thread : d_ptr->threads) { - d_ptr->workers.add(CpuLaunchData(d_ptr->miner, d_ptr->algo, cpu, thread)); + d_ptr->status.started++; + d_ptr->status.hugePages += pages.first; + d_ptr->status.pages += pages.second; + + if (d_ptr->status.started == d_ptr->status.threads) { + const double percent = d_ptr->status.hugePages == 0 ? 0.0 : static_cast(d_ptr->status.hugePages) / d_ptr->status.pages * 100.0; + const size_t memory = d_ptr->status.ways * d_ptr->status.memory / 1024; + + LOG_INFO(GREEN_BOLD("CPU READY") " threads " CYAN_BOLD("%zu(%zu)") " huge pages %s%zu/%zu %1.0f%%\x1B[0m memory " CYAN_BOLD("%zu KB") "", + d_ptr->status.threads, d_ptr->status.ways, + (d_ptr->status.hugePages == d_ptr->status.pages ? GREEN_BOLD_S : (d_ptr->status.hugePages == 0 ? RED_BOLD_S : YELLOW_BOLD_S)), + d_ptr->status.hugePages, d_ptr->status.pages, percent, memory); } - d_ptr->workers.start(); + uv_mutex_unlock(&d_ptr->mutex); + + worker->start(); } diff --git a/src/backend/cpu/CpuBackend.h b/src/backend/cpu/CpuBackend.h index a7b742eb..aabccb49 100644 --- a/src/backend/cpu/CpuBackend.h +++ b/src/backend/cpu/CpuBackend.h @@ -40,7 +40,7 @@ class Miner; class CpuBackend : public IBackend { public: - CpuBackend(const Miner *miner, Controller *controller); + CpuBackend(Controller *controller); ~CpuBackend() override; protected: @@ -48,6 +48,7 @@ protected: const String &profileName() const override; void printHashrate(bool details) override; void setJob(const Job &job) override; + void start(IWorker *worker) override; void stop() override; void tick(uint64_t ticks) override; diff --git a/src/core/Miner.cpp b/src/core/Miner.cpp index 1764a79e..40321662 100644 --- a/src/core/Miner.cpp +++ b/src/core/Miner.cpp @@ -101,7 +101,7 @@ xmrig::Miner::Miner(Controller *controller) { d_ptr->timer = new Timer(this); - d_ptr->backends.push_back(new CpuBackend(this, controller)); + d_ptr->backends.push_back(new CpuBackend(controller)); } @@ -210,15 +210,8 @@ void xmrig::Miner::setJob(const Job &job, bool donate) void xmrig::Miner::stop() { -// xmrig::Handle::close(m_timer); -// m_hashrate->stop(); - Nonce::stop(); -// for (size_t i = 0; i < m_workers.size(); ++i) { -// m_workers[i]->join(); -// } - for (IBackend *backend : d_ptr->backends) { backend->stop(); } diff --git a/src/crypto/common/VirtualMemory.h b/src/crypto/common/VirtualMemory.h index e2a5ac22..44f77a23 100644 --- a/src/crypto/common/VirtualMemory.h +++ b/src/crypto/common/VirtualMemory.h @@ -30,6 +30,7 @@ #include #include +#include namespace xmrig { @@ -43,10 +44,14 @@ public: ~VirtualMemory(); inline bool isHugePages() const { return m_flags & HUGEPAGES; } - inline size_t hugePages() const { return isHugePages() ? (align(size()) / 2097152) : 0; } inline size_t size() const { return m_size; } inline uint8_t *scratchpad() const { return m_scratchpad; } + inline std::pair hugePages() const + { + return std::pair(isHugePages() ? (align(size()) / 2097152) : 0, align(size()) / 2097152); + } + static void *allocateExecutableMemory(size_t size); static void *allocateLargePagesMemory(size_t size); static void flushInstructionCache(void *p, size_t size); diff --git a/src/crypto/rx/Rx.cpp b/src/crypto/rx/Rx.cpp index 630dd45a..7f482034 100644 --- a/src/crypto/rx/Rx.cpp +++ b/src/crypto/rx/Rx.cpp @@ -113,7 +113,7 @@ xmrig::RxDataset *xmrig::Rx::dataset(const uint8_t *seed, const Algorithm &algor const uint64_t ts = Chrono::steadyMSecs(); if (d_ptr->dataset->get() != nullptr) { - LOG_INFO("%s" MAGENTA_BOLD(" init dataset") " algo " WHITE_BOLD("%s") " threads " WHITE_BOLD("%u") BLACK_BOLD(" seed %s..."), + LOG_INFO("%s" MAGENTA_BOLD(" init dataset") " algo " WHITE_BOLD("%s (") CYAN_BOLD("%u") WHITE_BOLD(" threads)") BLACK_BOLD(" seed %s..."), tag, algorithm.shortName(), d_ptr->initThreads, diff --git a/src/workers/WorkersLegacy.cpp b/src/workers/WorkersLegacy.cpp deleted file mode 100644 index e7191116..00000000 --- a/src/workers/WorkersLegacy.cpp +++ /dev/null @@ -1,256 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017-2018 XMR-Stak , - * Copyright 2018-2019 SChernykh - * Copyright 2016-2019 XMRig , - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include - - -#include "api/Api.h" -#include "backend/cpu/CpuWorker.h" -#include "base/io/log/Log.h" -#include "base/tools/Chrono.h" -#include "base/tools/Handle.h" -#include "core/config/Config.h" -#include "core/Controller.h" -#include "crypto/common/Nonce.h" -#include "crypto/rx/RxAlgo.h" -#include "crypto/rx/RxCache.h" -#include "crypto/rx/RxDataset.h" -#include "rapidjson/document.h" -//#include "workers/Hashrate.h" -#include "workers/WorkersLegacy.h" - - -bool WorkersLegacy::m_active = false; -bool WorkersLegacy::m_enabled = true; -//Hashrate *WorkersLegacy::m_hashrate = nullptr; -xmrig::Job WorkersLegacy::m_job; -WorkersLegacy::LaunchStatus WorkersLegacy::m_status; -std::vector* > WorkersLegacy::m_workers; -uint64_t WorkersLegacy::m_ticks = 0; -uv_mutex_t WorkersLegacy::m_mutex; -uv_rwlock_t WorkersLegacy::m_rwlock; -//uv_timer_t *Workers::m_timer = nullptr; -xmrig::Controller *WorkersLegacy::m_controller = nullptr; - - -//xmrig::Job WorkersLegacy::job() -//{ -// uv_rwlock_rdlock(&m_rwlock); -// xmrig::Job job = m_job; -// uv_rwlock_rdunlock(&m_rwlock); - -// return job; -//} - - -//size_t WorkersLegacy::hugePages() -//{ -// uv_mutex_lock(&m_mutex); -// const size_t hugePages = m_status.hugePages; -// uv_mutex_unlock(&m_mutex); - -// return hugePages; -//} - - -//size_t WorkersLegacy::threads() -//{ -// uv_mutex_lock(&m_mutex); -// const size_t threads = m_status.threads; -// uv_mutex_unlock(&m_mutex); - -// return threads; -//} - - -//void Workers::pause() -//{ -// m_active = false; - -// xmrig::Nonce::pause(true); -// xmrig::Nonce::touch(); -//} - - -//void Workers::setEnabled(bool enabled) -//{ -// if (m_enabled == enabled) { -// return; -// } - -// m_enabled = enabled; -// if (!m_active) { -// return; -// } - -// xmrig::Nonce::pause(!enabled); -// xmrig::Nonce::touch(); -//} - - -//void Workers::setJob(const xmrig::Job &job, bool donate) -//{ -// uv_rwlock_wrlock(&m_rwlock); - -// m_job = job; -// m_job.setIndex(donate ? 1 : 0); - -// xmrig::Nonce::reset(donate ? 1 : 0); - -// uv_rwlock_wrunlock(&m_rwlock); - -// m_active = true; -// if (!m_enabled) { -// return; -// } - -// xmrig::Nonce::pause(false); -//} - - -void WorkersLegacy::start(xmrig::Controller *controller) -{ - using namespace xmrig; - -# ifdef APP_DEBUG - LOG_NOTICE("THREADS ------------------------------------------------------------------"); - for (const xmrig::IThread *thread : controller->config()->threads()) { - thread->print(); - } - LOG_NOTICE("--------------------------------------------------------------------------"); -# endif - - m_controller = controller; - - m_status.algo = xmrig::Algorithm::RX_WOW; // FIXME algo - const CpuThreads &threads = controller->config()->cpu().threads().get(m_status.algo); - m_status.threads = threads.size(); - - for (const CpuThread &thread : threads) { - m_status.ways += thread.intensity(); - } - -// m_hashrate = new Hashrate(threads.size(), controller); - - uv_mutex_init(&m_mutex); - uv_rwlock_init(&m_rwlock); - -// m_timer = new uv_timer_t; -// uv_timer_init(uv_default_loop(), m_timer); -// uv_timer_start(m_timer, Workers::onTick, 500, 500); - -// size_t index = 0; -// for (const CpuThread &thread : threads) { -// Thread *handle = new Thread(index++, CpuLaunchData(m_status.algo, controller->config()->cpu(), thread)); - -// m_workers.push_back(handle); -// handle->start(WorkersLegacy::onReady); -// } -} - - -//void Workers::stop() -//{ -// xmrig::Handle::close(m_timer); -// m_hashrate->stop(); - -// xmrig::Nonce::stop(); - -// for (size_t i = 0; i < m_workers.size(); ++i) { -// m_workers[i]->join(); -// } -//} - - -//#ifdef XMRIG_FEATURE_API -//void WorkersLegacy::threadsSummary(rapidjson::Document &doc) -//{ -// uv_mutex_lock(&m_mutex); -// const uint64_t pages[2] = { m_status.hugePages, m_status.pages }; -// const uint64_t memory = m_status.ways * xmrig::CnAlgo<>::memory(m_status.algo); -// uv_mutex_unlock(&m_mutex); - -// auto &allocator = doc.GetAllocator(); - -// rapidjson::Value hugepages(rapidjson::kArrayType); -// hugepages.PushBack(pages[0], allocator); -// hugepages.PushBack(pages[1], allocator); - -// doc.AddMember("hugepages", hugepages, allocator); -// doc.AddMember("memory", memory, allocator); -//} -//#endif - - -//void WorkersLegacy::onTick(uv_timer_t *) -//{ -// using namespace xmrig; - -// for (Thread *handle : m_workers) { -// if (!handle->worker()) { -// return; -// } - -// m_hashrate->add(handle->index(), handle->worker()->hashCount(), handle->worker()->timestamp()); -// } - -// if ((m_ticks++ & 0xF) == 0) { -// m_hashrate->updateHighest(); -// } -//} - - -void WorkersLegacy::start(xmrig::IWorker *worker) -{ -// const Worker *w = static_cast(worker); - - uv_mutex_lock(&m_mutex); - m_status.started++; -// m_status.pages += w->memory().pages; -// m_status.hugePages += w->memory().hugePages; - - if (m_status.started == m_status.threads) { - const double percent = (double) m_status.hugePages / m_status.pages * 100.0; - const size_t memory = m_status.ways * xmrig::CnAlgo<>::memory(m_status.algo) / 1024; - -# ifdef XMRIG_ALGO_RANDOMX - if (m_status.algo.family() == xmrig::Algorithm::RANDOM_X) { - LOG_INFO(GREEN_BOLD("READY (CPU)") " threads " CYAN_BOLD("%zu(%zu)") " memory " CYAN_BOLD("%zu KB") "", - m_status.threads, m_status.ways, memory); - } else -# endif - { - LOG_INFO(GREEN_BOLD("READY (CPU)") " threads " CYAN_BOLD("%zu(%zu)") " huge pages %s%zu/%zu %1.0f%%\x1B[0m memory " CYAN_BOLD("%zu KB") "", - m_status.threads, m_status.ways, - (m_status.hugePages == m_status.pages ? GREEN_BOLD_S : (m_status.hugePages == 0 ? RED_BOLD_S : YELLOW_BOLD_S)), - m_status.hugePages, m_status.pages, percent, memory); - } - } - - uv_mutex_unlock(&m_mutex); - - worker->start(); -} diff --git a/src/workers/WorkersLegacy.h b/src/workers/WorkersLegacy.h deleted file mode 100644 index d8ab1e59..00000000 --- a/src/workers/WorkersLegacy.h +++ /dev/null @@ -1,113 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017-2018 XMR-Stak , - * Copyright 2018-2019 SChernykh - * Copyright 2016-2019 XMRig , - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef XMRIG_WORKERSLEGACY_H -#define XMRIG_WORKERSLEGACY_H - - -#include -#include -#include -#include - -#ifdef XMRIG_ALGO_RANDOMX -# include -#endif - -#include "backend/common/Thread.h" -#include "backend/cpu/CpuLaunchData.h" -#include "base/net/stratum/Job.h" -#include "net/JobResult.h" -#include "rapidjson/fwd.h" - - -//class Hashrate; - - -namespace xmrig { - class IWorker; - class Controller; - class ThreadHandle; -} - - -class WorkersLegacy -{ -public: -// static size_t hugePages(); -// static size_t threads(); -// static void pause(); -// static void printHashrate(bool detail); -// static void setEnabled(bool enabled); -// static void setJob(const xmrig::Job &job, bool donate); - static void start(xmrig::Controller *controller); -// static void stop(); -// static xmrig::Job job(); - -// static inline bool isEnabled() { return m_enabled; } -// static inline Hashrate *hashrate() { return m_hashrate; } - -//# ifdef XMRIG_FEATURE_API -// static void threadsSummary(rapidjson::Document &doc); -//# endif - -private: -// static void onReady(void *arg); -// static void onTick(uv_timer_t *handle); - static void start(xmrig::IWorker *worker); - - class LaunchStatus - { - public: - inline LaunchStatus() : - hugePages(0), - pages(0), - started(0), - threads(0), - ways(0) - {} - - size_t hugePages; - size_t pages; - size_t started; - size_t threads; - size_t ways; - xmrig::Algorithm algo; - }; - - static bool m_active; - static bool m_enabled; -// static Hashrate *m_hashrate; - static xmrig::Job m_job; - static LaunchStatus m_status; - static std::vector* > m_workers; - static uint64_t m_ticks; - static uv_mutex_t m_mutex; - static uv_rwlock_t m_rwlock; -// static uv_timer_t *m_timer; - static xmrig::Controller *m_controller; -}; - - -#endif /* XMRIG_WORKERSLEGACY_H */ From 630a5dce676d5492fc81518853fef329e9dd4240 Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 17 Jul 2019 15:09:37 +0700 Subject: [PATCH 33/48] Improved log. --- src/backend/cpu/CpuBackend.cpp | 17 +++++++++++++++-- src/core/config/Config.cpp | 9 --------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/backend/cpu/CpuBackend.cpp b/src/backend/cpu/CpuBackend.cpp index bdb592ff..f325d0ff 100644 --- a/src/backend/cpu/CpuBackend.cpp +++ b/src/backend/cpu/CpuBackend.cpp @@ -32,6 +32,7 @@ #include "backend/cpu/CpuBackend.h" #include "base/io/log/Log.h" #include "base/net/stratum/Job.h" +#include "base/tools/Chrono.h" #include "base/tools/String.h" #include "core/config/Config.h" #include "core/Controller.h" @@ -55,6 +56,7 @@ public: started = 0; threads = 0; ways = 0; + ts = Chrono::steadyMSecs(); } size_t hugePages; @@ -63,6 +65,7 @@ public: size_t started; size_t threads; size_t ways; + uint64_t ts; }; @@ -108,6 +111,14 @@ public: profileName = cpu.threads().profileName(job.algorithm()); threads = cpu.threads().get(profileName); + if (profileName.isNull() || threads.empty()) { + workers.stop(); + + LOG_WARN(YELLOW_BOLD_S "CPU disabled, no suitable configuration for algo %s", job.algorithm().shortName()); + + return; + } + LOG_INFO(GREEN_BOLD("CPU") " use profile " BLUE_BG(WHITE_BOLD_S " %s ") WHITE_BOLD_S " (" CYAN_BOLD("%zu") WHITE_BOLD(" threads)") " scratchpad " CYAN_BOLD("%zu KB"), profileName.data(), threads.size(), @@ -217,10 +228,12 @@ void xmrig::CpuBackend::start(IWorker *worker) const double percent = d_ptr->status.hugePages == 0 ? 0.0 : static_cast(d_ptr->status.hugePages) / d_ptr->status.pages * 100.0; const size_t memory = d_ptr->status.ways * d_ptr->status.memory / 1024; - LOG_INFO(GREEN_BOLD("CPU READY") " threads " CYAN_BOLD("%zu(%zu)") " huge pages %s%zu/%zu %1.0f%%\x1B[0m memory " CYAN_BOLD("%zu KB") "", + LOG_INFO(GREEN_BOLD("CPU READY") " threads " CYAN_BOLD("%zu(%zu)") " huge pages %s%zu/%zu %1.0f%%\x1B[0m memory " CYAN_BOLD("%zu KB") BLACK_BOLD(" (%" PRIu64 " ms)"), d_ptr->status.threads, d_ptr->status.ways, (d_ptr->status.hugePages == d_ptr->status.pages ? GREEN_BOLD_S : (d_ptr->status.hugePages == 0 ? RED_BOLD_S : YELLOW_BOLD_S)), - d_ptr->status.hugePages, d_ptr->status.pages, percent, memory); + d_ptr->status.hugePages, d_ptr->status.pages, percent, memory, + Chrono::steadyMSecs() - d_ptr->status.ts + ); } uv_mutex_unlock(&d_ptr->mutex); diff --git a/src/core/config/Config.cpp b/src/core/config/Config.cpp index 02ef9c90..09728b4e 100644 --- a/src/core/config/Config.cpp +++ b/src/core/config/Config.cpp @@ -79,15 +79,6 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const doc.AddMember("background", isBackground(), allocator); doc.AddMember("colors", Log::colors, allocator); -// if (affinity() != -1L) { -// snprintf(affinity_tmp, sizeof(affinity_tmp) - 1, "0x%" PRIX64, affinity()); -// doc.AddMember("cpu-affinity", StringRef(affinity_tmp), allocator); -// } -// else { -// doc.AddMember("cpu-affinity", kNullType, allocator); -// } - - doc.AddMember("cpu", m_cpu.toJSON(doc), allocator); doc.AddMember("donate-level", m_pools.donateLevel(), allocator); From 6f93b7b38d164c8f6ed90885375ddbe63126b9df Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 17 Jul 2019 15:28:59 +0700 Subject: [PATCH 34/48] Removed unused code. --- CMakeLists.txt | 2 - src/Summary.cpp | 28 +-- src/backend/cpu/interfaces/ICpuInfo.h | 1 - src/backend/cpu/platform/AdvancedCpuInfo.cpp | 39 ---- src/backend/cpu/platform/AdvancedCpuInfo.h | 1 - src/backend/cpu/platform/BasicCpuInfo.cpp | 8 - src/backend/cpu/platform/BasicCpuInfo.h | 1 - src/backend/cpu/platform/BasicCpuInfo_arm.cpp | 6 - src/core/config/Config.cpp | 155 +------------ src/core/config/Config.h | 42 +--- src/workers/CpuThreadLegacy.cpp | 219 ------------------ src/workers/CpuThreadLegacy.h | 108 --------- 12 files changed, 19 insertions(+), 591 deletions(-) delete mode 100644 src/workers/CpuThreadLegacy.cpp delete mode 100644 src/workers/CpuThreadLegacy.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 89be20ec..4d205f55 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,7 +42,6 @@ set(HEADERS src/net/strategies/DonateStrategy.h src/Summary.h src/version.h - src/workers/CpuThreadLegacy.h ) set(HEADERS_CRYPTO @@ -88,7 +87,6 @@ set(SOURCES src/net/NetworkState.cpp src/net/strategies/DonateStrategy.cpp src/Summary.cpp - src/workers/CpuThreadLegacy.cpp src/xmrig.cpp ) diff --git a/src/Summary.cpp b/src/Summary.cpp index af7cad09..36f59ba3 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -84,29 +84,11 @@ static void print_cpu(xmrig::Config *) static void print_threads(xmrig::Config *config) { - if (config->threadsMode() != xmrig::Config::Advanced) { - char buf[32] = { 0 }; -// if (config->affinity() != -1L) { -// snprintf(buf, sizeof buf, ", affinity=0x%" PRIX64, config->affinity()); -// } - - xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%d") WHITE_BOLD(", av=%d, %sdonate=%d%%") WHITE_BOLD("%s"), - "THREADS", - config->threadsCount(), - config->algoVariant(), - config->pools().donateLevel() == 0 ? RED_BOLD_S : "", - config->pools().donateLevel(), - buf - ); - } - else { - xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("%d") WHITE_BOLD(", %sdonate=%d%%"), - "THREADS", - config->threadsCount(), - config->pools().donateLevel() == 0 ? RED_BOLD_S : "", - config->pools().donateLevel() - ); - } + xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") WHITE_BOLD("%s%d%%"), + "DONATE", + config->pools().donateLevel() == 0 ? RED_BOLD_S : "", + config->pools().donateLevel() + ); # ifdef XMRIG_FEATURE_ASM if (config->cpu().assembly() == xmrig::Assembly::AUTO) { diff --git a/src/backend/cpu/interfaces/ICpuInfo.h b/src/backend/cpu/interfaces/ICpuInfo.h index 74f6baee..5848db89 100644 --- a/src/backend/cpu/interfaces/ICpuInfo.h +++ b/src/backend/cpu/interfaces/ICpuInfo.h @@ -55,7 +55,6 @@ public: virtual size_t L2() const = 0; virtual size_t L3() const = 0; virtual size_t nodes() const = 0; - virtual size_t optimalThreadsCount(size_t memSize, int maxCpuUsage) const = 0; virtual size_t sockets() const = 0; virtual size_t threads() const = 0; }; diff --git a/src/backend/cpu/platform/AdvancedCpuInfo.cpp b/src/backend/cpu/platform/AdvancedCpuInfo.cpp index f3c4ed23..45b0dd66 100644 --- a/src/backend/cpu/platform/AdvancedCpuInfo.cpp +++ b/src/backend/cpu/platform/AdvancedCpuInfo.cpp @@ -80,45 +80,6 @@ xmrig::AdvancedCpuInfo::AdvancedCpuInfo() : } -size_t xmrig::AdvancedCpuInfo::optimalThreadsCount(size_t memSize, int maxCpuUsage) const -{ - if (threads() == 1) { - return 1; - } - - size_t cache = 0; - if (m_L3) { - cache = m_L2_exclusive ? (m_L2 + m_L3) : m_L3; - } - else { - cache = m_L2; - } - - size_t count = 0; - - if (cache) { - count = cache / memSize; - - if (cache % memSize >= memSize / 2) { - count++; - } - } - else { - count = threads() / 2; - } - - if (count > (size_t) threads()) { - count = threads(); - } - - if (((float) count / threads() * 100) > maxCpuUsage) { - count = (int) ceil((float) threads() * (maxCpuUsage / 100.0)); - } - - return count < 1 ? 1 : count; -} - - xmrig::CpuThreads xmrig::AdvancedCpuInfo::threads(const Algorithm &algorithm) const { if (threads() == 1) { diff --git a/src/backend/cpu/platform/AdvancedCpuInfo.h b/src/backend/cpu/platform/AdvancedCpuInfo.h index 9852f6bd..889fba00 100644 --- a/src/backend/cpu/platform/AdvancedCpuInfo.h +++ b/src/backend/cpu/platform/AdvancedCpuInfo.h @@ -38,7 +38,6 @@ public: AdvancedCpuInfo(); protected: - size_t optimalThreadsCount(size_t memSize, int maxCpuUsage) const override; CpuThreads threads(const Algorithm &algorithm) const override; inline Assembly::Id assembly() const override { return m_assembly; } diff --git a/src/backend/cpu/platform/BasicCpuInfo.cpp b/src/backend/cpu/platform/BasicCpuInfo.cpp index 369392b6..f30466fe 100644 --- a/src/backend/cpu/platform/BasicCpuInfo.cpp +++ b/src/backend/cpu/platform/BasicCpuInfo.cpp @@ -153,14 +153,6 @@ xmrig::BasicCpuInfo::BasicCpuInfo() : } -size_t xmrig::BasicCpuInfo::optimalThreadsCount(size_t memSize, int maxCpuUsage) const -{ - const size_t count = threads() / 2; - - return count < 1 ? 1 : count; -} - - xmrig::CpuThreads xmrig::BasicCpuInfo::threads(const Algorithm &algorithm) const { if (threads() == 1) { diff --git a/src/backend/cpu/platform/BasicCpuInfo.h b/src/backend/cpu/platform/BasicCpuInfo.h index 886d59c3..12d0e037 100644 --- a/src/backend/cpu/platform/BasicCpuInfo.h +++ b/src/backend/cpu/platform/BasicCpuInfo.h @@ -38,7 +38,6 @@ public: BasicCpuInfo(); protected: - size_t optimalThreadsCount(size_t memSize, int maxCpuUsage) const override; CpuThreads threads(const Algorithm &algorithm) const override; inline Assembly::Id assembly() const override { return m_assembly; } diff --git a/src/backend/cpu/platform/BasicCpuInfo_arm.cpp b/src/backend/cpu/platform/BasicCpuInfo_arm.cpp index 6702f6f0..3d733535 100644 --- a/src/backend/cpu/platform/BasicCpuInfo_arm.cpp +++ b/src/backend/cpu/platform/BasicCpuInfo_arm.cpp @@ -57,12 +57,6 @@ xmrig::BasicCpuInfo::BasicCpuInfo() : } -size_t xmrig::BasicCpuInfo::optimalThreadsCount(size_t memSize, int maxCpuUsage) const -{ - return threads(); -} - - xmrig::CpuThreads xmrig::BasicCpuInfo::threads(const Algorithm &algorithm) const { return CpuThreads(threads()); diff --git a/src/core/config/Config.cpp b/src/core/config/Config.cpp index 09728b4e..d6336b67 100644 --- a/src/core/config/Config.cpp +++ b/src/core/config/Config.cpp @@ -36,12 +36,9 @@ #include "rapidjson/document.h" #include "rapidjson/filewritestream.h" #include "rapidjson/prettywriter.h" -#include "workers/CpuThreadLegacy.h" -xmrig::Config::Config() : - m_algoVariant(CnHash::AV_AUTO), - m_shouldSave(false) +xmrig::Config::Config() : BaseConfig() { } @@ -54,10 +51,7 @@ bool xmrig::Config::read(const IJsonReader &reader, const char *fileName) m_cpu.read(reader.getValue("cpu")); - setAlgoVariant(reader.getInt("av")); - setThreads(reader.getValue("threads")); - - return finalize(); + return true; } @@ -72,148 +66,21 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const Value api(kObjectType); api.AddMember("id", m_apiId.toJSON(), allocator); api.AddMember("worker-id", m_apiWorkerId.toJSON(), allocator); - doc.AddMember("api", api, allocator); - doc.AddMember("http", m_http.toJSON(doc), allocator); - doc.AddMember("autosave", isAutoSave(), allocator); - doc.AddMember("av", algoVariant(), allocator); - doc.AddMember("background", isBackground(), allocator); - doc.AddMember("colors", Log::colors, allocator); - - doc.AddMember("cpu", m_cpu.toJSON(doc), allocator); + doc.AddMember("api", api, allocator); + doc.AddMember("autosave", isAutoSave(), allocator); + doc.AddMember("background", isBackground(), allocator); + doc.AddMember("colors", Log::colors, allocator); + doc.AddMember("cpu", m_cpu.toJSON(doc), allocator); doc.AddMember("donate-level", m_pools.donateLevel(), allocator); doc.AddMember("donate-over-proxy", m_pools.proxyDonate(), allocator); + doc.AddMember("http", m_http.toJSON(doc), allocator); doc.AddMember("log-file", m_logFile.toJSON(), allocator); doc.AddMember("pools", m_pools.toJSON(doc), allocator); doc.AddMember("print-time", printTime(), allocator); doc.AddMember("retries", m_pools.retries(), allocator); doc.AddMember("retry-pause", m_pools.retryPause(), allocator); - - if (threadsMode() != Simple) { - Value threads(kArrayType); - - for (const IThread *thread : m_threads.list) { - threads.PushBack(thread->toConfig(doc), allocator); - } - - doc.AddMember("threads", threads, allocator); - } - else { - doc.AddMember("threads", threadsCount(), allocator); - } - - doc.AddMember("user-agent", m_userAgent.toJSON(), allocator); - doc.AddMember("syslog", isSyslog(), allocator); - doc.AddMember("watch", m_watch, allocator); + doc.AddMember("syslog", isSyslog(), allocator); + doc.AddMember("user-agent", m_userAgent.toJSON(), allocator); + doc.AddMember("watch", m_watch, allocator); } - - -bool xmrig::Config::finalize() -{ - Algorithm algorithm(Algorithm::RX_WOW); // FIXME algo - - if (!m_threads.cpu.empty()) { - m_threads.mode = Advanced; - - for (size_t i = 0; i < m_threads.cpu.size(); ++i) { - m_threads.list.push_back(CpuThreadLegacy::createFromData(i, algorithm, m_threads.cpu[i], m_cpu.priority(), !m_cpu.isHwAES())); - } - - return true; - } - - const CnHash::AlgoVariant av = getAlgoVariant(); - m_threads.mode = m_threads.count ? Simple : Automatic; - - const size_t size = CpuThreadLegacy::multiway(av) * CnAlgo<>::memory(algorithm) / 1024; // FIXME MEMORY - - if (!m_threads.count) { - m_threads.count = Cpu::info()->optimalThreadsCount(size, 100); - } -// else if (m_safe) { -// const size_t count = Cpu::info()->optimalThreadsCount(size, m_maxCpuUsage); -// if (m_threads.count > count) { -// m_threads.count = count; -// } -// } - - for (size_t i = 0; i < m_threads.count; ++i) { - m_threads.list.push_back(CpuThreadLegacy::createFromAV(i, algorithm, av, m_threads.mask, m_cpu.priority(), m_cpu.assembly())); - } - - m_shouldSave = m_threads.mode == Automatic; - - return true; -} - - -void xmrig::Config::setAlgoVariant(int av) -{ - if (av >= CnHash::AV_AUTO && av < CnHash::AV_MAX) { - m_algoVariant = static_cast(av); - } -} - - -void xmrig::Config::setThreads(const rapidjson::Value &threads) -{ - if (threads.IsArray()) { - m_threads.cpu.clear(); - - for (const rapidjson::Value &value : threads.GetArray()) { - if (!value.IsObject()) { - continue; - } - - if (value.HasMember("low_power_mode")) { - auto data = CpuThreadLegacy::parse(value); - - if (data.valid) { - m_threads.cpu.push_back(std::move(data)); - } - } - } - } - else if (threads.IsUint()) { - const unsigned count = threads.GetUint(); - if (count < 1024) { - m_threads.count = count; - } - } -} - - -xmrig::CnHash::AlgoVariant xmrig::Config::getAlgoVariant() const -{ -# ifdef XMRIG_ALGO_CN_LITE -// if (m_algorithm.algo() == xmrig::CRYPTONIGHT_LITE) { // FIXME -// return getAlgoVariantLite(); -// } -# endif - - if (m_algoVariant <= CnHash::AV_AUTO || m_algoVariant >= CnHash::AV_MAX) { - return Cpu::info()->hasAES() ? CnHash::AV_SINGLE : CnHash::AV_SINGLE_SOFT; - } - -// if (m_safe && !Cpu::info()->hasAES() && m_algoVariant <= AV_DOUBLE) { -// return static_cast(m_algoVariant + 2); -// } - - return m_algoVariant; -} - - -#ifdef XMRIG_ALGO_CN_LITE -xmrig::CnHash::AlgoVariant xmrig::Config::getAlgoVariantLite() const -{ - if (m_algoVariant <= CnHash::AV_AUTO || m_algoVariant >= CnHash::AV_MAX) { - return Cpu::info()->hasAES() ? CnHash::AV_DOUBLE : CnHash::AV_DOUBLE_SOFT; - } - -// if (m_safe && !Cpu::info()->hasAES() && m_algoVariant <= AV_DOUBLE) { -// return static_cast(m_algoVariant + 2); -// } - - return m_algoVariant; -} -#endif diff --git a/src/core/config/Config.h b/src/core/config/Config.h index aa547796..e6b5c735 100644 --- a/src/core/config/Config.h +++ b/src/core/config/Config.h @@ -27,13 +27,11 @@ #include -#include #include "backend/cpu/CpuConfig.h" #include "base/kernel/config/BaseConfig.h" #include "rapidjson/fwd.h" -#include "workers/CpuThreadLegacy.h" namespace xmrig { @@ -45,51 +43,17 @@ class IThread; class Config : public BaseConfig { public: - enum ThreadsMode { - Automatic, - Simple, - Advanced - }; - - Config(); bool read(const IJsonReader &reader, const char *fileName) override; void getJSON(rapidjson::Document &doc) const override; - inline CnHash::AlgoVariant algoVariant() const { return m_algoVariant; } - inline bool isShouldSave() const { return (m_shouldSave || m_upgrade || m_cpu.isShouldSave()) && isAutoSave(); } - inline const CpuConfig &cpu() const { return m_cpu; } - inline const std::vector &threads() const { return m_threads.list; } - inline int threadsCount() const { return static_cast(m_threads.list.size()); } - inline ThreadsMode threadsMode() const { return m_threads.mode; } + inline bool isShouldSave() const { return (m_shouldSave || m_upgrade || m_cpu.isShouldSave()) && isAutoSave(); } + inline const CpuConfig &cpu() const { return m_cpu; } private: - bool finalize(); - void setAlgoVariant(int av); - void setThreads(const rapidjson::Value &threads); - - CnHash::AlgoVariant getAlgoVariant() const; -# ifdef XMRIG_ALGO_CN_LITE - CnHash::AlgoVariant getAlgoVariantLite() const; -# endif - - struct Threads - { - inline Threads() : mask(-1L), count(0), mode(Automatic) {} - - int64_t mask; - size_t count; - std::vector cpu; - std::vector list; - ThreadsMode mode; - }; - - - CnHash::AlgoVariant m_algoVariant; - bool m_shouldSave; + bool m_shouldSave = false; CpuConfig m_cpu; - Threads m_threads; }; diff --git a/src/workers/CpuThreadLegacy.cpp b/src/workers/CpuThreadLegacy.cpp deleted file mode 100644 index b5d457c7..00000000 --- a/src/workers/CpuThreadLegacy.cpp +++ /dev/null @@ -1,219 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017-2018 XMR-Stak , - * Copyright 2018-2019 SChernykh - * Copyright 2016-2019 XMRig , - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include - - -#include "base/io/log/Log.h" -#include "crypto/cn/CnHash.h" -#include "crypto/common/Assembly.h" -#include "crypto/common/VirtualMemory.h" -#include "rapidjson/document.h" -#include "workers/CpuThreadLegacy.h" - - -xmrig::CpuThreadLegacy::CpuThreadLegacy(size_t index, Algorithm algorithm, CnHash::AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch, Assembly assembly) : - m_algorithm(algorithm), - m_av(av), - m_assembly(assembly), - m_prefetch(prefetch), - m_softAES(softAES), - m_priority(priority), - m_affinity(affinity), - m_multiway(multiway), - m_index(index) -{ -} - - -xmrig::cn_hash_fun xmrig::CpuThreadLegacy::fn(const Algorithm &algorithm) const -{ - return CnHash::fn(algorithm, m_av, m_assembly); -} - - - -bool xmrig::CpuThreadLegacy::isSoftAES(CnHash::AlgoVariant av) -{ - return av == CnHash::AV_SINGLE_SOFT || av == CnHash::AV_DOUBLE_SOFT || av > CnHash::AV_PENTA; -} - - -xmrig::CpuThreadLegacy *xmrig::CpuThreadLegacy::createFromAV(size_t index, const Algorithm &algorithm, CnHash::AlgoVariant av, int64_t affinity, int priority, Assembly assembly) -{ - assert(av > CnHash::AV_AUTO && av < CnHash::AV_MAX); - - int64_t cpuId = -1L; - - if (affinity != -1L) { - size_t idx = 0; - - for (size_t i = 0; i < 64; i++) { - if (!(affinity & (1ULL << i))) { - continue; - } - - if (idx == index) { - cpuId = i; - break; - } - - idx++; - } - } - - return new CpuThreadLegacy(index, algorithm, av, multiway(av), cpuId, priority, isSoftAES(av), false, assembly); -} - - -xmrig::CpuThreadLegacy *xmrig::CpuThreadLegacy::createFromData(size_t index, const Algorithm &algorithm, const CpuThreadLegacy::Data &data, int priority, bool softAES) -{ - int av = CnHash::AV_AUTO; - const Multiway multiway = data.multiway; - - if (multiway <= DoubleWay) { - av = softAES ? (multiway + 2) : multiway; - } - else { - av = softAES ? (multiway + 5) : (multiway + 2); - } - - assert(av > CnHash::AV_AUTO && av < CnHash::AV_MAX); - - return new CpuThreadLegacy(index, algorithm, static_cast(av), multiway, data.affinity, priority, softAES, false, data.assembly); -} - - -xmrig::CpuThreadLegacy::Data xmrig::CpuThreadLegacy::parse(const rapidjson::Value &object) -{ - Data data; - - const auto &multiway = object["low_power_mode"]; - if (multiway.IsBool()) { - data.multiway = multiway.IsTrue() ? DoubleWay : SingleWay; - data.valid = true; - } - else if (multiway.IsUint()) { - data.setMultiway(multiway.GetInt()); - } - - if (!data.valid) { - return data; - } - - const auto &affinity = object["affine_to_cpu"]; - if (affinity.IsUint64()) { - data.affinity = affinity.GetInt64(); - } - -# ifdef XMRIG_FEATURE_ASM - data.assembly = object["asm"]; -# endif - - return data; -} - - -xmrig::IThread::Multiway xmrig::CpuThreadLegacy::multiway(CnHash::AlgoVariant av) -{ - switch (av) { - case CnHash::AV_SINGLE: - case CnHash::AV_SINGLE_SOFT: - return SingleWay; - - case CnHash::AV_DOUBLE_SOFT: - case CnHash::AV_DOUBLE: - return DoubleWay; - - case CnHash::AV_TRIPLE_SOFT: - case CnHash::AV_TRIPLE: - return TripleWay; - - case CnHash::AV_QUAD_SOFT: - case CnHash::AV_QUAD: - return QuadWay; - - case CnHash::AV_PENTA_SOFT: - case CnHash::AV_PENTA: - return PentaWay; - - default: - break; - } - - return SingleWay; -} - - -#ifdef APP_DEBUG -void xmrig::CpuThreadLegacy::print() const -{ - LOG_DEBUG(GREEN_BOLD("CPU thread: ") " index " WHITE_BOLD("%zu") ", multiway " WHITE_BOLD("%d") ", av " WHITE_BOLD("%d") ",", - index(), static_cast(multiway()), static_cast(m_av)); - -# ifdef XMRIG_FEATURE_ASM - LOG_DEBUG(" assembly: %s, affine_to_cpu: %" PRId64, m_assembly.toString(), affinity()); -# else - LOG_DEBUG(" affine_to_cpu: %" PRId64, affinity()); -# endif -} -#endif - - -#ifdef XMRIG_FEATURE_API -rapidjson::Value xmrig::CpuThreadLegacy::toAPI(rapidjson::Document &doc) const -{ - using namespace rapidjson; - - Value obj(kObjectType); - auto &allocator = doc.GetAllocator(); - - obj.AddMember("type", "cpu", allocator); - obj.AddMember("av", m_av, allocator); - obj.AddMember("low_power_mode", multiway(), allocator); - obj.AddMember("affine_to_cpu", affinity(), allocator); - obj.AddMember("priority", priority(), allocator); - obj.AddMember("soft_aes", isSoftAES(), allocator); - - return obj; -} -#endif - - -rapidjson::Value xmrig::CpuThreadLegacy::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); - -# ifdef XMRIG_FEATURE_ASM - obj.AddMember("asm", m_assembly.toJSON(), allocator); -# endif - - return obj; -} diff --git a/src/workers/CpuThreadLegacy.h b/src/workers/CpuThreadLegacy.h deleted file mode 100644 index b803a8c4..00000000 --- a/src/workers/CpuThreadLegacy.h +++ /dev/null @@ -1,108 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017-2018 XMR-Stak , - * Copyright 2018-2019 SChernykh - * Copyright 2016-2019 XMRig , - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef XMRIG_CPUTHREADLEGACY_H -#define XMRIG_CPUTHREADLEGACY_H - - -#include "backend/common/interfaces/IThread.h" -#include "crypto/cn/CnHash.h" - - -struct cryptonight_ctx; - - -namespace xmrig { - - -class CpuThreadLegacy : public IThread -{ -public: - struct Data - { - inline Data() : valid(false), affinity(-1L), multiway(SingleWay) {} - - inline void setMultiway(int value) - { - if (value >= SingleWay && value <= PentaWay) { - multiway = static_cast(value); - valid = true; - } - } - - Assembly assembly; - bool valid; - int64_t affinity; - Multiway multiway; - }; - - - CpuThreadLegacy(size_t index, Algorithm algorithm, CnHash::AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch, Assembly assembly); - - cn_hash_fun fn(const Algorithm &algorithm) const; - - static bool isSoftAES(CnHash::AlgoVariant av); - static CpuThreadLegacy *createFromAV(size_t index, const Algorithm &algorithm, CnHash::AlgoVariant av, int64_t affinity, int priority, Assembly assembly); - static CpuThreadLegacy *createFromData(size_t index, const Algorithm &algorithm, const CpuThreadLegacy::Data &data, int priority, bool softAES); - static Data parse(const rapidjson::Value &object); - static Multiway multiway(CnHash::AlgoVariant av); - - inline bool isPrefetch() const { return m_prefetch; } - inline bool isSoftAES() const { return m_softAES; } - - inline Algorithm algorithm() const override { return m_algorithm; } - inline int priority() const override { return m_priority; } - inline int64_t affinity() const override { return m_affinity; } - inline Multiway multiway() const override { return m_multiway; } - inline size_t index() const override { return m_index; } - inline Type type() const override { return CPU; } - -protected: -# ifdef APP_DEBUG - void print() const override; -# endif - -# ifdef XMRIG_FEATURE_API - rapidjson::Value toAPI(rapidjson::Document &doc) const override; -# endif - - rapidjson::Value toConfig(rapidjson::Document &doc) const override; - -private: - const Algorithm m_algorithm; - const CnHash::AlgoVariant m_av; - const Assembly m_assembly; - const bool m_prefetch; - const bool m_softAES; - const int m_priority; - const int64_t m_affinity; - const Multiway m_multiway; - const size_t m_index; -}; - - -} /* namespace xmrig */ - - -#endif /* XMRIG_CPUTHREADLEGACY_H */ From 871bc3e1801c979a51e244b5c4485743684ccd62 Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 18 Jul 2019 04:21:14 +0700 Subject: [PATCH 35/48] Fixed bugs. --- src/backend/common/Thread.h | 6 ++++-- src/backend/cpu/CpuWorker.cpp | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/backend/common/Thread.h b/src/backend/common/Thread.h index b62d880c..36367ece 100644 --- a/src/backend/common/Thread.h +++ b/src/backend/common/Thread.h @@ -29,11 +29,13 @@ #include +#include "backend/common/interfaces/IWorker.h" + + namespace xmrig { class IBackend; -class IWorker; template @@ -41,7 +43,7 @@ class Thread { public: inline Thread(IBackend *backend, size_t index, const T &config) : m_index(index), m_config(config), m_backend(backend) {} - inline ~Thread() { uv_thread_join(&m_thread); } + inline ~Thread() { uv_thread_join(&m_thread); delete m_worker; } inline const T &config() const { return m_config; } inline IBackend *backend() const { return m_backend; } diff --git a/src/backend/cpu/CpuWorker.cpp b/src/backend/cpu/CpuWorker.cpp index 356dfb1b..4318b8ce 100644 --- a/src/backend/cpu/CpuWorker.cpp +++ b/src/backend/cpu/CpuWorker.cpp @@ -158,7 +158,7 @@ void xmrig::CpuWorker::start() do { std::this_thread::sleep_for(std::chrono::milliseconds(200)); } - while (Nonce::isPaused()); + while (Nonce::isPaused() && Nonce::sequence(Nonce::CPU) > 0); if (Nonce::sequence(Nonce::CPU) == 0) { break; From f590cf58fb9f2b0899354402213087832610bf87 Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 18 Jul 2019 19:11:45 +0700 Subject: [PATCH 36/48] Added support for threads restart if config changed. --- src/backend/common/Workers.cpp | 13 ++--- src/backend/common/Workers.h | 3 +- src/backend/common/interfaces/IBackend.h | 16 +++--- src/backend/cpu/CpuBackend.cpp | 73 ++++++++++-------------- src/backend/cpu/CpuBackend.h | 1 + src/backend/cpu/CpuConfig.cpp | 19 ++++++ src/backend/cpu/CpuConfig.h | 2 + src/backend/cpu/CpuLaunchData.cpp | 13 +++++ src/backend/cpu/CpuLaunchData.h | 4 ++ src/base/net/stratum/Pool.cpp | 3 +- src/core/Miner.cpp | 16 ++++++ src/core/Miner.h | 4 +- 12 files changed, 105 insertions(+), 62 deletions(-) diff --git a/src/backend/common/Workers.cpp b/src/backend/common/Workers.cpp index 629b564b..d70546d3 100644 --- a/src/backend/common/Workers.cpp +++ b/src/backend/common/Workers.cpp @@ -78,13 +78,6 @@ const xmrig::Hashrate *xmrig::Workers::hashrate() const } -template -void xmrig::Workers::add(const T &data) -{ - m_workers.push_back(new Thread(d_ptr->backend, m_workers.size(), data)); -} - - template void xmrig::Workers::setBackend(IBackend *backend) { @@ -93,8 +86,12 @@ void xmrig::Workers::setBackend(IBackend *backend) template -void xmrig::Workers::start() +void xmrig::Workers::start(const std::vector &data) { + for (const T &item : data) { + m_workers.push_back(new Thread(d_ptr->backend, m_workers.size(), item)); + } + d_ptr->hashrate = new Hashrate(m_workers.size()); for (Thread *worker : m_workers) { diff --git a/src/backend/common/Workers.h b/src/backend/common/Workers.h index c13f5e77..32d9458a 100644 --- a/src/backend/common/Workers.h +++ b/src/backend/common/Workers.h @@ -46,9 +46,8 @@ public: ~Workers(); const Hashrate *hashrate() const; - void add(const T &data); void setBackend(IBackend *backend); - void start(); + void start(const std::vector &data); void stop(); void tick(uint64_t ticks); diff --git a/src/backend/common/interfaces/IBackend.h b/src/backend/common/interfaces/IBackend.h index 8ad7bb53..6fe917cb 100644 --- a/src/backend/common/interfaces/IBackend.h +++ b/src/backend/common/interfaces/IBackend.h @@ -32,6 +32,7 @@ namespace xmrig { +class Algorithm; class Hashrate; class IWorker; class Job; @@ -43,13 +44,14 @@ class IBackend public: virtual ~IBackend() = default; - virtual const Hashrate *hashrate() const = 0; - virtual const String &profileName() const = 0; - virtual void printHashrate(bool details) = 0; - virtual void setJob(const Job &job) = 0; - virtual void start(IWorker *worker) = 0; - virtual void stop() = 0; - virtual void tick(uint64_t ticks) = 0; + virtual bool isEnabled(const Algorithm &algorithm) const = 0; + virtual const Hashrate *hashrate() const = 0; + virtual const String &profileName() const = 0; + virtual void printHashrate(bool details) = 0; + virtual void setJob(const Job &job) = 0; + virtual void start(IWorker *worker) = 0; + virtual void stop() = 0; + virtual void tick(uint64_t ticks) = 0; }; diff --git a/src/backend/cpu/CpuBackend.cpp b/src/backend/cpu/CpuBackend.cpp index f325d0ff..15a0c359 100644 --- a/src/backend/cpu/CpuBackend.cpp +++ b/src/backend/cpu/CpuBackend.cpp @@ -85,40 +85,8 @@ public: } - inline bool isReady(const Algorithm &nextAlgo) const + inline void start() { - if (!algo.isValid()) { - return false; - } - - if (nextAlgo == algo) { - return true; - } - - const CpuThreads &nextThreads = controller->config()->cpu().threads().get(nextAlgo); - - return algo.memory() == nextAlgo.memory() - && threads.size() == nextThreads.size() - && std::equal(threads.begin(), threads.end(), nextThreads.begin()); - } - - - inline void start(const Job &job) - { - const CpuConfig &cpu = controller->config()->cpu(); - - algo = job.algorithm(); - profileName = cpu.threads().profileName(job.algorithm()); - threads = cpu.threads().get(profileName); - - if (profileName.isNull() || threads.empty()) { - workers.stop(); - - LOG_WARN(YELLOW_BOLD_S "CPU disabled, no suitable configuration for algo %s", job.algorithm().shortName()); - - return; - } - LOG_INFO(GREEN_BOLD("CPU") " use profile " BLUE_BG(WHITE_BOLD_S " %s ") WHITE_BOLD_S " (" CYAN_BOLD("%zu") WHITE_BOLD(" threads)") " scratchpad " CYAN_BOLD("%zu KB"), profileName.data(), threads.size(), @@ -131,20 +99,18 @@ public: status.memory = algo.memory(); status.threads = threads.size(); - for (const CpuThread &thread : threads) { - workers.add(CpuLaunchData(controller->miner(), algo, cpu, thread)); - - status.ways += static_cast(thread.intensity()); + for (const CpuLaunchData &data : threads) { + status.ways += static_cast(data.intensity); } - workers.start(); + workers.start(threads); } Algorithm algo; Controller *controller; - CpuThreads threads; LaunchStatus status; + std::vector threads; String profileName; uv_mutex_t mutex; Workers workers; @@ -167,6 +133,12 @@ xmrig::CpuBackend::~CpuBackend() } +bool xmrig::CpuBackend::isEnabled(const Algorithm &algorithm) const +{ + return !d_ptr->controller->config()->cpu().threads().get(algorithm).empty(); +} + + const xmrig::Hashrate *xmrig::CpuBackend::hashrate() const { return d_ptr->workers.hashrate(); @@ -190,10 +162,10 @@ void xmrig::CpuBackend::printHashrate(bool details) Log::print(WHITE_BOLD_S "| CPU THREAD | AFFINITY | 10s H/s | 60s H/s | 15m H/s |"); size_t i = 0; - for (const CpuThread &thread : d_ptr->threads) { + for (const CpuLaunchData &data : d_ptr->threads) { Log::print("| %13zu | %8" PRId64 " | %7s | %7s | %7s |", i, - thread.affinity(), + data.affinity, Hashrate::format(hashrate()->calc(i, Hashrate::ShortInterval), num, sizeof num / 3), Hashrate::format(hashrate()->calc(i, Hashrate::MediumInterval), num + 8, sizeof num / 3), Hashrate::format(hashrate()->calc(i, Hashrate::LargeInterval), num + 8 * 2, sizeof num / 3) @@ -206,11 +178,26 @@ void xmrig::CpuBackend::printHashrate(bool details) void xmrig::CpuBackend::setJob(const Job &job) { - if (d_ptr->isReady(job.algorithm())) { + const CpuConfig &cpu = d_ptr->controller->config()->cpu(); + + std::vector threads = cpu.get(d_ptr->controller->miner(), job.algorithm()); + if (d_ptr->threads.size() == threads.size() && std::equal(d_ptr->threads.begin(), d_ptr->threads.end(), threads.begin())) { return; } - d_ptr->start(job); + d_ptr->algo = job.algorithm(); + d_ptr->profileName = cpu.threads().profileName(job.algorithm()); + + if (d_ptr->profileName.isNull() || threads.empty()) { + d_ptr->workers.stop(); + + LOG_WARN(YELLOW_BOLD_S "CPU disabled, no suitable configuration for algo %s", job.algorithm().shortName()); + + return; + } + + d_ptr->threads = std::move(threads); + d_ptr->start(); } diff --git a/src/backend/cpu/CpuBackend.h b/src/backend/cpu/CpuBackend.h index aabccb49..543d4459 100644 --- a/src/backend/cpu/CpuBackend.h +++ b/src/backend/cpu/CpuBackend.h @@ -44,6 +44,7 @@ public: ~CpuBackend() override; protected: + bool isEnabled(const Algorithm &algorithm) const override; const Hashrate *hashrate() const override; const String &profileName() const override; void printHashrate(bool details) override; diff --git a/src/backend/cpu/CpuConfig.cpp b/src/backend/cpu/CpuConfig.cpp index b4a9c363..457f7ef4 100644 --- a/src/backend/cpu/CpuConfig.cpp +++ b/src/backend/cpu/CpuConfig.cpp @@ -100,6 +100,25 @@ rapidjson::Value xmrig::CpuConfig::toJSON(rapidjson::Document &doc) const } +std::vector xmrig::CpuConfig::get(const Miner *miner, const Algorithm &algorithm) const +{ + std::vector out; + const std::vector &threads = m_threads.get(algorithm); + + if (threads.empty()) { + return out; + } + + out.reserve(threads.size()); + + for (const CpuThread &thread : threads) { + out.push_back(CpuLaunchData(miner, algorithm, *this, thread)); + } + + return out; +} + + void xmrig::CpuConfig::read(const rapidjson::Value &value) { if (value.IsObject()) { diff --git a/src/backend/cpu/CpuConfig.h b/src/backend/cpu/CpuConfig.h index 88222ab1..8ff8b77c 100644 --- a/src/backend/cpu/CpuConfig.h +++ b/src/backend/cpu/CpuConfig.h @@ -27,6 +27,7 @@ #include "backend/common/Threads.h" +#include "backend/cpu/CpuLaunchData.h" #include "backend/cpu/CpuThread.h" #include "crypto/common/Assembly.h" @@ -47,6 +48,7 @@ public: bool isHwAES() const; rapidjson::Value toJSON(rapidjson::Document &doc) const; + std::vector get(const Miner *miner, const Algorithm &algorithm) const; void read(const rapidjson::Value &value); inline bool isEnabled() const { return m_enabled; } diff --git a/src/backend/cpu/CpuLaunchData.cpp b/src/backend/cpu/CpuLaunchData.cpp index 68b8e7ae..6fa458aa 100644 --- a/src/backend/cpu/CpuLaunchData.cpp +++ b/src/backend/cpu/CpuLaunchData.cpp @@ -41,6 +41,19 @@ xmrig::CpuLaunchData::CpuLaunchData(const Miner *miner, const Algorithm &algorit } +bool xmrig::CpuLaunchData::isEqual(const CpuLaunchData &other) const +{ + return (algorithm.memory() == other.algorithm.memory() + && assembly == other.assembly + && hugePages == other.hugePages + && hwAES == other.hwAES + && intensity == other.intensity + && priority == other.priority + && affinity == other.affinity + ); +} + + xmrig::CnHash::AlgoVariant xmrig::CpuLaunchData::av() const { if (intensity <= 2) { diff --git a/src/backend/cpu/CpuLaunchData.h b/src/backend/cpu/CpuLaunchData.h index 208a68b7..bb18816a 100644 --- a/src/backend/cpu/CpuLaunchData.h +++ b/src/backend/cpu/CpuLaunchData.h @@ -46,10 +46,14 @@ class CpuLaunchData public: CpuLaunchData(const Miner *miner, const Algorithm &algorithm, const CpuConfig &config, const CpuThread &thread); + bool isEqual(const CpuLaunchData &other) const; CnHash::AlgoVariant av() const; inline constexpr static Nonce::Backend backend() { return Nonce::CPU; } + inline bool operator!=(const CpuLaunchData &other) const { return !isEqual(other); } + inline bool operator==(const CpuLaunchData &other) const { return isEqual(other); } + const Algorithm algorithm; const Assembly assembly; const bool hugePages; diff --git a/src/base/net/stratum/Pool.cpp b/src/base/net/stratum/Pool.cpp index b11e1159..4d15ea47 100644 --- a/src/base/net/stratum/Pool.cpp +++ b/src/base/net/stratum/Pool.cpp @@ -192,7 +192,8 @@ bool xmrig::Pool::isEqual(const Pool &other) const && m_rigId == other.m_rigId && m_url == other.m_url && m_user == other.m_user - && m_pollInterval == other.m_pollInterval); + && m_pollInterval == other.m_pollInterval + ); } diff --git a/src/core/Miner.cpp b/src/core/Miner.cpp index 40321662..4135e8ab 100644 --- a/src/core/Miner.cpp +++ b/src/core/Miner.cpp @@ -99,6 +99,8 @@ public: xmrig::Miner::Miner(Controller *controller) : d_ptr(new MinerPrivate(controller)) { + controller->addListener(this); + d_ptr->timer = new Timer(this); d_ptr->backends.push_back(new CpuBackend(controller)); @@ -218,6 +220,20 @@ void xmrig::Miner::stop() } +void xmrig::Miner::onConfigChanged(Config *config, Config *previousConfig) +{ + if (config->pools() != previousConfig->pools() && config->pools().active() > 0) { + return; + } + + const Job job = this->job(); + + for (IBackend *backend : d_ptr->backends) { + backend->setJob(job); + } +} + + void xmrig::Miner::onTimer(const Timer *) { double maxHashrate = 0.0; diff --git a/src/core/Miner.h b/src/core/Miner.h index f32524a7..23497eae 100644 --- a/src/core/Miner.h +++ b/src/core/Miner.h @@ -29,6 +29,7 @@ #include +#include "base/kernel/interfaces/IBaseListener.h" #include "base/kernel/interfaces/ITimerListener.h" @@ -41,7 +42,7 @@ class MinerPrivate; class IBackend; -class Miner : public ITimerListener +class Miner : public ITimerListener, public IBaseListener { public: Miner(Controller *controller); @@ -57,6 +58,7 @@ public: void stop(); protected: + void onConfigChanged(Config *config, Config *previousConfig) override; void onTimer(const Timer *timer) override; private: From 0ab26a16193e79d7ddf848e35d390fdae5469c23 Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 18 Jul 2019 22:35:15 +0700 Subject: [PATCH 37/48] Restored algo field in login request. --- src/backend/cpu/CpuWorker.cpp | 4 ++ .../kernel/interfaces/IStrategyListener.h | 3 +- src/base/net/stratum/Client.cpp | 13 ----- .../stratum/strategies/FailoverStrategy.cpp | 8 +++- .../net/stratum/strategies/FailoverStrategy.h | 6 +-- .../stratum/strategies/SinglePoolStrategy.cpp | 8 +++- .../stratum/strategies/SinglePoolStrategy.h | 6 +-- src/core/Miner.cpp | 48 +++++++++++++++++-- src/core/Miner.h | 2 + src/crypto/common/Algorithm.h | 2 +- src/net/Network.cpp | 15 ++++++ src/net/Network.h | 1 + src/net/strategies/DonateStrategy.cpp | 43 ++++++++++++++--- src/net/strategies/DonateStrategy.h | 5 +- 14 files changed, 129 insertions(+), 35 deletions(-) diff --git a/src/backend/cpu/CpuWorker.cpp b/src/backend/cpu/CpuWorker.cpp index 4318b8ce..e35c5155 100644 --- a/src/backend/cpu/CpuWorker.cpp +++ b/src/backend/cpu/CpuWorker.cpp @@ -174,6 +174,10 @@ void xmrig::CpuWorker::start() const Job &job = m_job.currentJob(); + if (job.algorithm().memory() != m_algorithm.memory()) { + break; + } + # ifdef XMRIG_ALGO_RANDOMX if (job.algorithm().family() == Algorithm::RANDOM_X) { randomx_calculate_hash(m_vm->get(), m_job.blob(), job.size(), m_hash); diff --git a/src/base/kernel/interfaces/IStrategyListener.h b/src/base/kernel/interfaces/IStrategyListener.h index 2e63449b..01e668d4 100644 --- a/src/base/kernel/interfaces/IStrategyListener.h +++ b/src/base/kernel/interfaces/IStrategyListener.h @@ -26,7 +26,7 @@ #define XMRIG_ISTRATEGYLISTENER_H -#include +#include "rapidjson/fwd.h" namespace xmrig { @@ -45,6 +45,7 @@ public: virtual void onActive(IStrategy *strategy, IClient *client) = 0; virtual void onJob(IStrategy *strategy, IClient *client, const Job &job) = 0; + virtual void onLogin(IStrategy *strategy, IClient *client, rapidjson::Document &doc, rapidjson::Value ¶ms) = 0; virtual void onPause(IStrategy *strategy) = 0; virtual void onResultAccepted(IStrategy *strategy, IClient *client, const SubmitResult &result, const char *error) = 0; }; diff --git a/src/base/net/stratum/Client.cpp b/src/base/net/stratum/Client.cpp index c1519573..0be86eca 100644 --- a/src/base/net/stratum/Client.cpp +++ b/src/base/net/stratum/Client.cpp @@ -575,19 +575,6 @@ void xmrig::Client::login() params.AddMember("rigid", m_pool.rigId().toJSON(), allocator); } -//# ifdef XMRIG_PROXY_PROJECT FIXME -// if (m_pool.algorithm().variant() != xmrig::VARIANT_AUTO) -//# endif -// { -// Value algo(kArrayType); - -// for (const auto &a : m_pool.algorithms()) { -// algo.PushBack(StringRef(a.shortName()), allocator); -// } - -// params.AddMember("algo", algo, allocator); -// } - m_listener->onLogin(this, doc, params); JsonRequest::create(doc, 1, "login", params); diff --git a/src/base/net/stratum/strategies/FailoverStrategy.cpp b/src/base/net/stratum/strategies/FailoverStrategy.cpp index 9545e9e1..4a35f3a5 100644 --- a/src/base/net/stratum/strategies/FailoverStrategy.cpp +++ b/src/base/net/stratum/strategies/FailoverStrategy.cpp @@ -113,7 +113,7 @@ void xmrig::FailoverStrategy::resume() } -void xmrig::FailoverStrategy::setAlgo(const xmrig::Algorithm &algo) +void xmrig::FailoverStrategy::setAlgo(const Algorithm &algo) { for (IClient *client : m_pools) { client->setAlgo(algo); @@ -163,6 +163,12 @@ void xmrig::FailoverStrategy::onClose(IClient *client, int failures) } +void xmrig::FailoverStrategy::onLogin(IClient *client, rapidjson::Document &doc, rapidjson::Value ¶ms) +{ + m_listener->onLogin(this, client, doc, params); +} + + void xmrig::FailoverStrategy::onJobReceived(IClient *client, const Job &job, const rapidjson::Value &) { if (m_active == client->id()) { diff --git a/src/base/net/stratum/strategies/FailoverStrategy.h b/src/base/net/stratum/strategies/FailoverStrategy.h index b1fe8bac..5336a634 100644 --- a/src/base/net/stratum/strategies/FailoverStrategy.h +++ b/src/base/net/stratum/strategies/FailoverStrategy.h @@ -51,9 +51,8 @@ public: void add(const Pool &pool); protected: - inline bool isActive() const override { return m_active >= 0; } - inline IClient *client() const override { return isActive() ? active() : m_pools[m_index]; } - inline void onLogin(IClient *, rapidjson::Document &, rapidjson::Value &) override {} + inline bool isActive() const override { return m_active >= 0; } + inline IClient *client() const override { return isActive() ? active() : m_pools[m_index]; } int64_t submit(const JobResult &result) override; void connect() override; @@ -64,6 +63,7 @@ protected: void onClose(IClient *client, int failures) override; void onJobReceived(IClient *client, const Job &job, const rapidjson::Value ¶ms) override; + void onLogin(IClient *client, rapidjson::Document &doc, rapidjson::Value ¶ms) override; void onLoginSuccess(IClient *client) override; void onResultAccepted(IClient *client, const SubmitResult &result, const char *error) override; diff --git a/src/base/net/stratum/strategies/SinglePoolStrategy.cpp b/src/base/net/stratum/strategies/SinglePoolStrategy.cpp index 6c6a6fc1..5f09d174 100644 --- a/src/base/net/stratum/strategies/SinglePoolStrategy.cpp +++ b/src/base/net/stratum/strategies/SinglePoolStrategy.cpp @@ -84,7 +84,7 @@ void xmrig::SinglePoolStrategy::resume() } -void xmrig::SinglePoolStrategy::setAlgo(const xmrig::Algorithm &algo) +void xmrig::SinglePoolStrategy::setAlgo(const Algorithm &algo) { m_client->setAlgo(algo); } @@ -119,6 +119,12 @@ void xmrig::SinglePoolStrategy::onJobReceived(IClient *client, const Job &job, c } +void xmrig::SinglePoolStrategy::onLogin(IClient *client, rapidjson::Document &doc, rapidjson::Value ¶ms) +{ + m_listener->onLogin(this, client, doc, params); +} + + void xmrig::SinglePoolStrategy::onLoginSuccess(IClient *client) { m_active = true; diff --git a/src/base/net/stratum/strategies/SinglePoolStrategy.h b/src/base/net/stratum/strategies/SinglePoolStrategy.h index af0bd7d6..04eef40e 100644 --- a/src/base/net/stratum/strategies/SinglePoolStrategy.h +++ b/src/base/net/stratum/strategies/SinglePoolStrategy.h @@ -45,9 +45,8 @@ public: ~SinglePoolStrategy() override; protected: - inline bool isActive() const override { return m_active; } - inline IClient *client() const override { return m_client; } - inline void onLogin(IClient *, rapidjson::Document &, rapidjson::Value &) override {} + inline bool isActive() const override { return m_active; } + inline IClient *client() const override { return m_client; } int64_t submit(const JobResult &result) override; void connect() override; @@ -58,6 +57,7 @@ protected: void onClose(IClient *client, int failures) override; void onJobReceived(IClient *client, const Job &job, const rapidjson::Value ¶ms) override; + void onLogin(IClient *client, rapidjson::Document &doc, rapidjson::Value ¶ms) override; void onLoginSuccess(IClient *client) override; void onResultAccepted(IClient *client, const SubmitResult &result, const char *error) override; diff --git a/src/core/Miner.cpp b/src/core/Miner.cpp index 4135e8ab..891a0f34 100644 --- a/src/core/Miner.cpp +++ b/src/core/Miner.cpp @@ -62,17 +62,46 @@ public: } + bool isEnabled(const Algorithm &algorithm) const + { + for (IBackend *backend : backends) { + if (backend->isEnabled(algorithm)) { + return true; + } + } + + return false; + } + + + inline void rebuild() + { + algorithms.clear(); + + for (int i = 0; i < Algorithm::MAX; ++i) { + const Algorithm algo(static_cast(i)); + + if (isEnabled(algo)) { + algorithms.push_back(algo); + } + } + } + + inline void handleJobChange() { active = true; - if (enabled) { - Nonce::pause(false);; - } for (IBackend *backend : backends) { backend->setJob(job); } + if (enabled) { + Nonce::pause(false);; + } + + Nonce::reset(job.index()); + if (ticks == 0) { ticks++; timer->start(500, 500); @@ -80,6 +109,7 @@ public: } + Algorithms algorithms; bool active = false; bool enabled = true; Controller *controller; @@ -104,6 +134,8 @@ xmrig::Miner::Miner(Controller *controller) d_ptr->timer = new Timer(this); d_ptr->backends.push_back(new CpuBackend(controller)); + + d_ptr->rebuild(); } @@ -119,6 +151,12 @@ bool xmrig::Miner::isEnabled() const } +const xmrig::Algorithms &xmrig::Miner::algorithms() const +{ + return d_ptr->algorithms; +} + + const std::vector &xmrig::Miner::backends() const { return d_ptr->backends; @@ -202,8 +240,6 @@ void xmrig::Miner::setJob(const Job &job, bool donate) d_ptr->job = job; d_ptr->job.setIndex(index); - Nonce::reset(index); - uv_rwlock_wrunlock(&d_ptr->rwlock); d_ptr->handleJobChange(); @@ -222,6 +258,8 @@ void xmrig::Miner::stop() void xmrig::Miner::onConfigChanged(Config *config, Config *previousConfig) { + d_ptr->rebuild(); + if (config->pools() != previousConfig->pools() && config->pools().active() > 0) { return; } diff --git a/src/core/Miner.h b/src/core/Miner.h index 23497eae..dd195e29 100644 --- a/src/core/Miner.h +++ b/src/core/Miner.h @@ -31,6 +31,7 @@ #include "base/kernel/interfaces/IBaseListener.h" #include "base/kernel/interfaces/ITimerListener.h" +#include "crypto/common/Algorithm.h" namespace xmrig { @@ -49,6 +50,7 @@ public: ~Miner() override; bool isEnabled() const; + const Algorithms &algorithms() const; const std::vector &backends() const; Job job() const; void pause(); diff --git a/src/crypto/common/Algorithm.h b/src/crypto/common/Algorithm.h index a6ec22be..a1d8ded2 100644 --- a/src/crypto/common/Algorithm.h +++ b/src/crypto/common/Algorithm.h @@ -115,7 +115,7 @@ private: }; -typedef std::vector Algorithms; +typedef std::vector Algorithms; } /* namespace xmrig */ diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 6622a080..a1c1ec8d 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -154,6 +154,21 @@ void xmrig::Network::onJobResult(const JobResult &result) } +void xmrig::Network::onLogin(IStrategy *, IClient *, rapidjson::Document &doc, rapidjson::Value ¶ms) +{ + using namespace rapidjson; + auto &allocator = doc.GetAllocator(); + + Value algo(kArrayType); + + for (const auto &a : m_controller->miner()->algorithms()) { + algo.PushBack(StringRef(a.shortName()), allocator); + } + + params.AddMember("algo", algo, allocator); +} + + void xmrig::Network::onPause(IStrategy *strategy) { if (m_donate && m_donate == strategy) { diff --git a/src/net/Network.h b/src/net/Network.h index eaec9472..bf61a9b6 100644 --- a/src/net/Network.h +++ b/src/net/Network.h @@ -63,6 +63,7 @@ protected: void onConfigChanged(Config *config, Config *previousConfig) override; void onJob(IStrategy *strategy, IClient *client, const Job &job) override; void onJobResult(const JobResult &result) override; + void onLogin(IStrategy *strategy, IClient *client, rapidjson::Document &doc, rapidjson::Value ¶ms) override; void onPause(IStrategy *strategy) override; void onRequest(IApiRequest &request) override; void onResultAccepted(IStrategy *strategy, IClient *client, const SubmitResult &result, const char *error) override; diff --git a/src/net/strategies/DonateStrategy.cpp b/src/net/strategies/DonateStrategy.cpp index 2d0a5b43..4393cd46 100644 --- a/src/net/strategies/DonateStrategy.cpp +++ b/src/net/strategies/DonateStrategy.cpp @@ -23,7 +23,9 @@ */ +#include #include +#include #include "base/kernel/Platform.h" @@ -35,6 +37,7 @@ #include "base/tools/Timer.h" #include "core/config/Config.h" #include "core/Controller.h" +#include "core/Miner.h" #include "crypto/common/keccak.h" #include "net/Network.h" #include "net/strategies/DonateStrategy.h" @@ -57,10 +60,10 @@ static const char *kDonateHostTls = "donate.ssl.xmrig.com"; xmrig::DonateStrategy::DonateStrategy(Controller *controller, IStrategyListener *listener) : m_tls(false), m_userId(), - m_proxy(nullptr), m_donateTime(static_cast(controller->config()->pools().donateLevel()) * 60 * 1000), m_idleTime((100 - static_cast(controller->config()->pools().donateLevel())) * 60 * 1000), m_controller(controller), + m_proxy(nullptr), m_strategy(nullptr), m_listener(listener), m_state(STATE_NEW), @@ -78,10 +81,6 @@ xmrig::DonateStrategy::DonateStrategy(Controller *controller, IStrategyListener # endif m_pools.push_back(Pool(kDonateHost, 3333, m_userId, nullptr, 0, true)); -// for (Pool &pool : m_pools) { -// pool.adjust(Algorithm()); // FIXME -// } - if (m_pools.size() > 1) { m_strategy = new FailoverStrategy(m_pools, 1, 2, this, true); } @@ -129,6 +128,8 @@ void xmrig::DonateStrategy::connect() void xmrig::DonateStrategy::setAlgo(const xmrig::Algorithm &algo) { + m_algorithm = algo; + m_strategy->setAlgo(algo); } @@ -185,13 +186,14 @@ void xmrig::DonateStrategy::onClose(IClient *, int failures) void xmrig::DonateStrategy::onLogin(IClient *, rapidjson::Document &doc, rapidjson::Value ¶ms) { + using namespace rapidjson; auto &allocator = doc.GetAllocator(); # ifdef XMRIG_FEATURE_TLS if (m_tls) { char buf[40] = { 0 }; snprintf(buf, sizeof(buf), "stratum+ssl://%s", m_pools[0].url().data()); - params.AddMember("url", rapidjson::Value(buf, allocator), allocator); + params.AddMember("url", Value(buf, allocator), allocator); } else { params.AddMember("url", m_pools[1].url().toJSON(), allocator); @@ -199,6 +201,14 @@ void xmrig::DonateStrategy::onLogin(IClient *, rapidjson::Document &doc, rapidjs # else params.AddMember("url", m_pools[0].url().toJSON(), allocator); # endif + + setAlgorithms(doc, params); +} + + +void xmrig::DonateStrategy::onLogin(IStrategy *, IClient *, rapidjson::Document &doc, rapidjson::Value ¶ms) +{ + setAlgorithms(doc, params); } @@ -250,6 +260,27 @@ void xmrig::DonateStrategy::idle(double min, double max) } +void xmrig::DonateStrategy::setAlgorithms(rapidjson::Document &doc, rapidjson::Value ¶ms) +{ + using namespace rapidjson; + auto &allocator = doc.GetAllocator(); + + Algorithms algorithms = m_controller->miner()->algorithms(); + const size_t index = static_cast(std::distance(algorithms.begin(), std::find(algorithms.begin(), algorithms.end(), m_algorithm))); + if (index > 0 && index < algorithms.size()) { + std::swap(algorithms[0], algorithms[index]); + } + + Value algo(kArrayType); + + for (const auto &a : algorithms) { + algo.PushBack(StringRef(a.shortName()), allocator); + } + + params.AddMember("algo", algo, allocator); +} + + void xmrig::DonateStrategy::setJob(IClient *client, const Job &job) { if (isActive()) { diff --git a/src/net/strategies/DonateStrategy.h b/src/net/strategies/DonateStrategy.h index c9fc312d..5350aefa 100644 --- a/src/net/strategies/DonateStrategy.h +++ b/src/net/strategies/DonateStrategy.h @@ -70,6 +70,7 @@ protected: void onClose(IClient *client, int failures) override; void onLogin(IClient *client, rapidjson::Document &doc, rapidjson::Value ¶ms) override; + void onLogin(IStrategy *strategy, IClient *client, rapidjson::Document &doc, rapidjson::Value ¶ms) override; void onLoginSuccess(IClient *client) override; void onTimer(const Timer *timer) override; @@ -87,16 +88,18 @@ private: Client *createProxy(); void idle(double min, double max); + void setAlgorithms(rapidjson::Document &doc, rapidjson::Value ¶ms); void setJob(IClient *client, const Job &job); void setResult(IClient *client, const SubmitResult &result, const char *error); void setState(State state); + Algorithm m_algorithm; bool m_tls; char m_userId[65]; - IClient *m_proxy; const uint64_t m_donateTime; const uint64_t m_idleTime; Controller *m_controller; + IClient *m_proxy; IStrategy *m_strategy; IStrategyListener *m_listener; State m_state; From 88edde804fd750848f138a1d864fe1f090786332 Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 18 Jul 2019 23:48:16 +0700 Subject: [PATCH 38/48] Fixed duplicated shares after donation round. --- src/core/Miner.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/core/Miner.cpp b/src/core/Miner.cpp index 891a0f34..1f7f77e9 100644 --- a/src/core/Miner.cpp +++ b/src/core/Miner.cpp @@ -88,7 +88,7 @@ public: } - inline void handleJobChange() + inline void handleJobChange(bool reset) { active = true; @@ -96,12 +96,17 @@ public: backend->setJob(job); } + if (reset) { + Nonce::reset(job.index()); + } + else { + Nonce::touch(); + } + if (enabled) { Nonce::pause(false);; } - Nonce::reset(job.index()); - if (ticks == 0) { ticks++; timer->start(500, 500); @@ -116,6 +121,7 @@ public: double maxHashrate = 0.0; Job job; std::vector backends; + String userJobId; Timer *timer = nullptr; uint64_t ticks = 0; uv_rwlock_t rwlock; @@ -236,13 +242,18 @@ void xmrig::Miner::setJob(const Job &job, bool donate) uv_rwlock_wrlock(&d_ptr->rwlock); const uint8_t index = donate ? 1 : 0; + const bool reset = !(d_ptr->job.index() == 1 && index == 0 && d_ptr->userJobId == job.id()); d_ptr->job = job; d_ptr->job.setIndex(index); + if (index == 0) { + d_ptr->userJobId = job.id(); + } + uv_rwlock_wrunlock(&d_ptr->rwlock); - d_ptr->handleJobChange(); + d_ptr->handleJobChange(reset); } From 691b2fabbf2817f2a1e8c5b69ce22fe9bd13042d Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 19 Jul 2019 00:39:27 +0700 Subject: [PATCH 39/48] Restored algorithm verification. --- src/base/kernel/interfaces/IClientListener.h | 2 + .../kernel/interfaces/IStrategyListener.h | 2 + src/base/net/stratum/Client.cpp | 39 ++++++++----------- src/base/net/stratum/Client.h | 2 +- .../stratum/strategies/FailoverStrategy.cpp | 6 +++ .../net/stratum/strategies/FailoverStrategy.h | 1 + .../stratum/strategies/SinglePoolStrategy.cpp | 6 +++ .../stratum/strategies/SinglePoolStrategy.h | 1 + src/core/Miner.cpp | 6 +++ src/core/Miner.h | 1 + src/net/Network.cpp | 10 +++++ src/net/Network.h | 1 + src/net/strategies/DonateStrategy.h | 2 + 13 files changed, 56 insertions(+), 23 deletions(-) diff --git a/src/base/kernel/interfaces/IClientListener.h b/src/base/kernel/interfaces/IClientListener.h index de4dd81d..3583be5a 100644 --- a/src/base/kernel/interfaces/IClientListener.h +++ b/src/base/kernel/interfaces/IClientListener.h @@ -35,6 +35,7 @@ namespace xmrig { +class Algorithm; class IClient; class Job; class SubmitResult; @@ -50,6 +51,7 @@ public: virtual void onLogin(IClient *client, rapidjson::Document &doc, rapidjson::Value ¶ms) = 0; virtual void onLoginSuccess(IClient *client) = 0; virtual void onResultAccepted(IClient *client, const SubmitResult &result, const char *error) = 0; + virtual void onVerifyAlgorithm(const IClient *client, const Algorithm &algorithm, bool *ok) = 0; }; diff --git a/src/base/kernel/interfaces/IStrategyListener.h b/src/base/kernel/interfaces/IStrategyListener.h index 01e668d4..8b88b506 100644 --- a/src/base/kernel/interfaces/IStrategyListener.h +++ b/src/base/kernel/interfaces/IStrategyListener.h @@ -32,6 +32,7 @@ namespace xmrig { +class Algorithm; class IClient; class IStrategy; class Job; @@ -48,6 +49,7 @@ public: virtual void onLogin(IStrategy *strategy, IClient *client, rapidjson::Document &doc, rapidjson::Value ¶ms) = 0; virtual void onPause(IStrategy *strategy) = 0; virtual void onResultAccepted(IStrategy *strategy, IClient *client, const SubmitResult &result, const char *error) = 0; + virtual void onVerifyAlgorithm(IStrategy *strategy, const IClient *client, const Algorithm &algorithm, bool *ok) = 0; }; diff --git a/src/base/net/stratum/Client.cpp b/src/base/net/stratum/Client.cpp index 0be86eca..618e132c 100644 --- a/src/base/net/stratum/Client.cpp +++ b/src/base/net/stratum/Client.cpp @@ -330,14 +330,15 @@ bool xmrig::Client::parseJob(const rapidjson::Value ¶ms, int *code) return false; } - if (params.HasMember("algo")) { - job.setAlgorithm(params["algo"].GetString()); + const char *algo = Json::getString(params, "algo"); + if (algo) { + job.setAlgorithm(algo); } job.setSeedHash(Json::getString(params, "seed_hash")); job.setHeight(Json::getUint64(params, "height")); - if (!verifyAlgorithm(job.algorithm())) { + if (!verifyAlgorithm(job.algorithm(), algo)) { *code = 6; close(); @@ -415,30 +416,24 @@ bool xmrig::Client::send(BIO *bio) } -bool xmrig::Client::verifyAlgorithm(const Algorithm &algorithm) const +bool xmrig::Client::verifyAlgorithm(const Algorithm &algorithm, const char *algo) const { -//# ifdef XMRIG_PROXY_PROJECT -// if (m_pool.algorithm().variant() == VARIANT_AUTO || m_id == -1) { -// return true; -// } -//# endif + if (!algorithm.isValid()) { + if (!isQuiet()) { + LOG_ERR("[%s] Unknown/unsupported algorithm \"%s\" detected, reconnect", url(), algo); + } -// if (m_pool.algorithm() == algorithm) { // FIXME -// return true; -// } + return false; + } -// if (isQuiet()) { -// return false; -// } + bool ok = true; + m_listener->onVerifyAlgorithm(this, algorithm, &ok); -// if (algorithm.isValid()) { -// LOG_ERR("Incompatible algorithm \"%s\" detected, reconnect", algorithm.name()); -// } -// else { -// LOG_ERR("Unknown/unsupported algorithm detected, reconnect"); -// } + if (!ok && !isQuiet()) { + LOG_ERR("[%s] Incompatible/disabled algorithm \"%s\" detected, reconnect", url(), algorithm.shortName()); + } - return true; + return ok; } diff --git a/src/base/net/stratum/Client.h b/src/base/net/stratum/Client.h index 841e0e0b..46030aba 100644 --- a/src/base/net/stratum/Client.h +++ b/src/base/net/stratum/Client.h @@ -92,7 +92,7 @@ private: bool parseJob(const rapidjson::Value ¶ms, int *code); bool parseLogin(const rapidjson::Value &result, int *code); bool send(BIO *bio); - bool verifyAlgorithm(const Algorithm &algorithm) const; + bool verifyAlgorithm(const Algorithm &algorithm, const char *algo) const; int resolve(const String &host); int64_t send(const rapidjson::Document &doc); int64_t send(size_t size); diff --git a/src/base/net/stratum/strategies/FailoverStrategy.cpp b/src/base/net/stratum/strategies/FailoverStrategy.cpp index 4a35f3a5..48be2ba3 100644 --- a/src/base/net/stratum/strategies/FailoverStrategy.cpp +++ b/src/base/net/stratum/strategies/FailoverStrategy.cpp @@ -202,3 +202,9 @@ void xmrig::FailoverStrategy::onResultAccepted(IClient *client, const SubmitResu { m_listener->onResultAccepted(this, client, result, error); } + + +void xmrig::FailoverStrategy::onVerifyAlgorithm(const IClient *client, const Algorithm &algorithm, bool *ok) +{ + m_listener->onVerifyAlgorithm(this, client, algorithm, ok); +} diff --git a/src/base/net/stratum/strategies/FailoverStrategy.h b/src/base/net/stratum/strategies/FailoverStrategy.h index 5336a634..283d4916 100644 --- a/src/base/net/stratum/strategies/FailoverStrategy.h +++ b/src/base/net/stratum/strategies/FailoverStrategy.h @@ -66,6 +66,7 @@ protected: void onLogin(IClient *client, rapidjson::Document &doc, rapidjson::Value ¶ms) override; void onLoginSuccess(IClient *client) override; void onResultAccepted(IClient *client, const SubmitResult &result, const char *error) override; + void onVerifyAlgorithm(const IClient *client, const Algorithm &algorithm, bool *ok) override; private: inline IClient *active() const { return m_pools[static_cast(m_active)]; } diff --git a/src/base/net/stratum/strategies/SinglePoolStrategy.cpp b/src/base/net/stratum/strategies/SinglePoolStrategy.cpp index 5f09d174..c923e1c2 100644 --- a/src/base/net/stratum/strategies/SinglePoolStrategy.cpp +++ b/src/base/net/stratum/strategies/SinglePoolStrategy.cpp @@ -136,3 +136,9 @@ void xmrig::SinglePoolStrategy::onResultAccepted(IClient *client, const SubmitRe { m_listener->onResultAccepted(this, client, result, error); } + + +void xmrig::SinglePoolStrategy::onVerifyAlgorithm(const IClient *client, const Algorithm &algorithm, bool *ok) +{ + m_listener->onVerifyAlgorithm(this, client, algorithm, ok); +} diff --git a/src/base/net/stratum/strategies/SinglePoolStrategy.h b/src/base/net/stratum/strategies/SinglePoolStrategy.h index 04eef40e..ea808193 100644 --- a/src/base/net/stratum/strategies/SinglePoolStrategy.h +++ b/src/base/net/stratum/strategies/SinglePoolStrategy.h @@ -60,6 +60,7 @@ protected: void onLogin(IClient *client, rapidjson::Document &doc, rapidjson::Value ¶ms) override; void onLoginSuccess(IClient *client) override; void onResultAccepted(IClient *client, const SubmitResult &result, const char *error) override; + void onVerifyAlgorithm(const IClient *client, const Algorithm &algorithm, bool *ok) override; private: bool m_active; diff --git a/src/core/Miner.cpp b/src/core/Miner.cpp index 1f7f77e9..b64d6b95 100644 --- a/src/core/Miner.cpp +++ b/src/core/Miner.cpp @@ -157,6 +157,12 @@ bool xmrig::Miner::isEnabled() const } +bool xmrig::Miner::isEnabled(const Algorithm &algorithm) const +{ + return std::find(d_ptr->algorithms.begin(), d_ptr->algorithms.end(), algorithm) != d_ptr->algorithms.end(); +} + + const xmrig::Algorithms &xmrig::Miner::algorithms() const { return d_ptr->algorithms; diff --git a/src/core/Miner.h b/src/core/Miner.h index dd195e29..333f9250 100644 --- a/src/core/Miner.h +++ b/src/core/Miner.h @@ -50,6 +50,7 @@ public: ~Miner() override; bool isEnabled() const; + bool isEnabled(const Algorithm &algorithm) const; const Algorithms &algorithms() const; const std::vector &backends() const; Job job() const; diff --git a/src/net/Network.cpp b/src/net/Network.cpp index a1c1ec8d..eaff6748 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -213,6 +213,16 @@ void xmrig::Network::onResultAccepted(IStrategy *, IClient *, const SubmitResult } +void xmrig::Network::onVerifyAlgorithm(IStrategy *, const IClient *, const Algorithm &algorithm, bool *ok) +{ + if (!m_controller->miner()->isEnabled(algorithm)) { + *ok = false; + + return; + } +} + + void xmrig::Network::setJob(IClient *client, const Job &job, bool donate) { if (job.height()) { diff --git a/src/net/Network.h b/src/net/Network.h index bf61a9b6..68967713 100644 --- a/src/net/Network.h +++ b/src/net/Network.h @@ -67,6 +67,7 @@ protected: void onPause(IStrategy *strategy) override; void onRequest(IApiRequest &request) override; void onResultAccepted(IStrategy *strategy, IClient *client, const SubmitResult &result, const char *error) override; + void onVerifyAlgorithm(IStrategy *strategy, const IClient *client, const Algorithm &algorithm, bool *ok) override; private: constexpr static int kTickInterval = 1 * 1000; diff --git a/src/net/strategies/DonateStrategy.h b/src/net/strategies/DonateStrategy.h index 5350aefa..134127bf 100644 --- a/src/net/strategies/DonateStrategy.h +++ b/src/net/strategies/DonateStrategy.h @@ -57,6 +57,8 @@ protected: inline void onJobReceived(IClient *client, const Job &job, const rapidjson::Value &) override { setJob(client, job); } inline void onResultAccepted(IClient *client, const SubmitResult &result, const char *error) override { setResult(client, result, error); } inline void onResultAccepted(IStrategy *, IClient *client, const SubmitResult &result, const char *error) override { setResult(client, result, error); } + inline void onVerifyAlgorithm(const IClient *, const Algorithm &, bool *) override {} + inline void onVerifyAlgorithm(IStrategy *, const IClient *, const Algorithm &, bool *) override {} inline void resume() override {} int64_t submit(const JobResult &result) override; From d9164c0b7bc30dd8d6bf3dbfdd442f9fde87c13d Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 19 Jul 2019 02:24:37 +0700 Subject: [PATCH 40/48] Restored "GET /1/summary" endpoint. --- src/api/Api.cpp | 10 +-- src/api/interfaces/IApiListener.h | 2 + src/api/interfaces/IApiRequest.h | 12 ++- src/api/requests/ApiRequest.cpp | 3 +- src/api/requests/ApiRequest.h | 7 +- src/api/requests/HttpApiRequest.cpp | 11 +++ src/api/v1/ApiRouter.cpp | 70 +----------------- src/api/v1/ApiRouter.h | 4 +- src/backend/common/Hashrate.cpp | 15 +++- src/backend/common/Hashrate.h | 4 + src/core/Miner.cpp | 111 ++++++++++++++++++++++++++++ src/core/Miner.h | 7 +- src/net/Network.cpp | 42 ++++++----- src/net/Network.h | 9 ++- 14 files changed, 199 insertions(+), 108 deletions(-) diff --git a/src/api/Api.cpp b/src/api/Api.cpp index a1aeb4c2..11fc2a69 100644 --- a/src/api/Api.cpp +++ b/src/api/Api.cpp @@ -120,7 +120,7 @@ void xmrig::Api::exec(IApiRequest &request) { using namespace rapidjson; - if (request.method() == IApiRequest::METHOD_GET && (request.url() == "/1/summary" || request.url() == "/api.json")) { + if (request.type() == IApiRequest::REQ_SUMMARY) { auto &allocator = request.doc().GetAllocator(); request.accept(); @@ -145,14 +145,6 @@ void xmrig::Api::exec(IApiRequest &request) features.PushBack("tls", allocator); # endif request.reply().AddMember("features", features, allocator); - - Value algorithms(kArrayType); - - for (int i = 0; i < Algorithm::MAX; ++i) { - algorithms.PushBack(StringRef(Algorithm(static_cast(i)).shortName()), allocator); - } - - request.reply().AddMember("algorithms", algorithms, allocator); } for (IApiListener *listener : m_listeners) { diff --git a/src/api/interfaces/IApiListener.h b/src/api/interfaces/IApiListener.h index 7897e375..bbf153a6 100644 --- a/src/api/interfaces/IApiListener.h +++ b/src/api/interfaces/IApiListener.h @@ -35,7 +35,9 @@ class IApiListener public: virtual ~IApiListener() = default; +# ifdef XMRIG_FEATURE_API virtual void onRequest(IApiRequest &request) = 0; +# endif }; diff --git a/src/api/interfaces/IApiRequest.h b/src/api/interfaces/IApiRequest.h index 2c2f5634..8e65a921 100644 --- a/src/api/interfaces/IApiRequest.h +++ b/src/api/interfaces/IApiRequest.h @@ -4,7 +4,9 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016-2018 XMRig + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -50,6 +52,12 @@ public: }; + enum RequestType { + REQ_UNKNOWN, + REQ_SUMMARY + }; + + virtual ~IApiRequest() = default; virtual bool isDone() const = 0; @@ -57,9 +65,11 @@ public: virtual bool isRestricted() const = 0; virtual const rapidjson::Value &json() const = 0; virtual const String &url() const = 0; + virtual int version() const = 0; virtual Method method() const = 0; virtual rapidjson::Document &doc() = 0; virtual rapidjson::Value &reply() = 0; + virtual RequestType type() const = 0; virtual Source source() const = 0; virtual void accept() = 0; virtual void done(int status) = 0; diff --git a/src/api/requests/ApiRequest.cpp b/src/api/requests/ApiRequest.cpp index c092a334..3812e419 100644 --- a/src/api/requests/ApiRequest.cpp +++ b/src/api/requests/ApiRequest.cpp @@ -28,8 +28,7 @@ xmrig::ApiRequest::ApiRequest(Source source, bool restricted) : m_restricted(restricted), - m_source(source), - m_state(STATE_NEW) + m_source(source) { } diff --git a/src/api/requests/ApiRequest.h b/src/api/requests/ApiRequest.h index 1754aa9c..05716e29 100644 --- a/src/api/requests/ApiRequest.h +++ b/src/api/requests/ApiRequest.h @@ -43,10 +43,15 @@ protected: inline bool isDone() const override { return m_state == STATE_DONE; } inline bool isNew() const override { return m_state == STATE_NEW; } inline bool isRestricted() const override { return m_restricted; } + inline int version() const override { return m_version; } + inline RequestType type() const override { return m_type; } inline Source source() const override { return m_source; } inline void accept() override { m_state = STATE_ACCEPTED; } inline void done(int) override { m_state = STATE_DONE; } + int m_version = 1; + RequestType m_type = REQ_UNKNOWN; + private: enum State { STATE_NEW, @@ -56,7 +61,7 @@ private: bool m_restricted; Source m_source; - State m_state; + State m_state = STATE_NEW; }; diff --git a/src/api/requests/HttpApiRequest.cpp b/src/api/requests/HttpApiRequest.cpp index e4f2de1e..b4dc1810 100644 --- a/src/api/requests/HttpApiRequest.cpp +++ b/src/api/requests/HttpApiRequest.cpp @@ -35,6 +35,17 @@ xmrig::HttpApiRequest::HttpApiRequest(const HttpData &req, bool restricted) : m_res(req.id()), m_url(req.url.c_str()) { + if (method() == METHOD_GET) { + if (url() == "/1/summary" || url() == "/2/summary" || url() == "/api.json") { + m_type = REQ_SUMMARY; + } + } + + if (url().size() > 4) { + if (memcmp(url().data(), "/2/", 3) == 0) { + m_version = 2; + } + } } diff --git a/src/api/v1/ApiRouter.cpp b/src/api/v1/ApiRouter.cpp index 2a5bd3d0..0e1080a1 100644 --- a/src/api/v1/ApiRouter.cpp +++ b/src/api/v1/ApiRouter.cpp @@ -38,18 +38,6 @@ #include "version.h" -static inline rapidjson::Value normalize(double d) -{ - using namespace rapidjson; - - if (!std::isnormal(d)) { - return Value(kNullType); - } - - return Value(floor(d * 100.0) / 100.0); -} - - xmrig::ApiRouter::ApiRouter(Base *base) : m_base(base) { @@ -64,12 +52,7 @@ xmrig::ApiRouter::~ApiRouter() void xmrig::ApiRouter::onRequest(IApiRequest &request) { if (request.method() == IApiRequest::METHOD_GET) { - if (request.url() == "/1/summary" || request.url() == "/api.json") { - request.accept(); - getMiner(request.reply(), request.doc()); -// getHashrate(request.reply(), request.doc()); - } - else if (request.url() == "/1/threads") { + if (request.url() == "/1/threads") { request.accept(); getThreads(request.reply(), request.doc()); } @@ -96,57 +79,6 @@ void xmrig::ApiRouter::onRequest(IApiRequest &request) } -//void xmrig::ApiRouter::getHashrate(rapidjson::Value &reply, rapidjson::Document &doc) const -//{ -// using namespace rapidjson; -// auto &allocator = doc.GetAllocator(); - -// Value hashrate(kObjectType); -// Value total(kArrayType); -// Value threads(kArrayType); - -// const Hashrate *hr = WorkersLegacy::hashrate(); - -// total.PushBack(normalize(hr->calc(Hashrate::ShortInterval)), allocator); -// total.PushBack(normalize(hr->calc(Hashrate::MediumInterval)), allocator); -// total.PushBack(normalize(hr->calc(Hashrate::LargeInterval)), allocator); - -// for (size_t i = 0; i < WorkersLegacy::threads(); i++) { -// Value thread(kArrayType); -// thread.PushBack(normalize(hr->calc(i, Hashrate::ShortInterval)), allocator); -// thread.PushBack(normalize(hr->calc(i, Hashrate::MediumInterval)), allocator); -// thread.PushBack(normalize(hr->calc(i, Hashrate::LargeInterval)), allocator); - -// threads.PushBack(thread, allocator); -// } - -// hashrate.AddMember("total", total, allocator); -// hashrate.AddMember("highest", normalize(hr->highest()), allocator); -// hashrate.AddMember("threads", threads, allocator); -// reply.AddMember("hashrate", hashrate, allocator); -//} - - -void xmrig::ApiRouter::getMiner(rapidjson::Value &reply, rapidjson::Document &doc) const -{ - using namespace rapidjson; - auto &allocator = doc.GetAllocator(); - - Value cpu(kObjectType); - cpu.AddMember("brand", StringRef(Cpu::info()->brand()), allocator); - cpu.AddMember("aes", Cpu::info()->hasAES(), allocator); - cpu.AddMember("x64", Cpu::info()->isX64(), allocator); - cpu.AddMember("sockets", Cpu::info()->sockets(), allocator); - - reply.AddMember("version", APP_VERSION, allocator); - reply.AddMember("kind", APP_KIND, allocator); - reply.AddMember("ua", StringRef(Platform::userAgent()), allocator); - reply.AddMember("cpu", cpu, allocator); - reply.AddMember("hugepages", false, allocator); // FIXME hugepages - reply.AddMember("donate_level", m_base->config()->pools().donateLevel(), allocator); -} - - void xmrig::ApiRouter::getThreads(rapidjson::Value &reply, rapidjson::Document &doc) const { // using namespace rapidjson; diff --git a/src/api/v1/ApiRouter.h b/src/api/v1/ApiRouter.h index e2b9bd25..ec468d86 100644 --- a/src/api/v1/ApiRouter.h +++ b/src/api/v1/ApiRouter.h @@ -39,7 +39,7 @@ namespace xmrig { class Base; -class ApiRouter : public xmrig::IApiListener +class ApiRouter : public IApiListener { public: ApiRouter(Base *base); @@ -49,8 +49,6 @@ protected: void onRequest(IApiRequest &request) override; private: -// void getHashrate(rapidjson::Value &reply, rapidjson::Document &doc) const; - void getMiner(rapidjson::Value &reply, rapidjson::Document &doc) const; void getThreads(rapidjson::Value &reply, rapidjson::Document &doc) const; Base *m_base; diff --git a/src/backend/common/Hashrate.cpp b/src/backend/common/Hashrate.cpp index 6ffd45b7..a9c63733 100644 --- a/src/backend/common/Hashrate.cpp +++ b/src/backend/common/Hashrate.cpp @@ -29,9 +29,10 @@ #include +#include "backend/common/Hashrate.h" #include "base/tools/Chrono.h" #include "base/tools/Handle.h" -#include "backend/common/Hashrate.h" +#include "rapidjson/document.h" inline static const char *format(double h, char *buf, size_t size) @@ -162,3 +163,15 @@ const char *xmrig::Hashrate::format(double h, char *buf, size_t size) { return ::format(h, buf, size); } + + +rapidjson::Value xmrig::Hashrate::normalize(double d) +{ + using namespace rapidjson; + + if (!std::isnormal(d)) { + return Value(kNullType); + } + + return Value(floor(d * 100.0) / 100.0); +} diff --git a/src/backend/common/Hashrate.h b/src/backend/common/Hashrate.h index 2187c0be..0674c6ab 100644 --- a/src/backend/common/Hashrate.h +++ b/src/backend/common/Hashrate.h @@ -30,6 +30,9 @@ #include +#include "rapidjson/fwd.h" + + namespace xmrig { @@ -53,6 +56,7 @@ public: inline size_t threads() const { return m_threads; } static const char *format(double h, char *buf, size_t size); + static rapidjson::Value normalize(double d); private: constexpr static size_t kBucketSize = 2 << 11; diff --git a/src/core/Miner.cpp b/src/core/Miner.cpp index b64d6b95..7114baf9 100644 --- a/src/core/Miner.cpp +++ b/src/core/Miner.cpp @@ -28,14 +28,24 @@ #include "backend/common/Hashrate.h" +#include "backend/cpu/Cpu.h" #include "backend/cpu/CpuBackend.h" #include "base/io/log/Log.h" +#include "base/kernel/Platform.h" #include "base/net/stratum/Job.h" #include "base/tools/Timer.h" #include "core/config/Config.h" #include "core/Controller.h" #include "core/Miner.h" #include "crypto/common/Nonce.h" +#include "rapidjson/document.h" +#include "version.h" + + +#ifdef XMRIG_FEATURE_API +# include "api/Api.h" +# include "api/interfaces/IApiRequest.h" +#endif namespace xmrig { @@ -114,6 +124,90 @@ public: } +# ifdef XMRIG_FEATURE_API + void getMiner(rapidjson::Value &reply, rapidjson::Document &doc, int version) const + { + using namespace rapidjson; + auto &allocator = doc.GetAllocator(); + + Value cpu(kObjectType); + cpu.AddMember("brand", StringRef(Cpu::info()->brand()), allocator); + cpu.AddMember("aes", Cpu::info()->hasAES(), allocator); + cpu.AddMember("x64", Cpu::info()->isX64(), allocator); + cpu.AddMember("sockets", Cpu::info()->sockets(), allocator); + + reply.AddMember("version", APP_VERSION, allocator); + reply.AddMember("kind", APP_KIND, allocator); + reply.AddMember("ua", StringRef(Platform::userAgent()), allocator); + reply.AddMember("cpu", cpu, allocator); + + if (version == 1) { + reply.AddMember("hugepages", false, allocator); + } + + reply.AddMember("donate_level", controller->config()->pools().donateLevel(), allocator); + + Value algo(kArrayType); + + for (const Algorithm &a : algorithms) { + algo.PushBack(StringRef(a.shortName()), allocator); + } + + reply.AddMember("algorithms", algo, allocator); + } + + + void getHashrate(rapidjson::Value &reply, rapidjson::Document &doc, int version) const + { + using namespace rapidjson; + auto &allocator = doc.GetAllocator(); + + Value hashrate(kObjectType); + Value total(kArrayType); + Value threads(kArrayType); + + double t[3] = { 0.0 }; + + for (IBackend *backend : backends) { + const Hashrate *hr = backend->hashrate(); + if (!hr) { + continue; + } + + t[0] += hr->calc(Hashrate::ShortInterval); + t[1] += hr->calc(Hashrate::MediumInterval); + t[2] += hr->calc(Hashrate::LargeInterval); + + if (version > 1) { + continue; + } + + for (size_t i = 0; i < hr->threads(); i++) { + Value thread(kArrayType); + thread.PushBack(Hashrate::normalize(hr->calc(i, Hashrate::ShortInterval)), allocator); + thread.PushBack(Hashrate::normalize(hr->calc(i, Hashrate::MediumInterval)), allocator); + thread.PushBack(Hashrate::normalize(hr->calc(i, Hashrate::LargeInterval)), allocator); + + threads.PushBack(thread, allocator); + } + } + + total.PushBack(Hashrate::normalize(t[0]), allocator); + total.PushBack(Hashrate::normalize(t[1]), allocator); + total.PushBack(Hashrate::normalize(t[2]), allocator); + + hashrate.AddMember("total", total, allocator); + hashrate.AddMember("highest", Hashrate::normalize(maxHashrate), allocator); + + if (version == 1) { + hashrate.AddMember("threads", threads, allocator); + } + + reply.AddMember("hashrate", hashrate, allocator); + } +# endif + + Algorithms algorithms; bool active = false; bool enabled = true; @@ -137,6 +231,10 @@ xmrig::Miner::Miner(Controller *controller) { controller->addListener(this); +# ifdef XMRIG_FEATURE_API + controller->api()->addListener(this); +# endif + d_ptr->timer = new Timer(this); d_ptr->backends.push_back(new CpuBackend(controller)); @@ -309,3 +407,16 @@ void xmrig::Miner::onTimer(const Timer *) d_ptr->ticks++; } + + +#ifdef XMRIG_FEATURE_API +void xmrig::Miner::onRequest(IApiRequest &request) +{ + if (request.type() == IApiRequest::REQ_SUMMARY) { + request.accept(); + + d_ptr->getMiner(request.reply(), request.doc(), request.version()); + d_ptr->getHashrate(request.reply(), request.doc(), request.version()); + } +} +#endif diff --git a/src/core/Miner.h b/src/core/Miner.h index 333f9250..035c0205 100644 --- a/src/core/Miner.h +++ b/src/core/Miner.h @@ -29,6 +29,7 @@ #include +#include "api/interfaces/IApiListener.h" #include "base/kernel/interfaces/IBaseListener.h" #include "base/kernel/interfaces/ITimerListener.h" #include "crypto/common/Algorithm.h" @@ -43,7 +44,7 @@ class MinerPrivate; class IBackend; -class Miner : public ITimerListener, public IBaseListener +class Miner : public ITimerListener, public IBaseListener, public IApiListener { public: Miner(Controller *controller); @@ -64,6 +65,10 @@ protected: void onConfigChanged(Config *config, Config *previousConfig) override; void onTimer(const Timer *timer) override; +# ifdef XMRIG_FEATURE_API + void onRequest(IApiRequest &request) override; +# endif + private: MinerPrivate *d_ptr; }; diff --git a/src/net/Network.cpp b/src/net/Network.cpp index eaff6748..5ee00388 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -185,19 +185,6 @@ void xmrig::Network::onPause(IStrategy *strategy) } -void xmrig::Network::onRequest(IApiRequest &request) -{ -# ifdef XMRIG_FEATURE_API - if (request.method() == IApiRequest::METHOD_GET && (request.url() == "/1/summary" || request.url() == "/api.json")) { - request.accept(); - - getResults(request.reply(), request.doc()); - getConnection(request.reply(), request.doc()); - } -# endif -} - - void xmrig::Network::onResultAccepted(IStrategy *, IClient *, const SubmitResult &result, const char *error) { m_state.add(result, error); @@ -223,6 +210,19 @@ void xmrig::Network::onVerifyAlgorithm(IStrategy *, const IClient *, const Algor } +#ifdef XMRIG_FEATURE_API +void xmrig::Network::onRequest(IApiRequest &request) +{ + if (request.type() == IApiRequest::REQ_SUMMARY) { + request.accept(); + + getResults(request.reply(), request.doc(), request.version()); + getConnection(request.reply(), request.doc(), request.version()); + } +} +#endif + + void xmrig::Network::setJob(IClient *client, const Job &job, bool donate) { if (job.height()) { @@ -256,7 +256,7 @@ void xmrig::Network::tick() #ifdef XMRIG_FEATURE_API -void xmrig::Network::getConnection(rapidjson::Value &reply, rapidjson::Document &doc) const +void xmrig::Network::getConnection(rapidjson::Value &reply, rapidjson::Document &doc, int version) const { using namespace rapidjson; auto &allocator = doc.GetAllocator(); @@ -271,13 +271,16 @@ void xmrig::Network::getConnection(rapidjson::Value &reply, rapidjson::Document connection.AddMember("failures", m_state.failures, allocator); connection.AddMember("tls", m_state.tls().toJSON(), allocator); connection.AddMember("tls-fingerprint", m_state.fingerprint().toJSON(), allocator); - connection.AddMember("error_log", Value(kArrayType), allocator); + + if (version == 1) { + connection.AddMember("error_log", Value(kArrayType), allocator); + } reply.AddMember("connection", connection, allocator); } -void xmrig::Network::getResults(rapidjson::Value &reply, rapidjson::Document &doc) const +void xmrig::Network::getResults(rapidjson::Value &reply, rapidjson::Document &doc, int version) const { using namespace rapidjson; auto &allocator = doc.GetAllocator(); @@ -295,8 +298,11 @@ void xmrig::Network::getResults(rapidjson::Value &reply, rapidjson::Document &do best.PushBack(m_state.topDiff[i], allocator); } - results.AddMember("best", best, allocator); - results.AddMember("error_log", Value(kArrayType), allocator); + results.AddMember("best", best, allocator); + + if (version == 1) { + results.AddMember("error_log", Value(kArrayType), allocator); + } reply.AddMember("results", results, allocator); } diff --git a/src/net/Network.h b/src/net/Network.h index 68967713..ddf6d6f3 100644 --- a/src/net/Network.h +++ b/src/net/Network.h @@ -65,10 +65,13 @@ protected: void onJobResult(const JobResult &result) override; void onLogin(IStrategy *strategy, IClient *client, rapidjson::Document &doc, rapidjson::Value ¶ms) override; void onPause(IStrategy *strategy) override; - void onRequest(IApiRequest &request) override; void onResultAccepted(IStrategy *strategy, IClient *client, const SubmitResult &result, const char *error) override; void onVerifyAlgorithm(IStrategy *strategy, const IClient *client, const Algorithm &algorithm, bool *ok) override; +# ifdef XMRIG_FEATURE_API + void onRequest(IApiRequest &request) override; +# endif + private: constexpr static int kTickInterval = 1 * 1000; @@ -76,8 +79,8 @@ private: void tick(); # ifdef XMRIG_FEATURE_API - void getConnection(rapidjson::Value &reply, rapidjson::Document &doc) const; - void getResults(rapidjson::Value &reply, rapidjson::Document &doc) const; + void getConnection(rapidjson::Value &reply, rapidjson::Document &doc, int version) const; + void getResults(rapidjson::Value &reply, rapidjson::Document &doc, int version) const; # endif Controller *m_controller; From fa2c9df075c292e23efa35603dc17eae2ca82587 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 19 Jul 2019 02:39:00 +0700 Subject: [PATCH 41/48] Implemented "enabled" field for CPU backend; --- src/backend/common/interfaces/IBackend.h | 1 + src/backend/cpu/CpuBackend.cpp | 12 ++++++++++++ src/backend/cpu/CpuBackend.h | 1 + 3 files changed, 14 insertions(+) diff --git a/src/backend/common/interfaces/IBackend.h b/src/backend/common/interfaces/IBackend.h index 6fe917cb..ac97759b 100644 --- a/src/backend/common/interfaces/IBackend.h +++ b/src/backend/common/interfaces/IBackend.h @@ -44,6 +44,7 @@ class IBackend public: virtual ~IBackend() = default; + virtual bool isEnabled() const = 0; virtual bool isEnabled(const Algorithm &algorithm) const = 0; virtual const Hashrate *hashrate() const = 0; virtual const String &profileName() const = 0; diff --git a/src/backend/cpu/CpuBackend.cpp b/src/backend/cpu/CpuBackend.cpp index 15a0c359..8ab312f7 100644 --- a/src/backend/cpu/CpuBackend.cpp +++ b/src/backend/cpu/CpuBackend.cpp @@ -133,6 +133,12 @@ xmrig::CpuBackend::~CpuBackend() } +bool xmrig::CpuBackend::isEnabled() const +{ + return d_ptr->controller->config()->cpu().isEnabled(); +} + + bool xmrig::CpuBackend::isEnabled(const Algorithm &algorithm) const { return !d_ptr->controller->config()->cpu().threads().get(algorithm).empty(); @@ -178,6 +184,12 @@ void xmrig::CpuBackend::printHashrate(bool details) void xmrig::CpuBackend::setJob(const Job &job) { + if (!isEnabled()) { + d_ptr->workers.stop(); + d_ptr->threads.clear(); + return; + } + const CpuConfig &cpu = d_ptr->controller->config()->cpu(); std::vector threads = cpu.get(d_ptr->controller->miner(), job.algorithm()); diff --git a/src/backend/cpu/CpuBackend.h b/src/backend/cpu/CpuBackend.h index 543d4459..af59c345 100644 --- a/src/backend/cpu/CpuBackend.h +++ b/src/backend/cpu/CpuBackend.h @@ -44,6 +44,7 @@ public: ~CpuBackend() override; protected: + bool isEnabled() const override; bool isEnabled(const Algorithm &algorithm) const override; const Hashrate *hashrate() const override; const String &profileName() const override; From 1d78e7d60dab7fb03300715e07ef08c8c96575fe Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 19 Jul 2019 04:22:21 +0700 Subject: [PATCH 42/48] "GET /1/threads" replaced to "GET /2/backends". --- src/api/v1/ApiRouter.cpp | 36 +------- src/api/v1/ApiRouter.h | 2 - src/backend/common/interfaces/IBackend.h | 26 ++++-- src/backend/cpu/Cpu.h | 2 + src/backend/cpu/CpuBackend.cpp | 104 +++++++++++++++++++++-- src/backend/cpu/CpuBackend.h | 5 ++ src/core/Miner.cpp | 28 +++++- src/crypto/cn/CnHash.cpp | 2 +- src/crypto/rx/Rx.cpp | 11 +++ src/crypto/rx/Rx.h | 1 + 10 files changed, 159 insertions(+), 58 deletions(-) diff --git a/src/api/v1/ApiRouter.cpp b/src/api/v1/ApiRouter.cpp index 0e1080a1..21e69f2d 100644 --- a/src/api/v1/ApiRouter.cpp +++ b/src/api/v1/ApiRouter.cpp @@ -52,11 +52,7 @@ xmrig::ApiRouter::~ApiRouter() void xmrig::ApiRouter::onRequest(IApiRequest &request) { if (request.method() == IApiRequest::METHOD_GET) { - if (request.url() == "/1/threads") { - request.accept(); - getThreads(request.reply(), request.doc()); - } - else if (request.url() == "/1/config") { + if (request.url() == "/1/config") { if (request.isRestricted()) { return request.done(403); } @@ -77,33 +73,3 @@ void xmrig::ApiRouter::onRequest(IApiRequest &request) } } } - - -void xmrig::ApiRouter::getThreads(rapidjson::Value &reply, rapidjson::Document &doc) const -{ -// using namespace rapidjson; -// auto &allocator = doc.GetAllocator(); -// const Hashrate *hr = WorkersLegacy::hashrate(); - -// WorkersLegacy::threadsSummary(doc); - -// const std::vector &threads = m_base->config()->threads(); -// Value list(kArrayType); - -// size_t i = 0; -// for (const xmrig::IThread *thread : threads) { -// Value value = thread->toAPI(doc); - -// Value hashrate(kArrayType); -// hashrate.PushBack(normalize(hr->calc(i, Hashrate::ShortInterval)), allocator); -// hashrate.PushBack(normalize(hr->calc(i, Hashrate::MediumInterval)), allocator); -// hashrate.PushBack(normalize(hr->calc(i, Hashrate::LargeInterval)), allocator); - -// i++; - -// value.AddMember("hashrate", hashrate, allocator); -// list.PushBack(value, allocator); -// } - -// reply.AddMember("threads", list, allocator); -} diff --git a/src/api/v1/ApiRouter.h b/src/api/v1/ApiRouter.h index ec468d86..008f5bc0 100644 --- a/src/api/v1/ApiRouter.h +++ b/src/api/v1/ApiRouter.h @@ -49,8 +49,6 @@ protected: void onRequest(IApiRequest &request) override; private: - void getThreads(rapidjson::Value &reply, rapidjson::Document &doc) const; - Base *m_base; }; diff --git a/src/backend/common/interfaces/IBackend.h b/src/backend/common/interfaces/IBackend.h index ac97759b..e19e00ba 100644 --- a/src/backend/common/interfaces/IBackend.h +++ b/src/backend/common/interfaces/IBackend.h @@ -29,6 +29,9 @@ #include +#include "rapidjson/fwd.h" + + namespace xmrig { @@ -44,15 +47,20 @@ class IBackend public: virtual ~IBackend() = default; - virtual bool isEnabled() const = 0; - virtual bool isEnabled(const Algorithm &algorithm) const = 0; - virtual const Hashrate *hashrate() const = 0; - virtual const String &profileName() const = 0; - virtual void printHashrate(bool details) = 0; - virtual void setJob(const Job &job) = 0; - virtual void start(IWorker *worker) = 0; - virtual void stop() = 0; - virtual void tick(uint64_t ticks) = 0; + virtual bool isEnabled() const = 0; + virtual bool isEnabled(const Algorithm &algorithm) const = 0; + virtual const Hashrate *hashrate() const = 0; + virtual const String &profileName() const = 0; + virtual const String &type() const = 0; + virtual void printHashrate(bool details) = 0; + virtual void setJob(const Job &job) = 0; + virtual void start(IWorker *worker) = 0; + virtual void stop() = 0; + virtual void tick(uint64_t ticks) = 0; + +# ifdef XMRIG_FEATURE_API + virtual rapidjson::Value toJSON(rapidjson::Document &doc) const = 0; +# endif }; diff --git a/src/backend/cpu/Cpu.h b/src/backend/cpu/Cpu.h index 9c8afced..23cf37e6 100644 --- a/src/backend/cpu/Cpu.h +++ b/src/backend/cpu/Cpu.h @@ -38,6 +38,8 @@ public: static ICpuInfo *info(); static void init(); static void release(); + + inline static Assembly::Id assembly(Assembly::Id hint) { return hint == Assembly::AUTO ? Cpu::info()->assembly() : hint; } }; diff --git a/src/backend/cpu/CpuBackend.cpp b/src/backend/cpu/CpuBackend.cpp index 8ab312f7..165ed42e 100644 --- a/src/backend/cpu/CpuBackend.cpp +++ b/src/backend/cpu/CpuBackend.cpp @@ -29,6 +29,7 @@ #include "backend/common/Hashrate.h" #include "backend/common/interfaces/IWorker.h" #include "backend/common/Workers.h" +#include "backend/cpu/Cpu.h" #include "backend/cpu/CpuBackend.h" #include "base/io/log/Log.h" #include "base/net/stratum/Job.h" @@ -37,6 +38,9 @@ #include "core/config/Config.h" #include "core/Controller.h" #include "crypto/common/VirtualMemory.h" +#include "crypto/rx/Rx.h" +#include "crypto/rx/RxDataset.h" +#include "rapidjson/document.h" namespace xmrig { @@ -45,6 +49,9 @@ namespace xmrig { extern template class Threads; +static const String kType = "cpu"; + + struct LaunchStatus { public: @@ -59,13 +66,13 @@ public: ts = Chrono::steadyMSecs(); } - size_t hugePages; - size_t memory; - size_t pages; - size_t started; - size_t threads; - size_t ways; - uint64_t ts; + size_t hugePages = 0; + size_t memory = 0; + size_t pages = 0; + size_t started = 0; + size_t threads = 0; + size_t ways = 0; + uint64_t ts = 0; }; @@ -157,6 +164,12 @@ const xmrig::String &xmrig::CpuBackend::profileName() const } +const xmrig::String &xmrig::CpuBackend::type() const +{ + return kType; +} + + void xmrig::CpuBackend::printHashrate(bool details) { if (!details || !hashrate()) { @@ -251,3 +264,80 @@ void xmrig::CpuBackend::tick(uint64_t ticks) { d_ptr->workers.tick(ticks); } + + +#ifdef XMRIG_FEATURE_API +rapidjson::Value xmrig::CpuBackend::toJSON(rapidjson::Document &doc) const +{ + using namespace rapidjson; + auto &allocator = doc.GetAllocator(); + const CpuConfig &cpu = d_ptr->controller->config()->cpu(); + + Value out(kObjectType); + out.AddMember("type", type().toJSON(), allocator); + out.AddMember("enabled", isEnabled(), allocator); + out.AddMember("algo", d_ptr->algo.toJSON(), allocator); + out.AddMember("profile", profileName().toJSON(), allocator); + out.AddMember("hw-aes", cpu.isHwAES(), allocator); + out.AddMember("priority", cpu.priority(), allocator); + +# ifdef XMRIG_FEATURE_ASM + const Assembly assembly = Cpu::assembly(cpu.assembly()); + out.AddMember("asm", assembly.toJSON(), allocator); +# else + out.AddMember("asm", false, allocator); +# endif + + uv_mutex_lock(&d_ptr->mutex); + uint64_t pages[2] = { d_ptr->status.hugePages, d_ptr->status.pages }; + const size_t ways = d_ptr->status.ways; + uv_mutex_unlock(&d_ptr->mutex); + +# ifdef XMRIG_ALGO_RANDOMX + if (d_ptr->algo.family() == Algorithm::RANDOM_X) { + RxDataset *dataset = Rx::dataset(); + if (dataset) { + const auto rxPages = dataset->hugePages(); + pages[0] += rxPages.first; + pages[1] += rxPages.second; + } + } +# endif + + rapidjson::Value hugepages(rapidjson::kArrayType); + hugepages.PushBack(pages[0], allocator); + hugepages.PushBack(pages[1], allocator); + + out.AddMember("hugepages", hugepages, allocator); + out.AddMember("memory", d_ptr->algo.isValid() ? (ways * d_ptr->algo.memory()) : 0, allocator); + + if (d_ptr->threads.empty() || !hashrate()) { + return out; + } + + Value threads(kArrayType); + const Hashrate *hr = hashrate(); + + size_t i = 0; + for (const CpuLaunchData &data : d_ptr->threads) { + Value thread(kObjectType); + thread.AddMember("intensity", data.intensity, allocator); + thread.AddMember("affinity", data.affinity, allocator); + thread.AddMember("av", data.av(), allocator); + + Value hashrate(kArrayType); + hashrate.PushBack(Hashrate::normalize(hr->calc(i, Hashrate::ShortInterval)), allocator); + hashrate.PushBack(Hashrate::normalize(hr->calc(i, Hashrate::MediumInterval)), allocator); + hashrate.PushBack(Hashrate::normalize(hr->calc(i, Hashrate::LargeInterval)), allocator); + + i++; + + thread.AddMember("hashrate", hashrate, allocator); + threads.PushBack(thread, allocator); + } + + out.AddMember("threads", threads, allocator); + + return out; +} +#endif diff --git a/src/backend/cpu/CpuBackend.h b/src/backend/cpu/CpuBackend.h index af59c345..613e7cb6 100644 --- a/src/backend/cpu/CpuBackend.h +++ b/src/backend/cpu/CpuBackend.h @@ -48,12 +48,17 @@ protected: bool isEnabled(const Algorithm &algorithm) const override; const Hashrate *hashrate() const override; const String &profileName() const override; + const String &type() const override; void printHashrate(bool details) override; void setJob(const Job &job) override; void start(IWorker *worker) override; void stop() override; void tick(uint64_t ticks) override; +# ifdef XMRIG_FEATURE_API + rapidjson::Value toJSON(rapidjson::Document &doc) const override; +# endif + private: CpuBackendPrivate *d_ptr; }; diff --git a/src/core/Miner.cpp b/src/core/Miner.cpp index 7114baf9..f6acde12 100644 --- a/src/core/Miner.cpp +++ b/src/core/Miner.cpp @@ -205,6 +205,19 @@ public: reply.AddMember("hashrate", hashrate, allocator); } + + + void getBackends(rapidjson::Value &reply, rapidjson::Document &doc) const + { + using namespace rapidjson; + auto &allocator = doc.GetAllocator(); + + reply.SetArray(); + + for (IBackend *backend : backends) { + reply.PushBack(backend->toJSON(doc), allocator); + } + } # endif @@ -412,11 +425,18 @@ void xmrig::Miner::onTimer(const Timer *) #ifdef XMRIG_FEATURE_API void xmrig::Miner::onRequest(IApiRequest &request) { - if (request.type() == IApiRequest::REQ_SUMMARY) { - request.accept(); + if (request.method() == IApiRequest::METHOD_GET) { + if (request.type() == IApiRequest::REQ_SUMMARY) { + request.accept(); - d_ptr->getMiner(request.reply(), request.doc(), request.version()); - d_ptr->getHashrate(request.reply(), request.doc(), request.version()); + d_ptr->getMiner(request.reply(), request.doc(), request.version()); + d_ptr->getHashrate(request.reply(), request.doc(), request.version()); + } + else if (request.url() == "/2/backends") { + request.accept(); + + d_ptr->getBackends(request.reply(), request.doc()); + } } } #endif diff --git a/src/crypto/cn/CnHash.cpp b/src/crypto/cn/CnHash.cpp index 40f4fbba..a2f8880c 100644 --- a/src/crypto/cn/CnHash.cpp +++ b/src/crypto/cn/CnHash.cpp @@ -262,7 +262,7 @@ xmrig::cn_hash_fun xmrig::CnHash::fn(const Algorithm &algorithm, AlgoVariant av, } # ifdef XMRIG_FEATURE_ASM - cn_hash_fun fun = cnHash.m_map[algorithm][av][assembly == Assembly::AUTO ? Cpu::info()->assembly() : assembly]; + cn_hash_fun fun = cnHash.m_map[algorithm][av][Cpu::assembly(assembly)]; if (fun) { return fun; } diff --git a/src/crypto/rx/Rx.cpp b/src/crypto/rx/Rx.cpp index 7f482034..4125d81f 100644 --- a/src/crypto/rx/Rx.cpp +++ b/src/crypto/rx/Rx.cpp @@ -74,6 +74,17 @@ static const char *tag = BLUE_BG(" rx "); } // namespace xmrig + +xmrig::RxDataset *xmrig::Rx::dataset() +{ + d_ptr->lock(); + RxDataset *dataset = d_ptr->dataset; + d_ptr->unlock(); + + return dataset; +} + + xmrig::RxDataset *xmrig::Rx::dataset(const uint8_t *seed, const Algorithm &algorithm, bool hugePages) { d_ptr->lock(); diff --git a/src/crypto/rx/Rx.h b/src/crypto/rx/Rx.h index c9d068c6..63bb2e14 100644 --- a/src/crypto/rx/Rx.h +++ b/src/crypto/rx/Rx.h @@ -42,6 +42,7 @@ class RxDataset; class Rx { public: + static RxDataset *dataset(); static RxDataset *dataset(const uint8_t *seed, const Algorithm &algorithm, bool hugePages = true); static void stop(); }; From ca7fb33848b9299b9b704e544afcf3abb25089d0 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 19 Jul 2019 04:41:48 +0700 Subject: [PATCH 43/48] Removed class ApiRouter. --- CMakeLists.txt | 2 -- src/api/Api.cpp | 6 ---- src/api/Api.h | 2 -- src/api/v1/ApiRouter.cpp | 75 ---------------------------------------- src/api/v1/ApiRouter.h | 59 ------------------------------- src/base/kernel/Base.cpp | 30 ++++++++++++++++ src/base/kernel/Base.h | 9 +++-- 7 files changed, 37 insertions(+), 146 deletions(-) delete mode 100644 src/api/v1/ApiRouter.cpp delete mode 100644 src/api/v1/ApiRouter.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 4d205f55..e0290778 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -235,8 +235,6 @@ if (WITH_HTTP) src/api/requests/ApiRequest.h src/api/requests/HttpApiRequest.cpp src/api/requests/HttpApiRequest.h - src/api/v1/ApiRouter.cpp - src/api/v1/ApiRouter.h ) else() set(HTTP_SOURCES "") diff --git a/src/api/Api.cpp b/src/api/Api.cpp index 11fc2a69..9151aa7e 100644 --- a/src/api/Api.cpp +++ b/src/api/Api.cpp @@ -35,7 +35,6 @@ #include "api/Api.h" #include "api/interfaces/IApiListener.h" #include "api/requests/HttpApiRequest.h" -#include "api/v1/ApiRouter.h" #include "base/kernel/Base.h" #include "base/tools/Buffer.h" #include "base/tools/Chrono.h" @@ -61,16 +60,11 @@ xmrig::Api::Api(Base *base) : base->addListener(this); genId(base->config()->apiId()); - - m_v1 = new ApiRouter(base); - addListener(m_v1); } xmrig::Api::~Api() { - delete m_v1; - # ifdef XMRIG_FEATURE_HTTP delete m_httpd; # endif diff --git a/src/api/Api.h b/src/api/Api.h index eef57c3a..f2ed3926 100644 --- a/src/api/Api.h +++ b/src/api/Api.h @@ -36,7 +36,6 @@ namespace xmrig { -class ApiRouter; class Base; class Httpd; class HttpData; @@ -67,7 +66,6 @@ private: void genId(const String &id); void genWorkerId(const String &id); - ApiRouter *m_v1; Base *m_base; char m_id[32]; char m_workerId[128]; diff --git a/src/api/v1/ApiRouter.cpp b/src/api/v1/ApiRouter.cpp deleted file mode 100644 index 21e69f2d..00000000 --- a/src/api/v1/ApiRouter.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017-2018 XMR-Stak , - * Copyright 2018-2019 SChernykh - * Copyright 2016-2019 XMRig , - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include - - -#include "api/interfaces/IApiRequest.h" -#include "api/v1/ApiRouter.h" -#include "backend/common/interfaces/IThread.h" -#include "backend/cpu/Cpu.h" -#include "base/kernel/Base.h" -#include "base/kernel/Platform.h" -#include "core/config/Config.h" -#include "rapidjson/document.h" -#include "version.h" - - -xmrig::ApiRouter::ApiRouter(Base *base) : - m_base(base) -{ -} - - -xmrig::ApiRouter::~ApiRouter() -{ -} - - -void xmrig::ApiRouter::onRequest(IApiRequest &request) -{ - if (request.method() == IApiRequest::METHOD_GET) { - if (request.url() == "/1/config") { - if (request.isRestricted()) { - return request.done(403); - } - - request.accept(); - m_base->config()->getJSON(request.doc()); - } - } - else if (request.method() == IApiRequest::METHOD_PUT || request.method() == IApiRequest::METHOD_POST) { - if (request.url() == "/1/config") { - request.accept(); - - if (!m_base->reload(request.json())) { - return request.done(400); - } - - request.done(204); - } - } -} diff --git a/src/api/v1/ApiRouter.h b/src/api/v1/ApiRouter.h deleted file mode 100644 index 008f5bc0..00000000 --- a/src/api/v1/ApiRouter.h +++ /dev/null @@ -1,59 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017-2018 XMR-Stak , - * Copyright 2018-2019 SChernykh - * Copyright 2016-2019 XMRig , - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef XMRIG_APIROUTER_H -#define XMRIG_APIROUTER_H - - -#include "api/interfaces/IApiListener.h" -#include "rapidjson/fwd.h" - - -class Hashrate; - - -namespace xmrig { - - -class Base; - - -class ApiRouter : public IApiListener -{ -public: - ApiRouter(Base *base); - ~ApiRouter() override; - -protected: - void onRequest(IApiRequest &request) override; - -private: - Base *m_base; -}; - - -} // namespace xmrig - - -#endif /* XMRIG_APIROUTER_H */ diff --git a/src/base/kernel/Base.cpp b/src/base/kernel/Base.cpp index 46f32684..d290e7f4 100644 --- a/src/base/kernel/Base.cpp +++ b/src/base/kernel/Base.cpp @@ -48,6 +48,7 @@ #ifdef XMRIG_FEATURE_API # include "api/Api.h" +# include "api/interfaces/IApiRequest.h" #endif @@ -167,6 +168,7 @@ int xmrig::Base::init() # ifdef XMRIG_FEATURE_API d_ptr->api = new Api(this); + d_ptr->api->addListener(this); # endif Platform::init(config()->userAgent()); @@ -288,3 +290,31 @@ void xmrig::Base::onFileChanged(const String &fileName) d_ptr->replace(config); } + + +#ifdef XMRIG_FEATURE_API +void xmrig::Base::onRequest(IApiRequest &request) +{ + if (request.method() == IApiRequest::METHOD_GET) { + if (request.url() == "/1/config") { + if (request.isRestricted()) { + return request.done(403); + } + + request.accept(); + config()->getJSON(request.doc()); + } + } + else if (request.method() == IApiRequest::METHOD_PUT || request.method() == IApiRequest::METHOD_POST) { + if (request.url() == "/1/config") { + request.accept(); + + if (!reload(request.json())) { + return request.done(400); + } + + request.done(204); + } + } +} +#endif diff --git a/src/base/kernel/Base.h b/src/base/kernel/Base.h index 592d3a37..6a33a802 100644 --- a/src/base/kernel/Base.h +++ b/src/base/kernel/Base.h @@ -26,6 +26,7 @@ #define XMRIG_BASE_H +#include "api/interfaces/IApiListener.h" #include "base/kernel/interfaces/IConfigListener.h" #include "base/kernel/interfaces/IWatcherListener.h" #include "rapidjson/fwd.h" @@ -35,13 +36,13 @@ namespace xmrig { class Api; -class Config; class BasePrivate; +class Config; class IBaseListener; class Process; -class Base : public IWatcherListener +class Base : public IWatcherListener, public IApiListener { public: Base(Process *process); @@ -60,6 +61,10 @@ public: protected: void onFileChanged(const String &fileName) override; +# ifdef XMRIG_FEATURE_API + void onRequest(IApiRequest &request) override; +# endif + private: BasePrivate *d_ptr; }; From 2fc54d240a31ac46d8bd9d17e00d96b2080f6088 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 19 Jul 2019 05:03:14 +0700 Subject: [PATCH 44/48] Fixed build. --- cmake/flags.cmake | 2 +- src/backend/common/Hashrate.cpp | 8 ++++---- src/backend/cpu/CpuBackend.cpp | 2 +- src/core/Miner.cpp | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cmake/flags.cmake b/cmake/flags.cmake index 3a0add7a..3f2bd0a0 100644 --- a/cmake/flags.cmake +++ b/cmake/flags.cmake @@ -61,7 +61,7 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fmerge-all-constants") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fno-exceptions -fno-rtti -Wno-missing-braces") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fexceptions -fno-rtti -Wno-missing-braces") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -funroll-loops -fmerge-all-constants") if (XMRIG_ARMv8) diff --git a/src/backend/common/Hashrate.cpp b/src/backend/common/Hashrate.cpp index a9c63733..99a9a9c5 100644 --- a/src/backend/common/Hashrate.cpp +++ b/src/backend/common/Hashrate.cpp @@ -24,7 +24,7 @@ #include -#include +#include #include #include @@ -37,7 +37,7 @@ inline static const char *format(double h, char *buf, size_t size) { - if (isnormal(h)) { + if (std::isnormal(h)) { snprintf(buf, size, "%03.1f", h); return buf; } @@ -82,7 +82,7 @@ double xmrig::Hashrate::calc(size_t ms) const for (size_t i = 0; i < m_threads; ++i) { data = calc(i, ms); - if (isnormal(data)) { + if (std::isnormal(data)) { result += data; } } @@ -153,7 +153,7 @@ void xmrig::Hashrate::add(size_t threadId, uint64_t count, uint64_t timestamp) void xmrig::Hashrate::updateHighest() { double highest = calc(ShortInterval); - if (isnormal(highest) && highest > m_highest) { + if (std::isnormal(highest) && highest > m_highest) { m_highest = highest; } } diff --git a/src/backend/cpu/CpuBackend.cpp b/src/backend/cpu/CpuBackend.cpp index 165ed42e..ffc21597 100644 --- a/src/backend/cpu/CpuBackend.cpp +++ b/src/backend/cpu/CpuBackend.cpp @@ -309,7 +309,7 @@ rapidjson::Value xmrig::CpuBackend::toJSON(rapidjson::Document &doc) const hugepages.PushBack(pages[1], allocator); out.AddMember("hugepages", hugepages, allocator); - out.AddMember("memory", d_ptr->algo.isValid() ? (ways * d_ptr->algo.memory()) : 0, allocator); + out.AddMember("memory", static_cast(d_ptr->algo.isValid() ? (ways * d_ptr->algo.memory()) : 0), allocator); if (d_ptr->threads.empty() || !hashrate()) { return out; diff --git a/src/core/Miner.cpp b/src/core/Miner.cpp index f6acde12..df83c5e9 100644 --- a/src/core/Miner.cpp +++ b/src/core/Miner.cpp @@ -134,7 +134,7 @@ public: cpu.AddMember("brand", StringRef(Cpu::info()->brand()), allocator); cpu.AddMember("aes", Cpu::info()->hasAES(), allocator); cpu.AddMember("x64", Cpu::info()->isX64(), allocator); - cpu.AddMember("sockets", Cpu::info()->sockets(), allocator); + cpu.AddMember("sockets", static_cast(Cpu::info()->sockets()), allocator); reply.AddMember("version", APP_VERSION, allocator); reply.AddMember("kind", APP_KIND, allocator); From 222cebba7109bf8a1423d8d70d90bdcd5c3319b3 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 20 Jul 2019 00:37:15 +0700 Subject: [PATCH 45/48] Fixed command line config and removed --max-cpu-usage and --safe. --- src/backend/common/Threads.cpp | 75 +++++--- src/backend/common/Threads.h | 2 +- src/backend/cpu/CpuConfig.cpp | 70 ++++---- src/backend/cpu/CpuConfig.h | 4 +- src/backend/cpu/CpuWorker.cpp | 2 +- src/base/base.cmake | 2 - src/base/kernel/config/BaseConfig.cpp | 15 +- src/base/kernel/config/BaseTransform.cpp | 49 ++---- src/base/kernel/config/BaseTransform.h | 4 + src/base/kernel/interfaces/IConfig.h | 9 - src/base/kernel/interfaces/IConfigTransform.h | 3 +- src/core/config/ConfigTransform.cpp | 166 +++++++++++++++++- src/core/config/ConfigTransform.h | 8 +- src/core/config/Config_platform.h | 35 ---- src/core/config/usage.h | 2 - 15 files changed, 283 insertions(+), 163 deletions(-) diff --git a/src/backend/common/Threads.cpp b/src/backend/common/Threads.cpp index 4cb9d4c6..894c404b 100644 --- a/src/backend/common/Threads.cpp +++ b/src/backend/common/Threads.cpp @@ -28,6 +28,15 @@ #include "rapidjson/document.h" +namespace xmrig { + + +static const char *kAsterisk = "*"; + + +} // namespace xmrig + + template const std::vector &xmrig::Threads::get(const String &profileName) const { @@ -41,34 +50,7 @@ const std::vector &xmrig::Threads::get(const String &profileName) const template -xmrig::String xmrig::Threads::profileName(const Algorithm &algorithm, bool strict) const -{ - if (isDisabled(algorithm)) { - return String(); - } - - const String name = algorithm.shortName(); - if (has(name)) { - return name; - } - - if (m_aliases.count(algorithm) > 0) { - return m_aliases.at(algorithm); - } - - if (!strict && name.contains("/")) { - const String base = name.split('/').at(0); - if (has(base)) { - return base; - } - } - - return String(); -} - - -template -void xmrig::Threads::read(const rapidjson::Value &value) +size_t xmrig::Threads::read(const rapidjson::Value &value) { using namespace rapidjson; @@ -109,6 +91,43 @@ void xmrig::Threads::read(const rapidjson::Value &value) } } } + + return m_profiles.size(); +} + + +template +xmrig::String xmrig::Threads::profileName(const Algorithm &algorithm, bool strict) const +{ + if (isDisabled(algorithm)) { + return String(); + } + + const String name = algorithm.shortName(); + if (has(name)) { + return name; + } + + if (m_aliases.count(algorithm) > 0) { + return m_aliases.at(algorithm); + } + + if (strict) { + return String(); + } + + if (name.contains("/")) { + const String base = name.split('/').at(0); + if (has(base)) { + return base; + } + } + + if (has(kAsterisk)) { + return kAsterisk; + } + + return String(); } diff --git a/src/backend/common/Threads.h b/src/backend/common/Threads.h index 70bc02a4..bc9e36fd 100644 --- a/src/backend/common/Threads.h +++ b/src/backend/common/Threads.h @@ -50,8 +50,8 @@ public: inline void move(const char *profile, std::vector &&threads) { m_profiles.insert({ profile, threads }); } const std::vector &get(const String &profileName) const; + size_t read(const rapidjson::Value &value); String profileName(const Algorithm &algorithm, bool strict = false) const; - void read(const rapidjson::Value &value); void toJSON(rapidjson::Value &out, rapidjson::Document &doc) const; private: diff --git a/src/backend/cpu/CpuConfig.cpp b/src/backend/cpu/CpuConfig.cpp index 457f7ef4..4c86ceea 100644 --- a/src/backend/cpu/CpuConfig.cpp +++ b/src/backend/cpu/CpuConfig.cpp @@ -126,48 +126,56 @@ void xmrig::CpuConfig::read(const rapidjson::Value &value) m_hugePages = Json::getBool(value, kHugePages, m_hugePages); setAesMode(Json::getValue(value, kHwAes)); - setPriority(Json::getInt(value, kPriority, -1)); + setPriority(Json::getInt(value, kPriority, -1)); # ifdef XMRIG_FEATURE_ASM m_assembly = Json::getValue(value, kAsm); # endif - m_threads.read(value); + if (!m_threads.read(value)) { + generate(); + } } else if (value.IsBool() && value.IsFalse()) { m_enabled = false; } else { - m_shouldSave = true; - - m_threads.disable(Algorithm::CN_0); - m_threads.move(kCn, Cpu::info()->threads(Algorithm::CN_0)); - -# ifdef XMRIG_ALGO_CN_GPU - m_threads.move(kCnGPU, Cpu::info()->threads(Algorithm::CN_GPU)); -# endif - -# ifdef XMRIG_ALGO_CN_LITE - m_threads.disable(Algorithm::CN_LITE_0); - m_threads.move(kCnLite, Cpu::info()->threads(Algorithm::CN_LITE_1)); -# endif - -# ifdef XMRIG_ALGO_CN_HEAVY - m_threads.move(kCnHeavy, Cpu::info()->threads(Algorithm::CN_HEAVY_0)); -# endif - -# ifdef XMRIG_ALGO_CN_PICO - m_threads.move(kCnPico, Cpu::info()->threads(Algorithm::CN_PICO_0)); -# endif - -# ifdef XMRIG_ALGO_RANDOMX - m_threads.move(kRx, Cpu::info()->threads(Algorithm::RX_0)); - m_threads.move(kRxWOW, Cpu::info()->threads(Algorithm::RX_WOW)); -# endif + generate(); } } +void xmrig::CpuConfig::generate() +{ + m_shouldSave = true; + + m_threads.disable(Algorithm::CN_0); + m_threads.move(kCn, Cpu::info()->threads(Algorithm::CN_0)); + +# ifdef XMRIG_ALGO_CN_GPU + m_threads.move(kCnGPU, Cpu::info()->threads(Algorithm::CN_GPU)); +# endif + +# ifdef XMRIG_ALGO_CN_LITE + m_threads.disable(Algorithm::CN_LITE_0); + m_threads.move(kCnLite, Cpu::info()->threads(Algorithm::CN_LITE_1)); +# endif + +# ifdef XMRIG_ALGO_CN_HEAVY + m_threads.move(kCnHeavy, Cpu::info()->threads(Algorithm::CN_HEAVY_0)); +# endif + +# ifdef XMRIG_ALGO_CN_PICO + m_threads.move(kCnPico, Cpu::info()->threads(Algorithm::CN_PICO_0)); +# endif + +# ifdef XMRIG_ALGO_RANDOMX + m_threads.move(kRx, Cpu::info()->threads(Algorithm::RX_0)); + m_threads.move(kRxWOW, Cpu::info()->threads(Algorithm::RX_WOW)); +# endif +} + + void xmrig::CpuConfig::setAesMode(const rapidjson::Value &aesMode) { if (aesMode.IsBool()) { @@ -177,9 +185,3 @@ void xmrig::CpuConfig::setAesMode(const rapidjson::Value &aesMode) m_aes = AES_AUTO; } } - - -void xmrig::CpuConfig::setPriority(int priority) -{ - m_priority = (priority >= -1 && priority <= 5) ? priority : -1; -} diff --git a/src/backend/cpu/CpuConfig.h b/src/backend/cpu/CpuConfig.h index 8ff8b77c..5b2f3f86 100644 --- a/src/backend/cpu/CpuConfig.h +++ b/src/backend/cpu/CpuConfig.h @@ -59,8 +59,10 @@ public: inline int priority() const { return m_priority; } private: + void generate(); void setAesMode(const rapidjson::Value &aesMode); - void setPriority(int priority); + + inline void setPriority(int priority) { m_priority = (priority >= -1 && priority <= 5) ? priority : -1; } AesMode m_aes = AES_AUTO; Assembly m_assembly; diff --git a/src/backend/cpu/CpuWorker.cpp b/src/backend/cpu/CpuWorker.cpp index e35c5155..14ffaa73 100644 --- a/src/backend/cpu/CpuWorker.cpp +++ b/src/backend/cpu/CpuWorker.cpp @@ -273,7 +273,7 @@ template void xmrig::CpuWorker::allocateCnCtx() { if (m_ctx[0] == nullptr) { - CnCtx::create(m_ctx, m_memory->scratchpad(), m_memory->size(), N); + CnCtx::create(m_ctx, m_memory->scratchpad(), m_algorithm.memory(), N); } } diff --git a/src/base/base.cmake b/src/base/base.cmake index b25d9743..ef4da131 100644 --- a/src/base/base.cmake +++ b/src/base/base.cmake @@ -146,5 +146,3 @@ else() remove_definitions(/DXMRIG_FEATURE_HTTP) remove_definitions(/DXMRIG_FEATURE_API) endif() - -add_definitions(/DXMRIG_DEPRECATED) diff --git a/src/base/kernel/config/BaseConfig.cpp b/src/base/kernel/config/BaseConfig.cpp index 489849a3..462639e3 100644 --- a/src/base/kernel/config/BaseConfig.cpp +++ b/src/base/kernel/config/BaseConfig.cpp @@ -139,20 +139,7 @@ bool xmrig::BaseConfig::read(const IJsonReader &reader, const char *fileName) m_apiWorkerId = Json::getString(api, "worker-id"); } -# ifdef XMRIG_DEPRECATED - if (api.IsObject() && api.HasMember("port")) { - m_upgrade = true; - m_http.load(api); - m_http.setEnabled(Json::getUint(api, "port") > 0); - m_http.setHost("0.0.0.0"); - } - else { - m_http.load(reader.getObject("http")); - } -# else - m_http.load(chain.getObject("http")); -# endif - + m_http.load(reader.getObject("http")); m_pools.load(reader); return m_pools.active() > 0; diff --git a/src/base/kernel/config/BaseTransform.cpp b/src/base/kernel/config/BaseTransform.cpp index 615342b9..554565a5 100644 --- a/src/base/kernel/config/BaseTransform.cpp +++ b/src/base/kernel/config/BaseTransform.cpp @@ -87,15 +87,31 @@ void xmrig::BaseTransform::load(JsonChain &chain, Process *process, IConfigTrans LOG_WARN("%s: unsupported non-option argument '%s'", argv[0], argv[optind]); } + transform.finalize(doc); chain.add(std::move(doc)); } +void xmrig::BaseTransform::finalize(rapidjson::Document &doc) +{ + using namespace rapidjson; + auto &allocator = doc.GetAllocator(); + + if (m_algorithm.isValid() && doc.HasMember(kPools)) { + auto &pools = doc[kPools]; + for (Value &pool : pools.GetArray()) { + pool.AddMember(StringRef("algo"), m_algorithm.toJSON(), allocator); + } + } +} + + void xmrig::BaseTransform::transform(rapidjson::Document &doc, int key, const char *arg) { switch (key) { case IConfig::AlgorithmKey: /* --algo */ - return set(doc, "algo", arg); + m_algorithm = arg; + break; case IConfig::UserpassKey: /* --userpass */ { @@ -134,13 +150,6 @@ void xmrig::BaseTransform::transform(rapidjson::Document &doc, int key, const ch case IConfig::LogFileKey: /* --log-file */ return set(doc, "log-file", arg); -# ifdef XMRIG_DEPRECATED - case IConfig::ApiAccessTokenKey: /* --api-access-token */ - fputs("option \"--api-access-token\" deprecated, use \"--http-access-token\" instead.\n", stderr); - fflush(stdout); - return set(doc, kHttp, "access-token", arg); -# endif - case IConfig::HttpAccessTokenKey: /* --http-access-token */ return set(doc, kHttp, "access-token", arg); @@ -162,9 +171,6 @@ void xmrig::BaseTransform::transform(rapidjson::Document &doc, int key, const ch case IConfig::HttpPort: /* --http-port */ case IConfig::DonateLevelKey: /* --donate-level */ case IConfig::DaemonPollKey: /* --daemon-poll-interval */ -# ifdef XMRIG_DEPRECATED - case IConfig::ApiPort: /* --api-port */ -# endif return transformUint64(doc, key, static_cast(strtol(arg, nullptr, 10))); case IConfig::BackgroundKey: /* --background */ @@ -179,10 +185,6 @@ void xmrig::BaseTransform::transform(rapidjson::Document &doc, int key, const ch case IConfig::ColorKey: /* --no-color */ case IConfig::HttpRestrictedKey: /* --http-no-restricted */ -# ifdef XMRIG_DEPRECATED - case IConfig::ApiRestrictedKey: /* --api-no-restricted */ - case IConfig::ApiIPv6Key: /* --api-ipv6 */ -# endif return transformBoolean(doc, key, false); default: @@ -217,16 +219,6 @@ void xmrig::BaseTransform::transformBoolean(rapidjson::Document &doc, int key, b case IConfig::ColorKey: /* --no-color */ return set(doc, "colors", enable); -# ifdef XMRIG_DEPRECATED - case IConfig::ApiIPv6Key: /* --api-ipv6 */ - break; - - case IConfig::ApiRestrictedKey: /* --api-no-restricted */ - fputs("option \"--api-no-restricted\" deprecated, use \"--http-no-restricted\" instead.\n", stderr); - fflush(stdout); - return set(doc, kHttp, "restricted", enable); -# endif - case IConfig::HttpRestrictedKey: /* --http-no-restricted */ return set(doc, kHttp, "restricted", enable); @@ -257,13 +249,6 @@ void xmrig::BaseTransform::transformUint64(rapidjson::Document &doc, int key, ui case IConfig::ProxyDonateKey: /* --donate-over-proxy */ return set(doc, "donate-over-proxy", arg); -# ifdef XMRIG_DEPRECATED - case IConfig::ApiPort: /* --api-port */ - fputs("option \"--api-port\" deprecated, use \"--http-port\" instead.\n", stderr); - fflush(stdout); - return set(doc, kHttp, "port", arg); -# endif - case IConfig::HttpPort: /* --http-port */ return set(doc, kHttp, "port", arg); diff --git a/src/base/kernel/config/BaseTransform.h b/src/base/kernel/config/BaseTransform.h index 3952e22b..02b28c12 100644 --- a/src/base/kernel/config/BaseTransform.h +++ b/src/base/kernel/config/BaseTransform.h @@ -49,6 +49,7 @@ public: static void load(JsonChain &chain, Process *process, IConfigTransform &transform); protected: + void finalize(rapidjson::Document &doc) override; void transform(rapidjson::Document &doc, int key, const char *arg) override; @@ -96,6 +97,9 @@ protected: } } +protected: + Algorithm m_algorithm; + private: void transformBoolean(rapidjson::Document &doc, int key, bool enable); diff --git a/src/base/kernel/interfaces/IConfig.h b/src/base/kernel/interfaces/IConfig.h index c8189ba5..ba20a0ca 100644 --- a/src/base/kernel/interfaces/IConfig.h +++ b/src/base/kernel/interfaces/IConfig.h @@ -73,13 +73,6 @@ public: DaemonKey = 1018, DaemonPollKey = 1019, -# ifdef XMRIG_DEPRECATED - ApiPort = 4000, - ApiAccessTokenKey = 4001, - ApiIPv6Key = 4003, - ApiRestrictedKey = 4004, -# endif - // xmrig common CPUPriorityKey = 1021, NicehashKey = 1006, @@ -90,8 +83,6 @@ public: CPUAffinityKey = 1020, DryRunKey = 5000, HugePagesKey = 1009, - MaxCPUUsageKey = 1004, - SafeKey = 1005, ThreadsKey = 't', // HardwareAESKey = 1011, AssemblyKey = 1015, diff --git a/src/base/kernel/interfaces/IConfigTransform.h b/src/base/kernel/interfaces/IConfigTransform.h index f8854388..8afe8221 100644 --- a/src/base/kernel/interfaces/IConfigTransform.h +++ b/src/base/kernel/interfaces/IConfigTransform.h @@ -42,7 +42,8 @@ class IConfigTransform public: virtual ~IConfigTransform() = default; - virtual void transform(rapidjson::Document &doc, int key, const char *arg) = 0; + virtual void finalize(rapidjson::Document &doc) = 0; + virtual void transform(rapidjson::Document &doc, int key, const char *arg) = 0; }; diff --git a/src/core/config/ConfigTransform.cpp b/src/core/config/ConfigTransform.cpp index 7d313726..38bb42a1 100644 --- a/src/core/config/ConfigTransform.cpp +++ b/src/core/config/ConfigTransform.cpp @@ -23,27 +23,189 @@ */ -#include "core/config/ConfigTransform.h" #include "base/kernel/interfaces/IConfig.h" +#include "core/config/ConfigTransform.h" +#include "crypto/cn/CnHash.h" -xmrig::ConfigTransform::ConfigTransform() +namespace xmrig { + +static const char *kAffinity = "affinity"; +static const char *kAsterisk = "*"; +static const char *kCpu = "cpu"; +static const char *kIntensity = "intensity"; + + +static inline uint64_t intensity(uint64_t av) +{ + switch (av) { + case CnHash::AV_SINGLE: + case CnHash::AV_SINGLE_SOFT: + return 1; + + case CnHash::AV_DOUBLE_SOFT: + case CnHash::AV_DOUBLE: + return 2; + + case CnHash::AV_TRIPLE_SOFT: + case CnHash::AV_TRIPLE: + return 3; + + case CnHash::AV_QUAD_SOFT: + case CnHash::AV_QUAD: + return 4; + + case CnHash::AV_PENTA_SOFT: + case CnHash::AV_PENTA: + return 5; + + default: + break; + } + + return 1; +} + + +static inline bool isHwAes(uint64_t av) +{ + return av == CnHash::AV_SINGLE || av == CnHash::AV_DOUBLE || (av > CnHash::AV_DOUBLE_SOFT && av < CnHash::AV_TRIPLE_SOFT); +} + + +static inline int64_t affinity(uint64_t index, int64_t affinity) +{ + if (affinity == -1L) { + return -1L; + } + + size_t idx = 0; + + for (size_t i = 0; i < 64; i++) { + if (!(static_cast(affinity) & (1ULL << i))) { + continue; + } + + if (idx == index) { + return static_cast(i); + } + + idx++; + } + + return -1L; +} + + +} + + +xmrig::ConfigTransform::ConfigTransform() : BaseTransform() +{ +} + + +void xmrig::ConfigTransform::finalize(rapidjson::Document &doc) +{ + using namespace rapidjson; + auto &allocator = doc.GetAllocator(); + + BaseTransform::finalize(doc); + + if (m_threads) { + if (!doc.HasMember(kCpu)) { + doc.AddMember(StringRef(kCpu), Value(kObjectType), allocator); + } + + Value threads(kArrayType); + + if (m_intensity > 1) { + for (uint64_t i = 0; i < m_threads; ++i) { + Value thread(kObjectType); + thread.AddMember(StringRef(kIntensity), m_intensity, allocator); + thread.AddMember(StringRef(kAffinity), affinity(i, m_affinity), allocator); + + threads.PushBack(thread, doc.GetAllocator()); + } + } + else { + for (uint64_t i = 0; i < m_threads; ++i) { + threads.PushBack(affinity(i, m_affinity), doc.GetAllocator()); + } + } + + doc[kCpu].AddMember(StringRef(kAsterisk), threads, doc.GetAllocator()); + } } void xmrig::ConfigTransform::transform(rapidjson::Document &doc, int key, const char *arg) { BaseTransform::transform(doc, key, arg); + + switch (key) { + case IConfig::AVKey: /* --av */ + case IConfig::CPUPriorityKey: /* --cpu-priority */ + case IConfig::ThreadsKey: /* --threads */ + return transformUint64(doc, key, static_cast(strtol(arg, nullptr, 10))); + + case IConfig::HugePagesKey: /* --no-huge-pages */ + return transformBoolean(doc, key, false); + + case IConfig::CPUAffinityKey: /* --cpu-affinity */ + { + const char *p = strstr(arg, "0x"); + return transformUint64(doc, key, p ? strtoull(p, nullptr, 16) : strtoull(arg, nullptr, 10)); + } + +# ifndef XMRIG_NO_ASM + case IConfig::AssemblyKey: /* --asm */ + return set(doc, kCpu, "asm", arg); +# endif + + default: + break; + } } void xmrig::ConfigTransform::transformBoolean(rapidjson::Document &doc, int key, bool enable) { + switch (key) { + case IConfig::HugePagesKey: /* --no-huge-pages */ + return set(doc, kCpu, "huge-pages", enable); + + default: + break; + } } void xmrig::ConfigTransform::transformUint64(rapidjson::Document &doc, int key, uint64_t arg) { + using namespace rapidjson; + + switch (key) { + case IConfig::CPUAffinityKey: /* --cpu-affinity */ + m_affinity = static_cast(arg); + break; + + case IConfig::ThreadsKey: /* --threads */ + m_threads = arg; + break; + + case IConfig::AVKey: /* --av */ + m_intensity = intensity(arg); + set(doc, kCpu, "hw-aes", isHwAes(arg)); + break; + + case IConfig::CPUPriorityKey: /* --cpu-priority */ + return set(doc, kCpu, "priority", arg); + + default: + break; + } } + diff --git a/src/core/config/ConfigTransform.h b/src/core/config/ConfigTransform.h index 2d291d8f..440a7169 100644 --- a/src/core/config/ConfigTransform.h +++ b/src/core/config/ConfigTransform.h @@ -5,7 +5,8 @@ * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee * Copyright 2017-2018 XMR-Stak , - * Copyright 2016-2018 XMRig , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -37,11 +38,16 @@ public: ConfigTransform(); protected: + void finalize(rapidjson::Document &doc) override; void transform(rapidjson::Document &doc, int key, const char *arg) override; private: void transformBoolean(rapidjson::Document &doc, int key, bool enable); void transformUint64(rapidjson::Document &doc, int key, uint64_t arg); + + int64_t m_affinity = -1; + uint64_t m_intensity = 1; + uint64_t m_threads = 0; }; diff --git a/src/core/config/Config_platform.h b/src/core/config/Config_platform.h index ca06a703..85ab0b43 100644 --- a/src/core/config/Config_platform.h +++ b/src/core/config/Config_platform.h @@ -62,7 +62,6 @@ static const option options[] = { { "dry-run", 0, nullptr, IConfig::DryRunKey }, { "keepalive", 0, nullptr, IConfig::KeepAliveKey }, { "log-file", 1, nullptr, IConfig::LogFileKey }, - { "max-cpu-usage", 1, nullptr, IConfig::MaxCPUUsageKey }, { "nicehash", 0, nullptr, IConfig::NicehashKey }, { "no-color", 0, nullptr, IConfig::ColorKey }, { "no-huge-pages", 0, nullptr, IConfig::HugePagesKey }, @@ -71,7 +70,6 @@ static const option options[] = { { "print-time", 1, nullptr, IConfig::PrintTimeKey }, { "retries", 1, nullptr, IConfig::RetriesKey }, { "retry-pause", 1, nullptr, IConfig::RetryPauseKey }, - { "safe", 0, nullptr, IConfig::SafeKey }, { "syslog", 0, nullptr, IConfig::SyslogKey }, { "threads", 1, nullptr, IConfig::ThreadsKey }, { "url", 1, nullptr, IConfig::UrlKey }, @@ -84,43 +82,10 @@ static const option options[] = { { "asm", 1, nullptr, IConfig::AssemblyKey }, { "daemon", 0, nullptr, IConfig::DaemonKey }, { "daemon-poll-interval", 1, nullptr, IConfig::DaemonPollKey }, - -# ifdef XMRIG_DEPRECATED - { "api-port", 1, nullptr, IConfig::ApiPort }, - { "api-access-token", 1, nullptr, IConfig::ApiAccessTokenKey }, - { "api-no-restricted", 0, nullptr, IConfig::ApiRestrictedKey }, - { "api-ipv6", 0, nullptr, IConfig::ApiIPv6Key }, -# endif - { nullptr, 0, nullptr, 0 } }; -static struct option const config_options[] = { - { "algo", 1, nullptr, IConfig::AlgorithmKey }, - { "av", 1, nullptr, IConfig::AVKey }, - { "background", 0, nullptr, IConfig::BackgroundKey }, - { "colors", 0, nullptr, IConfig::ColorKey }, - { "cpu-affinity", 1, nullptr, IConfig::CPUAffinityKey }, - { "cpu-priority", 1, nullptr, IConfig::CPUPriorityKey }, - { "donate-level", 1, nullptr, IConfig::DonateLevelKey }, - { "donate-over-proxy", 1, nullptr, IConfig::ProxyDonateKey }, - { "dry-run", 0, nullptr, IConfig::DryRunKey }, - { "huge-pages", 0, nullptr, IConfig::HugePagesKey }, - { "log-file", 1, nullptr, IConfig::LogFileKey }, - { "max-cpu-usage", 1, nullptr, IConfig::MaxCPUUsageKey }, - { "print-time", 1, nullptr, IConfig::PrintTimeKey }, - { "retries", 1, nullptr, IConfig::RetriesKey }, - { "retry-pause", 1, nullptr, IConfig::RetryPauseKey }, - { "safe", 0, nullptr, IConfig::SafeKey }, - { "syslog", 0, nullptr, IConfig::SyslogKey }, - { "threads", 1, nullptr, IConfig::ThreadsKey }, - { "user-agent", 1, nullptr, IConfig::UserAgentKey }, - { "asm", 1, nullptr, IConfig::AssemblyKey }, - { nullptr, 0, nullptr, 0 } -}; - - } // namespace xmrig diff --git a/src/core/config/usage.h b/src/core/config/usage.h index 42cbc24a..ec3dd589 100644 --- a/src/core/config/usage.h +++ b/src/core/config/usage.h @@ -87,8 +87,6 @@ Options:\n\ -S, --syslog use system log for output messages\n" # endif "\ - --max-cpu-usage=N maximum CPU usage for automatic threads mode (default: 100)\n\ - --safe safe adjust threads and av settings for current CPU\n\ --asm=ASM ASM optimizations, possible values: auto, none, intel, ryzen, bulldozer.\n\ --print-time=N print hashrate report every N seconds\n" #ifdef XMRIG_FEATURE_HTTP From d2ca254789f9ec8eb3023b5bcc6905e11f243376 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 20 Jul 2019 01:20:50 +0700 Subject: [PATCH 46/48] Disable rx/0 algorithm. --- src/backend/common/Threads.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/common/Threads.h b/src/backend/common/Threads.h index bc9e36fd..126245f6 100644 --- a/src/backend/common/Threads.h +++ b/src/backend/common/Threads.h @@ -43,7 +43,7 @@ class Threads { public: inline bool has(const char *profile) const { return m_profiles.count(profile) > 0; } - inline bool isDisabled(const Algorithm &algo) const { return m_disabled.count(algo) > 0; } + inline bool isDisabled(const Algorithm &algo) const { return m_disabled.count(algo) > 0 || algo == Algorithm::RX_0; } inline bool isExist(const Algorithm &algo) const { return isDisabled(algo) || m_aliases.count(algo) > 0 || has(algo.shortName()); } inline const std::vector &get(const Algorithm &algo, bool strict = false) const { return get(profileName(algo, strict)); } inline void disable(const Algorithm &algo) { m_disabled.insert(algo); } From dc2c0552e082fd8787c94a0ca1918591943f1ef7 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 20 Jul 2019 01:43:36 +0700 Subject: [PATCH 47/48] Moved current valid algorithm to first position in algo list. --- src/net/Network.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/net/Network.cpp b/src/net/Network.cpp index 5ee00388..547a8638 100644 --- a/src/net/Network.cpp +++ b/src/net/Network.cpp @@ -27,7 +27,9 @@ #pragma warning(disable:4244) #endif +#include #include +#include #include #include @@ -154,14 +156,23 @@ void xmrig::Network::onJobResult(const JobResult &result) } -void xmrig::Network::onLogin(IStrategy *, IClient *, rapidjson::Document &doc, rapidjson::Value ¶ms) +void xmrig::Network::onLogin(IStrategy *, IClient *client, rapidjson::Document &doc, rapidjson::Value ¶ms) { using namespace rapidjson; auto &allocator = doc.GetAllocator(); + Algorithms algorithms = m_controller->miner()->algorithms(); + const Algorithm algorithm = client->pool().algorithm(); + if (algorithm.isValid()) { + const size_t index = static_cast(std::distance(algorithms.begin(), std::find(algorithms.begin(), algorithms.end(), algorithm))); + if (index > 0 && index < algorithms.size()) { + std::swap(algorithms[0], algorithms[index]); + } + } + Value algo(kArrayType); - for (const auto &a : m_controller->miner()->algorithms()) { + for (const auto &a : algorithms) { algo.PushBack(StringRef(a.shortName()), allocator); } From 3fb180f04e9108925293a6940f0d052ee59176c6 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 20 Jul 2019 05:24:21 +0700 Subject: [PATCH 48/48] Removed --variant option, use --algo instead. --- src/base/kernel/config/BaseTransform.cpp | 15 ++++++++++----- src/base/kernel/interfaces/IConfig.h | 1 - src/core/config/Config_platform.h | 1 - src/core/config/usage.h | 19 ++++++++++++++----- 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/base/kernel/config/BaseTransform.cpp b/src/base/kernel/config/BaseTransform.cpp index 554565a5..8043c6e9 100644 --- a/src/base/kernel/config/BaseTransform.cpp +++ b/src/base/kernel/config/BaseTransform.cpp @@ -44,6 +44,7 @@ namespace xmrig { +static const char *kAlgo = "algo"; static const char *kApi = "api"; static const char *kHttp = "http"; static const char *kPools = "pools"; @@ -100,7 +101,9 @@ void xmrig::BaseTransform::finalize(rapidjson::Document &doc) if (m_algorithm.isValid() && doc.HasMember(kPools)) { auto &pools = doc[kPools]; for (Value &pool : pools.GetArray()) { - pool.AddMember(StringRef("algo"), m_algorithm.toJSON(), allocator); + if (!pool.HasMember(kAlgo)) { + pool.AddMember(StringRef(kAlgo), m_algorithm.toJSON(), allocator); + } } } } @@ -110,7 +113,12 @@ void xmrig::BaseTransform::transform(rapidjson::Document &doc, int key, const ch { switch (key) { case IConfig::AlgorithmKey: /* --algo */ - m_algorithm = arg; + if (!doc.HasMember(kPools)) { + m_algorithm = arg; + } + else { + return add(doc, kPools, kAlgo, arg); + } break; case IConfig::UserpassKey: /* --userpass */ @@ -144,9 +152,6 @@ void xmrig::BaseTransform::transform(rapidjson::Document &doc, int key, const ch case IConfig::FingerprintKey: /* --tls-fingerprint */ return add(doc, kPools, "tls-fingerprint", arg); - case IConfig::VariantKey: /* --variant */ - return add(doc, kPools, "variant", arg); - case IConfig::LogFileKey: /* --log-file */ return set(doc, "log-file", arg); diff --git a/src/base/kernel/interfaces/IConfig.h b/src/base/kernel/interfaces/IConfig.h index ba20a0ca..2697bf01 100644 --- a/src/base/kernel/interfaces/IConfig.h +++ b/src/base/kernel/interfaces/IConfig.h @@ -65,7 +65,6 @@ public: UserAgentKey = 1008, UserKey = 'u', UserpassKey = 'O', - VariantKey = 1010, VerboseKey = 1100, TlsKey = 1013, FingerprintKey = 1014, diff --git a/src/core/config/Config_platform.h b/src/core/config/Config_platform.h index 85ab0b43..fdd15c96 100644 --- a/src/core/config/Config_platform.h +++ b/src/core/config/Config_platform.h @@ -65,7 +65,6 @@ static const option options[] = { { "nicehash", 0, nullptr, IConfig::NicehashKey }, { "no-color", 0, nullptr, IConfig::ColorKey }, { "no-huge-pages", 0, nullptr, IConfig::HugePagesKey }, - { "variant", 1, nullptr, IConfig::VariantKey }, { "pass", 1, nullptr, IConfig::PasswordKey }, { "print-time", 1, nullptr, IConfig::PrintTimeKey }, { "retries", 1, nullptr, IConfig::RetriesKey }, diff --git a/src/core/config/usage.h b/src/core/config/usage.h index ec3dd589..2d0d5623 100644 --- a/src/core/config/usage.h +++ b/src/core/config/usage.h @@ -36,18 +36,28 @@ static char const usage[] = "\ Usage: " APP_ID " [OPTIONS]\n\ Options:\n\ -a, --algo=ALGO specify the algorithm to use\n\ - cryptonight\n" + cn/r, cn/2, cn/1, cn/0, cn/double, cn/half, cn/fast,\n\ + cn/rwz, cn/zls, cn/xao, cn/rto" +#ifdef XMRIG_ALGO_CN_GPU +", cn/gpu,\n" +#else +",\n" +#endif #ifdef XMRIG_ALGO_CN_LITE "\ - cryptonight-lite\n" + cn-lite/1,\n" #endif #ifdef XMRIG_ALGO_CN_HEAVY "\ - cryptonight-heavy\n" + cn-heavy/xhv, cn-heavy/tube, cn-heavy/0,\n" #endif #ifdef XMRIG_ALGO_CN_PICO "\ - cryptonight-pico\n" + cn-pico,\n" +#endif +#ifdef XMRIG_ALGO_RANDOMX +"\ + rx/wow, rx/loki\n" #endif "\ -o, --url=URL URL of mining server\n\ @@ -76,7 +86,6 @@ Options:\n\ --cpu-priority set process priority (0 idle, 2 normal to 5 highest)\n\ --no-huge-pages disable huge pages support\n\ --no-color disable colored output\n\ - --variant algorithm PoW variant\n\ --donate-level=N donate level, default 5%% (5 minutes in 100 minutes)\n\ --user-agent set custom user-agent string for pool\n\ -B, --background run the miner in the background\n\