From 1c7ca3a0a77fb1f7d227e1c6eee1a0a30f127afe Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 30 Jul 2019 19:40:03 +0700 Subject: [PATCH 01/13] v2.99.4-evo --- src/version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.h b/src/version.h index 38c467df..350814be 100644 --- a/src/version.h +++ b/src/version.h @@ -28,7 +28,7 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "XMRig CPU miner" -#define APP_VERSION "2.99.3-beta" +#define APP_VERSION "2.99.4-evo" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2019 xmrig.com" @@ -36,7 +36,7 @@ #define APP_VER_MAJOR 2 #define APP_VER_MINOR 99 -#define APP_VER_PATCH 3 +#define APP_VER_PATCH 4 #ifdef _MSC_VER # if (_MSC_VER >= 1920) From 962f0cdd8ee5fe8ba287b47d4b491fca55776828 Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 30 Jul 2019 21:25:27 +0700 Subject: [PATCH 02/13] Use std::thread and std:mutex instead of uv_thread_t and uv_mutex_t. --- src/backend/common/Thread.h | 8 ++-- src/core/Miner.cpp | 8 ++++ src/crypto/rx/Rx.cpp | 78 ++++++++++++++++--------------------- src/crypto/rx/Rx.h | 3 +- 4 files changed, 47 insertions(+), 50 deletions(-) diff --git a/src/backend/common/Thread.h b/src/backend/common/Thread.h index 36367ece..b7165915 100644 --- a/src/backend/common/Thread.h +++ b/src/backend/common/Thread.h @@ -26,7 +26,7 @@ #define XMRIG_THREAD_H -#include +#include #include "backend/common/interfaces/IWorker.h" @@ -43,21 +43,21 @@ 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); delete m_worker; } + inline ~Thread() { m_thread.join(); delete m_worker; } 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; } - inline void start(void (*callback) (void *)) { uv_thread_create(&m_thread, callback, this); } + inline void start(void (*callback) (void *)) { m_thread = std::thread(callback, this); } private: const size_t m_index = 0; const T m_config; IBackend *m_backend; IWorker *m_worker = nullptr; - uv_thread_t m_thread; + std::thread m_thread; }; diff --git a/src/core/Miner.cpp b/src/core/Miner.cpp index 64bd54c8..1bca9fc8 100644 --- a/src/core/Miner.cpp +++ b/src/core/Miner.cpp @@ -59,6 +59,10 @@ public: inline MinerPrivate(Controller *controller) : controller(controller) { uv_rwlock_init(&rwlock); + +# ifdef XMRIG_ALGO_RANDOMX + Rx::init(); +# endif } @@ -71,6 +75,10 @@ public: for (IBackend *backend : backends) { delete backend; } + +# ifdef XMRIG_ALGO_RANDOMX + Rx::destroy(); +# endif } diff --git a/src/crypto/rx/Rx.cpp b/src/crypto/rx/Rx.cpp index 5fc95006..676eca2c 100644 --- a/src/crypto/rx/Rx.cpp +++ b/src/crypto/rx/Rx.cpp @@ -26,8 +26,8 @@ #include +#include #include -#include #ifdef XMRIG_FEATURE_HWLOC @@ -50,7 +50,11 @@ namespace xmrig { +class RxPrivate; + + static const char *tag = BLUE_BG(WHITE_BOLD_S " rx ") " "; +static RxPrivate *d_ptr = nullptr; class RxPrivate @@ -58,7 +62,6 @@ class RxPrivate public: inline RxPrivate() { - uv_mutex_init(&mutex); } @@ -69,21 +72,15 @@ public: } datasets.clear(); - - uv_mutex_destroy(&mutex); } - inline void lock() { uv_mutex_lock(&mutex); } - inline void unlock() { uv_mutex_unlock(&mutex); } - - - static void allocate(RxPrivate *self, uint32_t nodeId) + static void allocate(uint32_t nodeId) { const uint64_t ts = Chrono::steadyMSecs(); # ifdef XMRIG_FEATURE_HWLOC - if (self->numa) { + if (d_ptr->numa) { hwloc_topology_t topology; hwloc_topology_init(&topology); hwloc_topology_load(topology); @@ -113,8 +110,8 @@ public: RxCache::size() / 1024 / 1024 ); - RxDataset *dataset = new RxDataset(self->hugePages); - self->datasets[nodeId] = dataset; + RxDataset *dataset = new RxDataset(d_ptr->hugePages); + d_ptr->datasets[nodeId] = dataset; if (dataset->get() != nullptr) { const auto hugePages = dataset->hugePages(); @@ -140,40 +137,33 @@ public: bool hugePages = true; bool numa = true; std::map datasets; - uv_mutex_t mutex; + std::mutex mutex; }; -static RxPrivate *d_ptr = new RxPrivate(); - - } // namespace xmrig bool xmrig::Rx::isReady(const Job &job, uint32_t nodeId) { - d_ptr->lock(); - const bool rc = isReady(job.seedHash(), job.algorithm(), d_ptr->numa ? nodeId : 0); - d_ptr->unlock(); + std::lock_guard lock(d_ptr->mutex); - return rc; + return isReady(job.seedHash(), job.algorithm(), d_ptr->numa ? nodeId : 0); } xmrig::RxDataset *xmrig::Rx::dataset(uint32_t nodeId) { - d_ptr->lock(); - RxDataset *dataset = d_ptr->datasets[d_ptr->numa ? nodeId : 0]; - d_ptr->unlock(); + std::lock_guard lock(d_ptr->mutex); - return dataset; + return d_ptr->datasets[d_ptr->numa ? nodeId : 0]; } std::pair xmrig::Rx::hugePages() { std::pair pages(0, 0); - d_ptr->lock(); + std::lock_guard lock(d_ptr->mutex); for (auto const &item : d_ptr->datasets) { if (!item.second) { @@ -185,19 +175,31 @@ std::pair xmrig::Rx::hugePages() pages.second += p.second; } - d_ptr->unlock(); - return pages; } +void xmrig::Rx::destroy() +{ + delete d_ptr; + + d_ptr = nullptr; +} + + +void xmrig::Rx::init() +{ + d_ptr = new RxPrivate(); +} + + void xmrig::Rx::init(const Job &job, int initThreads, bool hugePages, bool numa) { if (job.algorithm().family() != Algorithm::RANDOM_X) { return; } - d_ptr->lock(); + std::lock_guard lock(d_ptr->mutex); size_t ready = 0; @@ -208,8 +210,6 @@ void xmrig::Rx::init(const Job &job, int initThreads, bool hugePages, bool numa) } if (!d_ptr->datasets.empty() && ready == d_ptr->datasets.size()) { - d_ptr->unlock(); - return; } @@ -231,16 +231,6 @@ void xmrig::Rx::init(const Job &job, int initThreads, bool hugePages, bool numa) std::thread thread(initDataset, 0, job.seedHash(), job.algorithm(), threads); thread.detach(); } - - d_ptr->unlock(); -} - - -void xmrig::Rx::stop() -{ - delete d_ptr; - - d_ptr = nullptr; } @@ -252,19 +242,19 @@ bool xmrig::Rx::isReady(const uint8_t *seed, const Algorithm &algorithm, uint32_ void xmrig::Rx::initDataset(uint32_t nodeId, const uint8_t *seed, const Algorithm &algorithm, uint32_t threads) { - d_ptr->lock(); + std::lock_guard lock(d_ptr->mutex); RxDataset *dataset = d_ptr->datasets[nodeId]; if (!dataset) { # ifdef XMRIG_FEATURE_HWLOC if (d_ptr->numa) { - std::thread thread(RxPrivate::allocate, d_ptr, nodeId); + std::thread thread(RxPrivate::allocate, nodeId); thread.join(); } else # endif { - RxPrivate::allocate(d_ptr, nodeId); + RxPrivate::allocate(nodeId); } dataset = d_ptr->datasets[nodeId]; @@ -295,6 +285,4 @@ void xmrig::Rx::initDataset(uint32_t nodeId, const uint8_t *seed, const Algorith LOG_INFO("%s" CYAN_BOLD("#%u") GREEN(" init done") BLACK_BOLD(" (%" PRIu64 " ms)"), tag, nodeId, Chrono::steadyMSecs() - ts); } - - d_ptr->unlock(); } diff --git a/src/crypto/rx/Rx.h b/src/crypto/rx/Rx.h index 43e4be1c..c484c3b4 100644 --- a/src/crypto/rx/Rx.h +++ b/src/crypto/rx/Rx.h @@ -47,8 +47,9 @@ public: static bool isReady(const Job &job, uint32_t nodeId); static RxDataset *dataset(uint32_t nodeId); static std::pair hugePages(); + static void destroy(); + static void init(); static void init(const Job &job, int initThreads, bool hugePages, bool numa); - static void stop(); private: static bool isReady(const uint8_t *seed, const Algorithm &algorithm, uint32_t nodeId); From c138161ee23c40d2758683fe409ecf9980accea4 Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 31 Jul 2019 09:29:09 +0700 Subject: [PATCH 03/13] Replacement for PR #1087 --- src/backend/cpu/platform/HwlocCpuInfo.cpp | 18 +++++++++++++++++- src/crypto/common/VirtualMemory.cpp | 4 ++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/backend/cpu/platform/HwlocCpuInfo.cpp b/src/backend/cpu/platform/HwlocCpuInfo.cpp index 98f55989..23ee554f 100644 --- a/src/backend/cpu/platform/HwlocCpuInfo.cpp +++ b/src/backend/cpu/platform/HwlocCpuInfo.cpp @@ -32,6 +32,12 @@ #include +#if HWLOC_API_VERSION < 0x00010b00 +# define HWLOC_OBJ_PACKAGE HWLOC_OBJ_SOCKET +# define HWLOC_OBJ_NUMANODE HWLOC_OBJ_NODE +#endif + + #include "backend/cpu/platform/HwlocCpuInfo.h" #include "base/io/log/Log.h" @@ -152,7 +158,17 @@ xmrig::HwlocCpuInfo::HwlocCpuInfo() : BasicCpuInfo(), # endif hwloc_obj_t root = hwloc_get_root_obj(m_topology); - snprintf(m_backend, sizeof m_backend, "hwloc/%s", hwloc_obj_get_info_by_name(root, "hwlocVersion")); + +# if HWLOC_API_VERSION >= 0x00010b00 + const char *version = hwloc_obj_get_info_by_name(root, "hwlocVersion"); + if (version) { + snprintf(m_backend, sizeof m_backend, "hwloc/%s", version); + } + else +# endif + { + snprintf(m_backend, sizeof m_backend, "hwloc"); + } findCache(root, 2, 3, [this](hwloc_obj_t found) { this->m_cache[found->attr->cache.depth] += found->attr->cache.size; }); diff --git a/src/crypto/common/VirtualMemory.cpp b/src/crypto/common/VirtualMemory.cpp index e3c70dfb..5f7c4551 100644 --- a/src/crypto/common/VirtualMemory.cpp +++ b/src/crypto/common/VirtualMemory.cpp @@ -28,6 +28,10 @@ #ifdef XMRIG_FEATURE_HWLOC # include # include "backend/cpu/platform/HwlocCpuInfo.h" +# +# if HWLOC_API_VERSION < 0x00010b00 +# define HWLOC_OBJ_NUMANODE HWLOC_OBJ_NODE +# endif #endif From ab0d3b8919b8b07c61e25bd868c8bee950fce00f Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 31 Jul 2019 09:38:27 +0700 Subject: [PATCH 04/13] Fixed ARM build with hwloc. --- src/backend/cpu/cpu.cmake | 4 +++- src/backend/cpu/platform/BasicCpuInfo_arm.cpp | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/backend/cpu/cpu.cmake b/src/backend/cpu/cpu.cmake index 1072df08..2ae73db7 100644 --- a/src/backend/cpu/cpu.cmake +++ b/src/backend/cpu/cpu.cmake @@ -39,7 +39,6 @@ if (WITH_HWLOC) endif() set(SOURCES_CPUID - src/backend/cpu/platform/BasicCpuInfo.cpp src/backend/cpu/platform/BasicCpuInfo.h src/backend/cpu/platform/HwlocCpuInfo.cpp src/backend/cpu/platform/HwlocCpuInfo.h @@ -66,7 +65,10 @@ else() set(SOURCES_CPUID src/backend/cpu/platform/BasicCpuInfo.h ) +endif() + +if (NOT WITH_LIBCPUID) if (XMRIG_ARM) set(SOURCES_CPUID ${SOURCES_CPUID} src/backend/cpu/platform/BasicCpuInfo_arm.cpp) else() diff --git a/src/backend/cpu/platform/BasicCpuInfo_arm.cpp b/src/backend/cpu/platform/BasicCpuInfo_arm.cpp index 1e6c3cb7..b241e197 100644 --- a/src/backend/cpu/platform/BasicCpuInfo_arm.cpp +++ b/src/backend/cpu/platform/BasicCpuInfo_arm.cpp @@ -36,10 +36,10 @@ xmrig::BasicCpuInfo::BasicCpuInfo() : - m_aes(false), m_brand(), - m_avx2(false), - m_threads(std::thread::hardware_concurrency()) + m_threads(std::thread::hardware_concurrency()), + m_aes(false), + m_avx2(false) { # ifdef XMRIG_ARMv8 memcpy(m_brand, "ARMv8", 5); From 97453d986f818e8da28a21416b7c3bd066b5acb7 Mon Sep 17 00:00:00 2001 From: SChernykh Date: Wed, 31 Jul 2019 10:01:32 +0200 Subject: [PATCH 05/13] Fix Mac OS X compilation Thanks to @cjdelisle --- src/crypto/randomx/jit_compiler_x86_static.S | 24 ++++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/crypto/randomx/jit_compiler_x86_static.S b/src/crypto/randomx/jit_compiler_x86_static.S index 9cffaab5..67d2bdbc 100644 --- a/src/crypto/randomx/jit_compiler_x86_static.S +++ b/src/crypto/randomx/jit_compiler_x86_static.S @@ -68,9 +68,9 @@ DECL(randomx_program_prologue): #else #include "asm/program_prologue_linux.inc" #endif - movapd xmm13, xmmword ptr mantissaMask[rip] - movapd xmm14, xmmword ptr exp240[rip] - movapd xmm15, xmmword ptr scaleMask[rip] + movapd xmm13, xmmword ptr [mantissaMask+rip] + movapd xmm14, xmmword ptr [exp240+rip] + movapd xmm15, xmmword ptr [scaleMask+rip] jmp DECL(randomx_program_loop_begin) .balign 64 @@ -177,26 +177,26 @@ DECL(randomx_sshash_end): DECL(randomx_sshash_init): lea r8, [rbx+1] #include "asm/program_sshash_prefetch.inc" - imul r8, qword ptr r0_mul[rip] - mov r9, qword ptr r1_add[rip] + imul r8, qword ptr [r0_mul+rip] + mov r9, qword ptr [r1_add+rip] xor r9, r8 - mov r10, qword ptr r2_add[rip] + mov r10, qword ptr [r2_add+rip] xor r10, r8 - mov r11, qword ptr r3_add[rip] + mov r11, qword ptr [r3_add+rip] xor r11, r8 - mov r12, qword ptr r4_add[rip] + mov r12, qword ptr [r4_add+rip] xor r12, r8 - mov r13, qword ptr r5_add[rip] + mov r13, qword ptr [r5_add+rip] xor r13, r8 - mov r14, qword ptr r6_add[rip] + mov r14, qword ptr [r6_add+rip] xor r14, r8 - mov r15, qword ptr r7_add[rip] + mov r15, qword ptr [r7_add+rip] xor r15, r8 jmp DECL(randomx_program_end) .balign 64 #include "asm/program_sshash_constants.inc" - + .balign 64 DECL(randomx_program_end): nop From 84ff8af4bd4a6a12fc4af4664e94ba9617904bd4 Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 1 Aug 2019 20:37:05 +0700 Subject: [PATCH 06/13] Optimized RandomX initialization and switching. --- src/backend/cpu/CpuWorker.cpp | 11 +- src/base/io/log/Log.cpp | 17 +-- src/base/tools/Buffer.h | 15 ++- src/core/Miner.cpp | 2 +- src/crypto/rx/Rx.cpp | 239 +++++++++++++++++++--------------- src/crypto/rx/Rx.h | 7 +- src/crypto/rx/RxCache.h | 3 +- src/crypto/rx/RxDataset.cpp | 16 +-- src/crypto/rx/RxDataset.h | 3 +- 9 files changed, 156 insertions(+), 157 deletions(-) diff --git a/src/backend/cpu/CpuWorker.cpp b/src/backend/cpu/CpuWorker.cpp index cd804199..000d7061 100644 --- a/src/backend/cpu/CpuWorker.cpp +++ b/src/backend/cpu/CpuWorker.cpp @@ -82,7 +82,9 @@ xmrig::CpuWorker::~CpuWorker() template void xmrig::CpuWorker::allocateRandomX_VM() { - while (!Rx::isReady(m_job.currentJob(), m_node)) { + RxDataset *dataset = Rx::dataset(m_job.currentJob(), m_node); + + while (dataset == nullptr) { std::this_thread::sleep_for(std::chrono::milliseconds(200)); if (Nonce::sequence(Nonce::CPU) == 0) { @@ -90,13 +92,6 @@ void xmrig::CpuWorker::allocateRandomX_VM() } } - RxDataset *dataset = Rx::dataset(m_node); - assert(dataset != nullptr); - - if (!dataset) { - return; - } - if (!m_vm) { m_vm = new RxVm(dataset, m_memory->scratchpad(), !m_hwAES); } diff --git a/src/base/io/log/Log.cpp b/src/base/io/log/Log.cpp index 22972a7e..4e3bd5a5 100644 --- a/src/base/io/log/Log.cpp +++ b/src/base/io/log/Log.cpp @@ -31,6 +31,7 @@ #include +#include #include #include #include @@ -69,14 +70,11 @@ public: inline LogPrivate() : m_buf() { - uv_mutex_init(&m_mutex); } inline ~LogPrivate() { - uv_mutex_destroy(&m_mutex); - for (ILogBackend *backend : m_backends) { delete backend; } @@ -91,13 +89,14 @@ public: size_t size = 0; size_t offset = 0; - lock(); + std::lock_guard lock(m_mutex); + timestamp(level, size, offset); color(level, size); const int rc = vsnprintf(m_buf + size, sizeof (m_buf) - offset - 32, fmt, args); if (rc < 0) { - return unlock(); + return; } size += std::min(static_cast(rc), sizeof (m_buf) - offset - 32); @@ -119,16 +118,10 @@ public: fputs(txt.c_str(), stdout); fflush(stdout); } - - unlock(); } private: - inline void lock() { uv_mutex_lock(&m_mutex); } - inline void unlock() { uv_mutex_unlock(&m_mutex); } - - inline void timestamp(Log::Level level, size_t &size, size_t &offset) { if (level == Log::NONE) { @@ -192,8 +185,8 @@ private: char m_buf[4096]; + std::mutex m_mutex; std::vector m_backends; - uv_mutex_t m_mutex; }; diff --git a/src/base/tools/Buffer.h b/src/base/tools/Buffer.h index 6b720357..28f92b9e 100644 --- a/src/base/tools/Buffer.h +++ b/src/base/tools/Buffer.h @@ -43,17 +43,20 @@ public: ~Buffer(); - inline char *data() { return m_data; } - inline const char *data() const { return m_data; } - inline size_t size() const { return m_size; } - inline void from(const Buffer &other) { from(other.data(), other.size()); } + inline bool isEqual(const Buffer &other) const { return m_size == other.m_size && (m_size == 0 || memcmp(m_data, other.m_data, m_size) == 0); } + inline char *data() { return m_data; } + inline const char *data() const { return m_data; } + inline size_t size() const { return m_size; } + inline void from(const Buffer &other) { from(other.data(), other.size()); } void from(const char *data, size_t size); - inline Buffer &operator=(const Buffer &other) { from(other); return *this; } - inline Buffer &operator=(Buffer &&other) { move(std::move(other)); return *this; } + inline bool operator!=(const Buffer &other) const { return !isEqual(other); } + inline bool operator==(const Buffer &other) const { return isEqual(other); } + inline Buffer &operator=(Buffer &&other) { move(std::move(other)); return *this; } + inline Buffer &operator=(const Buffer &other) { from(other); return *this; } static Buffer allocUnsafe(size_t size); diff --git a/src/core/Miner.cpp b/src/core/Miner.cpp index 1bca9fc8..ab4a8ef6 100644 --- a/src/core/Miner.cpp +++ b/src/core/Miner.cpp @@ -380,7 +380,7 @@ void xmrig::Miner::setJob(const Job &job, bool donate) } # ifdef XMRIG_ALGO_RANDOMX - Rx::init(job, + Rx::init(d_ptr->job, d_ptr->controller->config()->rx().threads(), d_ptr->controller->config()->cpu().isHugePages(), d_ptr->controller->config()->rx().isNUMA() diff --git a/src/crypto/rx/Rx.cpp b/src/crypto/rx/Rx.cpp index 676eca2c..5f5414c9 100644 --- a/src/crypto/rx/Rx.cpp +++ b/src/crypto/rx/Rx.cpp @@ -43,6 +43,7 @@ #include "base/tools/Buffer.h" #include "base/tools/Chrono.h" #include "crypto/rx/Rx.h" +#include "crypto/rx/RxAlgo.h" #include "crypto/rx/RxCache.h" #include "crypto/rx/RxDataset.h" @@ -57,11 +58,50 @@ static const char *tag = BLUE_BG(WHITE_BOLD_S " rx ") " "; static RxPrivate *d_ptr = nullptr; +#ifdef XMRIG_FEATURE_HWLOC +static void bindToNUMANode(uint32_t nodeId) +{ + hwloc_topology_t topology; + hwloc_topology_init(&topology); + hwloc_topology_load(topology); + + hwloc_obj_t node = hwloc_get_numanode_obj_by_os_index(topology, nodeId); + if (node) { + if (HwlocCpuInfo::has(HwlocCpuInfo::SET_THISTHREAD_MEMBIND)) { +# if HWLOC_API_VERSION >= 0x20000 + hwloc_set_membind(topology, node->nodeset, HWLOC_MEMBIND_BIND, HWLOC_MEMBIND_THREAD | HWLOC_MEMBIND_BYNODESET); +# else + hwloc_set_membind_nodeset(topology, node->nodeset, HWLOC_MEMBIND_BIND, HWLOC_MEMBIND_THREAD); +# endif + } + + Platform::setThreadAffinity(static_cast(hwloc_bitmap_first(node->cpuset))); + } + + hwloc_topology_destroy(topology); +} +#else +inline static void bindToNUMANode(uint32_t) {} +#endif + + class RxPrivate { public: - inline RxPrivate() + inline RxPrivate() : + m_seed() { +# ifdef XMRIG_FEATURE_HWLOC + if (Cpu::info()->nodes() > 1) { + for (uint32_t nodeId : HwlocCpuInfo::nodeIndexes()) { + datasets.insert({ nodeId, nullptr }); + } + } + else +# endif + { + datasets.insert({ 0, nullptr }); + } } @@ -75,32 +115,19 @@ public: } + inline bool isNUMA() const { return m_numa; } + inline const Algorithm &algorithm() const { return m_algorithm; } + inline const uint8_t *seed() const { return m_seed; } + inline size_t count() const { return isNUMA() ? datasets.size() : 1; } + + static void allocate(uint32_t nodeId) { const uint64_t ts = Chrono::steadyMSecs(); -# ifdef XMRIG_FEATURE_HWLOC - if (d_ptr->numa) { - hwloc_topology_t topology; - hwloc_topology_init(&topology); - hwloc_topology_load(topology); - - hwloc_obj_t node = hwloc_get_numanode_obj_by_os_index(topology, nodeId); - if (node) { - if (HwlocCpuInfo::has(HwlocCpuInfo::SET_THISTHREAD_MEMBIND)) { -# if HWLOC_API_VERSION >= 0x20000 - hwloc_set_membind(topology, node->nodeset, HWLOC_MEMBIND_BIND, HWLOC_MEMBIND_THREAD | HWLOC_MEMBIND_BYNODESET); -# else - hwloc_set_membind_nodeset(topology, node->nodeset, HWLOC_MEMBIND_BIND, HWLOC_MEMBIND_THREAD); -# endif - } - - Platform::setThreadAffinity(static_cast(hwloc_bitmap_first(node->cpuset))); - } - - hwloc_topology_destroy(topology); + if (d_ptr->isNUMA()) { + bindToNUMANode(nodeId); } -# endif LOG_INFO("%s" CYAN_BOLD("#%u") MAGENTA_BOLD(" allocate") CYAN_BOLD(" %zu MB") BLACK_BOLD(" (%zu+%zu) for RandomX dataset & cache"), tag, @@ -110,7 +137,7 @@ public: RxCache::size() / 1024 / 1024 ); - RxDataset *dataset = new RxDataset(d_ptr->hugePages); + RxDataset *dataset = new RxDataset(d_ptr->m_hugePages); d_ptr->datasets[nodeId] = dataset; if (dataset->get() != nullptr) { @@ -134,29 +161,84 @@ public: } - bool hugePages = true; - bool numa = true; + static void initDataset(uint32_t nodeId, uint32_t threads) + { + std::lock_guard lock(d_ptr->mutex); + + const uint64_t ts = Chrono::steadyMSecs(); + + d_ptr->getOrAllocate(nodeId)->init(d_ptr->seed(), threads); + d_ptr->m_ready++; + + LOG_INFO("%s" CYAN_BOLD("#%u") GREEN(" init done") BLACK_BOLD(" (%" PRIu64 " ms)"), tag, nodeId, Chrono::steadyMSecs() - ts); + } + + + inline RxDataset *getOrAllocate(uint32_t nodeId) + { + RxDataset *dataset = datasets.at(nodeId); + + if (dataset == nullptr) { + # ifdef XMRIG_FEATURE_HWLOC + if (d_ptr->isNUMA()) { + std::thread thread(allocate, nodeId); + thread.join(); + } else + # endif + { + allocate(nodeId); + } + + dataset = datasets.at(nodeId); + } + + return dataset; + } + + + inline void setState(const Job &job, bool hugePages, bool numa) + { + if (m_algorithm != job.algorithm()) { + m_algorithm = RxAlgo::apply(job.algorithm()); + } + + m_ready = 0; + m_numa = numa && Cpu::info()->nodes() > 1; + m_hugePages = hugePages; + + memcpy(m_seed, job.seedHash(), sizeof(m_seed)); + } + + + inline bool isReady(const Job &job) + { + return m_ready == count() && m_algorithm == job.algorithm() && memcmp(m_seed, job.seedHash(), sizeof(m_seed)) == 0; + } + + std::map datasets; std::mutex mutex; + +private: + bool m_hugePages = true; + bool m_numa = true; + Algorithm m_algorithm; + size_t m_ready = 0; + uint8_t m_seed[32]; }; } // namespace xmrig -bool xmrig::Rx::isReady(const Job &job, uint32_t nodeId) +xmrig::RxDataset *xmrig::Rx::dataset(const Job &job, uint32_t nodeId) { std::lock_guard lock(d_ptr->mutex); + if (!d_ptr->isReady(job)) { + return nullptr; + } - return isReady(job.seedHash(), job.algorithm(), d_ptr->numa ? nodeId : 0); -} - - -xmrig::RxDataset *xmrig::Rx::dataset(uint32_t nodeId) -{ - std::lock_guard lock(d_ptr->mutex); - - return d_ptr->datasets[d_ptr->numa ? nodeId : 0]; + return d_ptr->datasets.at(d_ptr->isNUMA() ? nodeId : 0); } @@ -201,88 +283,33 @@ void xmrig::Rx::init(const Job &job, int initThreads, bool hugePages, bool numa) std::lock_guard lock(d_ptr->mutex); - size_t ready = 0; - - for (auto const &item : d_ptr->datasets) { - if (isReady(job.seedHash(), job.algorithm(), item.first)) { - ready++; - } - } - - if (!d_ptr->datasets.empty() && ready == d_ptr->datasets.size()) { + if (d_ptr->isReady(job)) { return; } - d_ptr->hugePages = hugePages; - d_ptr->numa = numa && Cpu::info()->nodes() > 1; - const uint32_t threads = initThreads < 1 ? static_cast(Cpu::info()->threads()) - : static_cast(initThreads); + d_ptr->setState(job, hugePages, numa); + const uint32_t threads = initThreads < 1 ? static_cast(Cpu::info()->threads()) : static_cast(initThreads); + const String buf = Buffer::toHex(job.seedHash(), 8); + + LOG_INFO("%s" MAGENTA_BOLD("init dataset%s") " algo " WHITE_BOLD("%s (") CYAN_BOLD("%u") WHITE_BOLD(" threads)") BLACK_BOLD(" seed %s..."), + tag, + d_ptr->count() > 1 ? "s" : "", + job.algorithm().shortName(), + threads, + buf.data() + ); # ifdef XMRIG_FEATURE_HWLOC - if (d_ptr->numa) { - for (uint32_t nodeId : HwlocCpuInfo::nodeIndexes()) { - std::thread thread(initDataset, nodeId, job.seedHash(), job.algorithm(), threads); + if (d_ptr->isNUMA()) { + for (auto const &item : d_ptr->datasets) { + std::thread thread(RxPrivate::initDataset, item.first, threads); thread.detach(); } } else # endif { - std::thread thread(initDataset, 0, job.seedHash(), job.algorithm(), threads); + std::thread thread(RxPrivate::initDataset, 0, threads); thread.detach(); } } - - -bool xmrig::Rx::isReady(const uint8_t *seed, const Algorithm &algorithm, uint32_t nodeId) -{ - return !d_ptr->datasets.empty() && d_ptr->datasets[nodeId] != nullptr && d_ptr->datasets[nodeId]->isReady(seed, algorithm); -} - - -void xmrig::Rx::initDataset(uint32_t nodeId, const uint8_t *seed, const Algorithm &algorithm, uint32_t threads) -{ - std::lock_guard lock(d_ptr->mutex); - - RxDataset *dataset = d_ptr->datasets[nodeId]; - - if (!dataset) { -# ifdef XMRIG_FEATURE_HWLOC - if (d_ptr->numa) { - std::thread thread(RxPrivate::allocate, nodeId); - thread.join(); - } else -# endif - { - RxPrivate::allocate(nodeId); - } - - dataset = d_ptr->datasets[nodeId]; - } - - if (!dataset->isReady(seed, algorithm)) { - const uint64_t ts = Chrono::steadyMSecs(); - - if (dataset->get() != nullptr) { - LOG_INFO("%s" CYAN_BOLD("#%u") MAGENTA_BOLD(" init dataset") " algo " WHITE_BOLD("%s (") CYAN_BOLD("%u") WHITE_BOLD(" threads)") BLACK_BOLD(" seed %s..."), - tag, - nodeId, - algorithm.shortName(), - threads, - Buffer::toHex(seed, 8).data() - ); - } - else { - LOG_INFO("%s" CYAN_BOLD("#%u") MAGENTA_BOLD(" init cache") " algo " WHITE_BOLD("%s") BLACK_BOLD(" seed %s..."), - tag, - nodeId, - algorithm.shortName(), - Buffer::toHex(seed, 8).data() - ); - } - - dataset->init(seed, algorithm, threads); - - LOG_INFO("%s" CYAN_BOLD("#%u") GREEN(" init done") BLACK_BOLD(" (%" PRIu64 " ms)"), tag, nodeId, Chrono::steadyMSecs() - ts); - } -} diff --git a/src/crypto/rx/Rx.h b/src/crypto/rx/Rx.h index c484c3b4..1ba6397e 100644 --- a/src/crypto/rx/Rx.h +++ b/src/crypto/rx/Rx.h @@ -44,16 +44,11 @@ class Job; class Rx { public: - static bool isReady(const Job &job, uint32_t nodeId); - static RxDataset *dataset(uint32_t nodeId); + static RxDataset *dataset(const Job &job, uint32_t nodeId); static std::pair hugePages(); static void destroy(); static void init(); static void init(const Job &job, int initThreads, bool hugePages, bool numa); - -private: - static bool isReady(const uint8_t *seed, const Algorithm &algorithm, uint32_t nodeId); - static void initDataset(uint32_t nodeId, const uint8_t *seed, const Algorithm &algorithm, uint32_t threads); }; diff --git a/src/crypto/rx/RxCache.h b/src/crypto/rx/RxCache.h index c48924a1..80c1faba 100644 --- a/src/crypto/rx/RxCache.h +++ b/src/crypto/rx/RxCache.h @@ -53,11 +53,12 @@ public: 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: + bool isReady(const void *seed) const; + 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 617b9200..7d498c4d 100644 --- a/src/crypto/rx/RxDataset.cpp +++ b/src/crypto/rx/RxDataset.cpp @@ -64,16 +64,8 @@ xmrig::RxDataset::~RxDataset() } -bool xmrig::RxDataset::init(const void *seed, const Algorithm &algorithm, uint32_t numThreads) +bool xmrig::RxDataset::init(const void *seed, uint32_t numThreads) { - if (isReady(seed, algorithm)) { - return false; - } - - if (m_algorithm != algorithm) { - m_algorithm = RxAlgo::apply(algorithm); - } - cache()->init(seed); if (!get()) { @@ -104,12 +96,6 @@ bool xmrig::RxDataset::init(const void *seed, const Algorithm &algorithm, uint32 } -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; diff --git a/src/crypto/rx/RxDataset.h b/src/crypto/rx/RxDataset.h index 7944d52c..d3488668 100644 --- a/src/crypto/rx/RxDataset.h +++ b/src/crypto/rx/RxDataset.h @@ -52,8 +52,7 @@ public: 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; + bool init(const void *seed, uint32_t numThreads); std::pair hugePages() const; static inline constexpr size_t size() { return RANDOMX_DATASET_MAX_SIZE; } From 718be7e9aa89b163077d40cf0e6cd63dae7d2757 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 2 Aug 2019 10:54:00 +0700 Subject: [PATCH 07/13] Fixed 32-bit. --- cmake/flags.cmake | 6 +++++- src/base/net/stratum/Job.cpp | 17 +++++++++++++++++ src/base/net/stratum/Job.h | 5 ++++- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/cmake/flags.cmake b/cmake/flags.cmake index 3f2bd0a0..bc441dd0 100644 --- a/cmake/flags.cmake +++ b/cmake/flags.cmake @@ -34,7 +34,11 @@ if (CMAKE_CXX_COMPILER_ID MATCHES GNU) endif() if (WIN32) - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static") + if (CMAKE_SIZEOF_VOID_P EQUAL 8) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static") + else() + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static -Wl,--large-address-aware") + endif() else() set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++") endif() diff --git a/src/base/net/stratum/Job.cpp b/src/base/net/stratum/Job.cpp index a383bbf7..512b686e 100644 --- a/src/base/net/stratum/Job.cpp +++ b/src/base/net/stratum/Job.cpp @@ -160,3 +160,20 @@ void xmrig::Job::setDiff(uint64_t diff) m_rawTarget[16] = '\0'; # endif } + + +void xmrig::Job::copy(const Job &other) +{ + m_algorithm = other.m_algorithm; + m_nicehash = other.m_nicehash; + m_size = other.m_size; + m_clientId = other.m_clientId; + m_id = other.m_id; + m_diff = other.m_diff; + m_height = other.m_height; + m_target = other.m_target; + m_index = other.m_index; + + memcpy(m_blob, other.m_blob, sizeof (m_blob)); + memcpy(m_seedHash, other.m_seedHash, sizeof(m_seedHash)); +} diff --git a/src/base/net/stratum/Job.h b/src/base/net/stratum/Job.h index 06d1be79..2b256a12 100644 --- a/src/base/net/stratum/Job.h +++ b/src/base/net/stratum/Job.h @@ -90,10 +90,13 @@ public: inline bool operator==(const Job &other) const { return isEqual(other); } inline bool operator!=(const Job &other) const { return !isEqual(other); } + inline Job &operator=(const Job &other) { copy(other); return *this; } private: + void copy(const Job &other); + Algorithm m_algorithm; - bool m_nicehash = false; + bool m_nicehash = false; size_t m_size = 0; String m_clientId; String m_id; From bdaf28adf814cda247db0592c403b8ee4c92a321 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 2 Aug 2019 14:44:38 +0700 Subject: [PATCH 08/13] Unified memory allocation functions. --- src/crypto/randomx/virtual_memory.cpp | 81 ++++++--------------------- 1 file changed, 17 insertions(+), 64 deletions(-) diff --git a/src/crypto/randomx/virtual_memory.cpp b/src/crypto/randomx/virtual_memory.cpp index 925e8e86..661740fc 100644 --- a/src/crypto/randomx/virtual_memory.cpp +++ b/src/crypto/randomx/virtual_memory.cpp @@ -26,80 +26,33 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "virtual_memory.hpp" - #include -#if defined(_WIN32) || defined(__CYGWIN__) -#include -#else -#ifdef __APPLE__ -#include -#endif -#include -#include -#ifndef MAP_ANONYMOUS -#define MAP_ANONYMOUS MAP_ANON -#endif -#endif -#if defined(_WIN32) || defined(__CYGWIN__) -std::string getErrorMessage(const char* function) { - LPSTR messageBuffer = nullptr; - size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL); - std::string message(messageBuffer, size); - LocalFree(messageBuffer); - return std::string(function) + std::string(": ") + message; -} -#endif +#include "crypto/common/VirtualMemory.h" +#include "virtual_memory.hpp" + void* allocExecutableMemory(std::size_t bytes) { - void* mem; -#if defined(_WIN32) || defined(__CYGWIN__) - mem = VirtualAlloc(nullptr, bytes, MEM_COMMIT, PAGE_EXECUTE_READWRITE); - if (mem == nullptr) - throw std::runtime_error(getErrorMessage("allocExecutableMemory - VirtualAlloc")); -#else - mem = mmap(nullptr, bytes, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); - if (mem == MAP_FAILED) - throw std::runtime_error("allocExecutableMemory - mmap failed"); -#endif - return mem; + void *mem = xmrig::VirtualMemory::allocateExecutableMemory(bytes); + if (mem == nullptr) { + throw std::runtime_error("Failed to allocate executable memory"); + } + + return mem; } -constexpr std::size_t align(std::size_t pos, std::size_t align) { - return ((pos - 1) / align + 1) * align; -} void* allocLargePagesMemory(std::size_t bytes) { - void* mem; -#if defined(_WIN32) || defined(__CYGWIN__) - auto pageMinimum = GetLargePageMinimum(); - if (pageMinimum > 0) - mem = VirtualAlloc(NULL, align(bytes, pageMinimum), MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, PAGE_READWRITE); - else - throw std::runtime_error("allocLargePagesMemory - Large pages are not supported"); - if (mem == nullptr) - throw std::runtime_error(getErrorMessage("allocLargePagesMemory - VirtualAlloc")); -#else -#ifdef __APPLE__ - mem = mmap(nullptr, bytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, VM_FLAGS_SUPERPAGE_SIZE_2MB, 0); -#elif defined(__FreeBSD__) - mem = mmap(nullptr, bytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER, -1, 0); -#else - mem = mmap(nullptr, bytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE, -1, 0); -#endif - if (mem == MAP_FAILED) - throw std::runtime_error("allocLargePagesMemory - mmap failed"); -#endif - return mem; + void *mem = xmrig::VirtualMemory::allocateLargePagesMemory(bytes); + if (mem == nullptr) { + throw std::runtime_error("Failed to allocate large pages memory"); + } + + return mem; } + void freePagedMemory(void* ptr, std::size_t bytes) { -#if defined(_WIN32) || defined(__CYGWIN__) - VirtualFree(ptr, 0, MEM_RELEASE); -#else - munmap(ptr, bytes); -#endif + xmrig::VirtualMemory::freeLargePagesMemory(ptr, bytes); } From e584b266df174567cb2597e92d457a3c315a76aa Mon Sep 17 00:00:00 2001 From: Tony Butler Date: Thu, 1 Aug 2019 13:45:03 -0600 Subject: [PATCH 09/13] Build hwloc version string based on HWLOC_API_VERSION, whenever `hwlocVersion` object does not exist (<1.11.x) --- src/backend/cpu/platform/HwlocCpuInfo.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/backend/cpu/platform/HwlocCpuInfo.cpp b/src/backend/cpu/platform/HwlocCpuInfo.cpp index 23ee554f..b2aa47d7 100644 --- a/src/backend/cpu/platform/HwlocCpuInfo.cpp +++ b/src/backend/cpu/platform/HwlocCpuInfo.cpp @@ -167,7 +167,11 @@ xmrig::HwlocCpuInfo::HwlocCpuInfo() : BasicCpuInfo(), else # endif { - snprintf(m_backend, sizeof m_backend, "hwloc"); + snprintf(m_backend, sizeof m_backend, "hwloc/%d.%d.%d", + (HWLOC_API_VERSION>>16)&0x000000ff, + (HWLOC_API_VERSION>>8 )&0x000000ff, + (HWLOC_API_VERSION )&0x000000ff + ); } findCache(root, 2, 3, [this](hwloc_obj_t found) { this->m_cache[found->attr->cache.depth] += found->attr->cache.size; }); From f7ea4b6dbd739fdad1d0d38aef0c8a8d3da3f08d Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 2 Aug 2019 16:44:55 +0700 Subject: [PATCH 10/13] Always stop mining threads in RandomX dataset change upcoming. --- src/backend/cpu/CpuBackend.cpp | 24 +++++++++++++----------- src/base/io/log/Log.h | 4 ++++ src/core/Miner.cpp | 10 ++++++++-- src/crypto/rx/Rx.cpp | 10 +++++++++- src/crypto/rx/Rx.h | 1 + 5 files changed, 35 insertions(+), 14 deletions(-) diff --git a/src/backend/cpu/CpuBackend.cpp b/src/backend/cpu/CpuBackend.cpp index 005ff1de..60ca8cf3 100644 --- a/src/backend/cpu/CpuBackend.cpp +++ b/src/backend/cpu/CpuBackend.cpp @@ -49,7 +49,8 @@ namespace xmrig { extern template class Threads; -static const String kType = "cpu"; +static const char *tag = CYAN_BG_BOLD(" cpu "); +static const String kType = "cpu"; struct LaunchStatus @@ -94,7 +95,8 @@ public: inline void start() { - 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"), + LOG_INFO("%s use profile " BLUE_BG(WHITE_BOLD_S " %s ") WHITE_BOLD_S " (" CYAN_BOLD("%zu") WHITE_BOLD(" threads)") " scratchpad " CYAN_BOLD("%zu KB"), + tag, profileName.data(), threads.size(), algo.memory() / 1024 @@ -170,12 +172,8 @@ const xmrig::String &xmrig::CpuBackend::type() const } -void xmrig::CpuBackend::prepare(const Job &nextJob) +void xmrig::CpuBackend::prepare(const Job &) { - if (nextJob.algorithm().family() == Algorithm::RANDOM_X && nextJob.algorithm() != d_ptr->algo) { - d_ptr->workers.stop(); - d_ptr->threads.clear(); - } } @@ -207,9 +205,7 @@ void xmrig::CpuBackend::printHashrate(bool details) void xmrig::CpuBackend::setJob(const Job &job) { if (!isEnabled()) { - d_ptr->workers.stop(); - d_ptr->threads.clear(); - return; + return stop(); } const CpuConfig &cpu = d_ptr->controller->config()->cpu(); @@ -249,7 +245,8 @@ 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") BLACK_BOLD(" (%" PRIu64 " ms)"), + LOG_INFO("%s" GREEN_BOLD(" READY") " threads " CYAN_BOLD("%zu(%zu)") " huge pages %s%zu/%zu %1.0f%%\x1B[0m memory " CYAN_BOLD("%zu KB") BLACK_BOLD(" (%" PRIu64 " ms)"), + tag, 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, @@ -265,7 +262,12 @@ void xmrig::CpuBackend::start(IWorker *worker) void xmrig::CpuBackend::stop() { + const uint64_t ts = Chrono::steadyMSecs(); + d_ptr->workers.stop(); + d_ptr->threads.clear(); + + LOG_INFO("%s" YELLOW(" stopped") BLACK_BOLD(" (%" PRIu64 " ms)"), tag, Chrono::steadyMSecs() - ts); } diff --git a/src/base/io/log/Log.h b/src/base/io/log/Log.h index 078a8546..d8bcb44a 100644 --- a/src/base/io/log/Log.h +++ b/src/base/io/log/Log.h @@ -85,6 +85,8 @@ private: #define BLUE_BG_BOLD_S CSI "44;1m" #define MAGENTA_BG_S CSI "45m" #define MAGENTA_BG_BOLD_S CSI "45;1m" +#define CYAN_BG_S CSI "46m" +#define CYAN_BG_BOLD_S CSI "46;1m" //color wrappings #define BLACK(x) BLACK_S x CLEAR @@ -108,6 +110,8 @@ private: #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 CYAN_BG(x) CYAN_BG_S x CLEAR +#define CYAN_BG_BOLD(x) CYAN_BG_BOLD_S x CLEAR #define LOG_EMERG(x, ...) xmrig::Log::print(xmrig::Log::EMERG, x, ##__VA_ARGS__) diff --git a/src/core/Miner.cpp b/src/core/Miner.cpp index ab4a8ef6..a1c65ed2 100644 --- a/src/core/Miner.cpp +++ b/src/core/Miner.cpp @@ -361,12 +361,18 @@ void xmrig::Miner::setEnabled(bool enabled) void xmrig::Miner::setJob(const Job &job, bool donate) { - d_ptr->algorithm = job.algorithm(); - for (IBackend *backend : d_ptr->backends) { backend->prepare(job); } +# ifdef XMRIG_ALGO_RANDOMX + if (d_ptr->algorithm.family() == Algorithm::RANDOM_X && job.algorithm().family() == Algorithm::RANDOM_X && !Rx::isReady(job)) { + stop(); + } +# endif + + d_ptr->algorithm = job.algorithm(); + uv_rwlock_wrlock(&d_ptr->rwlock); const uint8_t index = donate ? 1 : 0; diff --git a/src/crypto/rx/Rx.cpp b/src/crypto/rx/Rx.cpp index 5f5414c9..6df708be 100644 --- a/src/crypto/rx/Rx.cpp +++ b/src/crypto/rx/Rx.cpp @@ -54,7 +54,7 @@ namespace xmrig { class RxPrivate; -static const char *tag = BLUE_BG(WHITE_BOLD_S " rx ") " "; +static const char *tag = BLUE_BG(WHITE_BOLD_S " rx ") " "; static RxPrivate *d_ptr = nullptr; @@ -231,6 +231,14 @@ private: } // namespace xmrig +bool xmrig::Rx::isReady(const Job &job) +{ + std::lock_guard lock(d_ptr->mutex); + + return d_ptr->isReady(job); +} + + xmrig::RxDataset *xmrig::Rx::dataset(const Job &job, uint32_t nodeId) { std::lock_guard lock(d_ptr->mutex); diff --git a/src/crypto/rx/Rx.h b/src/crypto/rx/Rx.h index 1ba6397e..7cb94b4e 100644 --- a/src/crypto/rx/Rx.h +++ b/src/crypto/rx/Rx.h @@ -44,6 +44,7 @@ class Job; class Rx { public: + static bool isReady(const Job &job); static RxDataset *dataset(const Job &job, uint32_t nodeId); static std::pair hugePages(); static void destroy(); From 3df080990c474c610ed6aab194ddde3463cba274 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 2 Aug 2019 17:57:41 +0700 Subject: [PATCH 11/13] Fixed warning. --- src/core/config/ConfigTransform.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/core/config/ConfigTransform.cpp b/src/core/config/ConfigTransform.cpp index 6d420739..ed315fb4 100644 --- a/src/core/config/ConfigTransform.cpp +++ b/src/core/config/ConfigTransform.cpp @@ -36,7 +36,10 @@ static const char *kAffinity = "affinity"; static const char *kAsterisk = "*"; static const char *kCpu = "cpu"; static const char *kIntensity = "intensity"; -static const char *kRandomX = "randomx"; + +#ifdef XMRIG_ALGO_RANDOMX +static const char *kRandomX = "randomx"; +#endif static inline uint64_t intensity(uint64_t av) From 7a93599d4e144fcfa94107cec4e81b5fd32974de Mon Sep 17 00:00:00 2001 From: xmrig Date: Fri, 2 Aug 2019 21:19:31 +0700 Subject: [PATCH 12/13] Update CHANGELOG.md --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c1cab4a9..646e53bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# v2.99.4-beta +- [#1088](https://github.com/xmrig/xmrig/pull/1088) Fixed macOS compilation. +- [#1095](https://github.com/xmrig/xmrig/pull/1095) Fixed compatibility with hwloc 1.10.x. +- Optimized RandomX initialization and switching, fixed rare crash when re-initialize dataset. +- Fixed ARM build with hwloc. + # v2.99.3-beta - [#1082](https://github.com/xmrig/xmrig/issues/1082) Fixed hwloc auto configuration on AMD FX CPUs. - Added command line option `--export-topology` for export hwloc topology to a XML file. From f1dfa26783279f2f1664f0798f913b9d52cb905d Mon Sep 17 00:00:00 2001 From: xmrig Date: Sat, 3 Aug 2019 22:19:40 +0700 Subject: [PATCH 13/13] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 646e53bb..97216550 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ # v2.99.4-beta +- [#1062](https://github.com/xmrig/xmrig/issues/1062) Fixed 32 bit support. **32 bit is slow and deprecated**. - [#1088](https://github.com/xmrig/xmrig/pull/1088) Fixed macOS compilation. - [#1095](https://github.com/xmrig/xmrig/pull/1095) Fixed compatibility with hwloc 1.10.x. - Optimized RandomX initialization and switching, fixed rare crash when re-initialize dataset.